/**
 * Toggles the visibility of the given selector.
 * @param selector The selector of the element(s) to show/hide
 * @param toggleswitch The element containing the text instructions.
 * @param show The text to show in the clicked link when the elements are shown.
 * @param hide The text to show in the clicked link when the elements are hidden.
 */
function toggleVisibility(selector, toggleswitch, show, hide) {
    $(selector).toggle();

    if($(selector).is(':visible'))
        $(toggleswitch).text(show);
    else
        $(toggleswitch).text(hide);
}

function tableAppendRow(tableSelector, row) {
    $(tableSelector).children('tbody').append($(row));
}

function selectnav(select, url, replace)
{
    var newUrl = url.replace(replace, select.value);
    window.location = newUrl;
}

/**
 * @param input The file input to re-enable.
 * @param deleteUrl The url to call for deleting the image.
 * @param hiddenvalue The hidden input that contains the file name and should be set to null.
 * @param callback A callback function to call when done.
 */
function realtimeFileDelete(input, deleteUrl, hiddenvalue, callback)
{
    // Get input name
    var inputName = $(input).attr('name');
    inputName = inputName.replace('[', '\\[');
    inputName = inputName.replace(']', '\\]');
    
    var callbackfunc = function(response)
    {
        callback(response);
        $(input).removeAttr('disabled');
        $(input).val(null);
        $('div.filedisplay[name='+inputName+']').hide();
        $(hiddenvalue).val(null);
    }
    ajax(deleteUrl, null, null, callbackfunc);
}

/**
 * @param input The HTML file input that uploads the file.
 * @param uploadUrl The url of the script which will handle the upload.
 * @param inputPath The input path from top input to the file input, separated by ';'.
 * @param hiddenvalue The input which should contain the hidden value after the upload.
 * @param callback A callback function to execute using the uploaded file as response.
 */
function realtimeUpload(input, uploadUrl, inputPath, hiddenvalue, callback)
{
    // Get input name
    var inputName = $(input).attr('name');
    inputName = inputName.replace('[', '\\[');
    inputName = inputName.replace(']', '\\]');

    console.log(hiddenvalue);
    console.log($(hiddenvalue));

    // Upload
    $(input).upload(
        uploadUrl,
        {path: inputPath},
        function(response){
            callback(response);
            // Set value to the hidden input
            $(hiddenvalue).val(response);
            // Disable file input when submitted
            $(input).attr('disabled', 'disabled');
            $('div.filedisplay[name='+inputName+']').show();
            $('a.filedisplaylink[name='+inputName+']').html(response.substr(response.lastIndexOf('/')+1));
        },
        'html'
    );
}

function ajax(url){
    ajax(url, null, null);
}
function ajax(url, confirm){
    ajax(url, confirm, null);
}
function ajax(url, confirm, messageSelector){
    ajax(url, confirm, messageSelector, null);
}
function ajax(url, confirm, messageSelector, callback) {
    ajax(url, confirm, messageSelector, callback, null);
}
function ajax(url, confirm, messageSelector, callback, oncancelled)
{
    if(confirm != null)
    {
        if(!window.confirm(confirm)) {
            oncancelled();
            return;
        }
    }

    if(messageSelector != null)
    {
        var message = $(messageSelector);
        message.empty();
        message.append("Bezig...");
        message.slideDown("normal");
    }
    $.post(
        url,
        {},
        function(response)
        {
            if(messageSelector != null)
            {
                message.empty();
                message.append(response);
                message.slideDown("normal");
            }
            if(callback != null)
                callback(response);
        },
        'html'
    );
}

function popup(url, name, options)
{
    window.open(url, name, options);
}

function redirect(url)
{
    window.location = url;
}

/**
 * If the selector is checked, disables all elements within the group, including
 * or excluding selectors. Enables if object is not checked.
 * @var selectorID The ID of the selector that is checked or unchecked, deciding
 * whether the group is enabled or disabled.
 * @var inputName The name of the html input corresponding to the selector. This
 * input will be excluded from enabling/disabling.
 * @var group The group, defined by a common html attribute.
 * @var mutual A boolean specifying whether inputs in the group are mutually exlusive.
 */
