/**
 * calendar.js
 *
 * Adds functionality to the event editor by allowing the toggling of new
 * location and attraction forms, and by allowing the adding and removal
 * of new dates.
 */

// Constants
var idCellIndex = 0;        // The index of ID cell in a date row
var dateFieldIndex = 0;     // The index of the date field in an input set
var removeButtonIndex = 3;  // The index of the remove button in an input set

/******************************************************************************
 *  Initialization                                                            *
 ******************************************************************************/

addEvent(window, "load", loadEditor);

// Initializes the editor form.
function loadEditor()
{
    // Set the new location and new attraction form states
    var location = document.getElementById("location_id");
    var attraction = document.getElementById("attraction_id");    

    addEvent(location, "change", function () { toggle("location"); });
    addEvent(attraction, "change", function () { toggle("attraction"); });
    
    toggle("location");
    toggle("attraction");

    // Set handlers for add and remove buttons.
    var addButton = document.getElementById("add_date");
    addEvent(addButton, "click", addDate);

    var dateTable = document.getElementById("date_table");
    var inputs = dateTable.getElementsByTagName("input");
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].getAttribute("type") == "button")
            addEvent(inputs[i], "click", removeDate);
    }

}

/******************************************************************************
 *  Event Handlers                                                            *
 ******************************************************************************/

// Toggles the visibility of the new location/attraction forms.
function toggle(type)
{
    var select = document.getElementById(type + "_id");
    var div = document.getElementById("new_" + type);

    if (getSelectValue(select) == "new")
        div.className = "active";
    else
        div.className = null;
}

// Adds a new date to the date table.
function addDate(date, start, end)
{
    if (!date.length)
        date = "";

    var dateTable = document.getElementById("date_table");
    var rows = dateTable.getElementsByTagName("tr");
    var lastRow = rows[rows.length - 1];

    var dateFormat = /\d{2}\/\d{2}\/\d{2}/;
    var dateField = lastRow.getElementsByTagName("input")[dateFieldIndex];

    // If there's no valid date, or the last row has a value, create a new row
    if (!date.match(dateFormat) || dateField.value) {

        // Create a new table row
        var newRow = lastRow.cloneNode(true);
        lastRow.parentNode.appendChild(newRow);
    
        // Add an event handler on the new "Remove" button
        var button = newRow.getElementsByTagName("input")[removeButtonIndex];
        removeEvent(button, "click", removeDate);
        addEvent(button, "click", removeDate);

        // Replace the ID number
        var cell = newRow.getElementsByTagName("td")[idCellIndex];
        setText(cell, parseInt(cell.firstChild.nodeValue) + 1);

    } else {
        var newRow = lastRow;
    }

    // Initialize the text fields
    var inputs = newRow.getElementsByTagName("input");

    inputs[dateFieldIndex].value = (date.match(dateFormat)) ? date : "";
}

// Removes a date from the date table.
function removeDate()
{
    var currentRow = this.parentNode.parentNode;
    var tableBody = currentRow.parentNode;
    var rows = tableBody.getElementsByTagName("tr");

    // If there is only one row left, clear the text nodes
    if (rows.length == 1) {
        fields = currentRow.getElementsByTagName("input");
        for (var i = 0; i < fields.length; i++) {
            if (fields[i].getAttribute("type") != "button")
                fields[i].value = "";
        }

    // Otherwise, remove the row entirely
    } else {

        tableBody.removeChild(currentRow);

        // Reset the row numbers
        for (var i = 0; i < rows.length; i++) {
            var cell = rows[i].getElementsByTagName("td")[idCellIndex];
            setText(cell, i + 1);
        }
    }
}

/******************************************************************************
 *  Utility Functions                                                         *
 ******************************************************************************/

// Creates a text field initialized to a given value.
function createTextField(name, size, value)
{
    var field = document.createElement("input");
    field.setAttribute("type", "text");
    field.setAttribute("name", name);
    field.setAttribute("size", size);
    field.setAttribute("maxlength", size);

    if (value)
        field.setAttribute("value", value);

    return field;
}

function getSelectValue(select)
{
    return select.options[select.selectedIndex].value;
}

// Sets the text of an element (element should be empty or first child text)
function setText(element, text)
{
    var textNode = document.createTextNode(text);

    if (element.firstChild)
        element.replaceChild(textNode, element.firstChild);
    else
        element.appendChild(textNode);
}

// Removes the text from an element (text should be first/only child)
function removeText(element)
{
    if (element.firstChild)
        element.removeChild(element.firstChild);
}

function addEvent(element, type, handler)
{
    if (element.addEventListener) {
        element.addEventListener( type, handler, false );
    } else if (element.attachEvent) {
        element["e" + type + handler] = handler;
        element[type + handler] = function() { element["e" + type + handler](window.event); }
        element.attachEvent("on" + type, element[type + handler]);
    }
}

function removeEvent(element, type, handler)
{
    if (element.removeEventListener) {
        element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
        element.detachEvent("on" + type, element[type+handler]);
        element[type+handler] = null;
    }
}