function exclusion(selectorID, inputName, group, mutual)
{
    var active = $('#'+selectorID).attr('checked');

    // Disable group
    $('['+group+']').attr('disabled', active)

    // Set enabled/disabled corresponding to selector
    if(!mutual)
        $('[name='+inputName+']').attr('disabled', !active);
    else
        // Re-enable excluded input and its selector
        $('[name='+inputName+']').attr('disabled', false);
    $('#'+selectorID).attr('disabled', false);

    // If specified, include selectors in enabling/disabling
    if(!mutual)
        $('['+group+'][selector]').attr('disabled', active);
    else // enable all selectors
        $('['+group+'][selector]').attr('disabled', false);
}

/**
 *
 */
function filtergrid(tbodyID, filterAttribute, filterField, dimX, maxY)
{
    var filterValue = filterField.value+''.toLowerCase();

    var accepted = new Array();
    var rejected = new Array();

    // Extract all cell contents from table and split into rejected and accepted
    $('#'+tbodyID+" > tr > td["+filterAttribute+"]").each(
        function(key, cell)
        {
            // Obtain item and column number for storage
            var item = cell.getAttribute('item');
            var col = cell.getAttribute('col');

            // Check filter
            var value = cell.getAttribute(filterAttribute);
            var array = rejected;
            if(value.toLowerCase().indexOf(filterValue) != -1)
                array = accepted;

            // If item/col does not exist in array, create it
            if(array[item] == null)
                array[item] = new Array();

            // Add cell to array
            array[item][col] = cell.cloneNode(true);
        }
    );

    var dimY = Math.ceil(accepted.length / dimX);
    $('#'+tbodyID+' > tr > td[x][y][z]').empty();
    $('#'+tbodyID+' > tr > td[x][y][z]').removeAttr(filterAttribute);

    // Reset indexes
    var temp = Array();
    var i = 0;
    for(item in accepted)
    {
        temp[i] = accepted[item];
        i++;
    }
    accepted = temp;
    temp = new Array();
    i = 0;
    for(item in rejected)
    {
        temp[i] = rejected[item];
        i++;
    }
    rejected = temp;

    // Find the number of columns per item
    var dimZ;
    if(accepted[0] != null)
        dimZ = accepted[0].length;
    else if(rejected[0] != null)
        dimZ = rejected[0].length;
    else
        return; // this means there are no items at all

    // Remove storage cells
    $('#'+tbodyID+" > tr[storage]").remove();

    // For each cell in the grid
    for(var x = 0; x < dimX; x++)
    {
        for(var y = 0; y < dimY; y++)
        {
            for(var z = 0; z < dimZ; z++)
            {
                // Compute item index
                var item = y + x * dimY;

                var cell = null;
                // If there is an accepted item for the table cell
                if(accepted[item] != null)
                {
                    // Get accepted cell
                    cell = accepted[item][z];
                }
                else
                {
                    // Create emtpy cell
                    cell = document.createElement('td');
                    cell.innerHTML = '&nbsp;'
                }

                // Get table cell
                var tablecell = $('#'+tbodyID+' > tr > td[x='+x+'][y='+y+'][z='+z+']');

                // Copy some attributes
                var classAttr = tablecell.attr('class');
                cell.setAttribute('class', classAttr);
                cell.setAttribute('x', x);
                cell.setAttribute('y', y);
                cell.setAttribute('z', z);

                // Show
                if(cell.style.display == 'hidden' || cell.style.display == 'none')
                    cell.style.display = '';

                // Replace table cell with accepted cell
                tablecell.replaceWith(cell);
            }
        }
    }

    // Hide unused cells
    for(x = 0; x < dimX; x++)
    {
        for(y = dimY; y < maxY; y++)
        {
            for(z = 0; z < dimZ; z++)
            {
                $('#'+tbodyID+' > tr > td[x='+x+'][y='+y+'][z='+z+']').hide();
            }
        }
    }

    // Add storage cells
    var tbody = $('#'+tbodyID);
    for(item in rejected)
    {
        var tr = $("<tr storage=1>");
        for(col in rejected[item])
        {
            tr.append(rejected[item][col]);
            rejected[item][col].style.display = 'none';
        }
        tbody.append(tr);
    }
}
