﻿/**
 * Allgemine Funktionen für Formulare.
 */
var FormClass = Class.create();

/**
 * Der Url der aktuellen Seite.
 * 
 * @var string
 */
FormClass.prototype.baseUrl = undefined;

/**
 * Der Name des Formulars.
 * 
 * @var string
 */
FormClass.prototype.name = undefined;

/**
 * Setzt den Namen des Formulars und die Url.
 */
FormClass.prototype.initialize = function(name, baseUrl) {
    this.name = name;
    this.baseUrl = baseUrl;
};

/**
 * Lädt die Daten von verknüpften Selects nach.
 * 
 * @param   {String}    name                Der Name des geänderten Elements.
 * @param   {Object}    additionalParams    Zusätzliche Parameter für die URL.
 */
FormClass.prototype.reloadSelects = function(name, additionalParams) {
    var value  = document.getElementsByName(name)[0].value;
    var params = $H(
        {
            form:       this.name,
            formAction: 'reloadSelect',
            element:    name,
            index:      value
        }
    );
    if (additionalParams !== undefined) {
        params.merge(additionalParams);
    }

    var instance = this;
    new Ajax.Request(
        this.baseUrl,
        {
            method:     'get',
            parameters: params.toQueryString(),
            onComplete: function(request, data) {
                instance.setSelects(request, data);
            }
        }
    );
};

/**
 * Setzt die Daten von verknüpften Selects.
 * 
 * @param   string  request Die Ausgabe der Abfrage.
 * @param   Hash    data    Assoziazives Array mit dem Namen des Selects als
 *                          Index und den Optionen als Wert.
 */
FormClass.prototype.setSelects = function(request, data) {
    if (data == undefined) {
        data = eval(request.responseText);
    }

    if ($H(data).toArray().length > 0) {
        $H(data).each(
            function(value, index) {
                this.setOptions(value.key, value.value);
            }.bind(this)
        );
    }
};

/**
 * Setzt die Options eines Select Elements.
 * 
 * @param   string  name    Der Name des Selects.
 * @param   Hash    options Assoziatives Array mit dem Wert der Option als Index
 *                          und dem Text als Wert.
 */
FormClass.prototype.setOptions = function(name, options) {
    var element = document.getElementsByName(name)[0];
    element.length = 0;
    $H(options).each(
        function(value, index) {
            var option = document.createElement('option');
            option.value = value.key;
            var text = document.createTextNode(value.value);
            option.appendChild(text);
            element.appendChild(option);
        }
    );
    if (element.onchange) {
        element.onchange();
    }
};

/**
 * Fügt einer Gruppe gleicher Elemente weitere hinzu.
 */
FormClass.ElementAdd = Class.create();

/**
 * Der Name der Eelemente.
 * 
 * @var string
 */
FormClass.ElementAdd.prototype._name = undefined;

/**
 * Element in dem die aktuelle Anzahl der Elemente gespeichert ist.
 * 
 * @var HTMLElement
 */
FormClass.ElementAdd.prototype._elementCount = undefined;

/**
 * Maximal Anzahl an Elementen.
 * 
 * @var integer
 */
FormClass.ElementAdd.prototype._maxElements = 0;

/**
 * Setzt die Werte und erstellt den Link.
 * 
 * @param   string      name            Der Name der Elemente.
 * @param   HTMLElement elementCount    Element in dem die aktuelle Anzahl der
 *                                      Elemente gespeichert ist.
 * @param   integer     maxElements     Maximal Anzahl an Elementen.
 * @param   string      linkText        Text für den hinzufügen Link.
 */
FormClass.ElementAdd.prototype.initialize = function(name, elementCount, maxElements, linkText) {
    this._name = name;
    this._elementCount = elementCount;
    this._maxElements = maxElements;

    if (this._elementCount.value < this._maxElements) {
        new Insertion.Before(document.getElementsByName(this._name + '[' + (this._elementCount.value - 1) + ']')[0], '<div id="' + this._name + 'ElementAdd"><a href="javascript: undefined;">' + linkText + '</a></div>');
        $(this._name + 'ElementAdd').onclick = this.add.bind(this);
    }
};

/**
 * Fügt ein neues Element hinzu.
 */
FormClass.ElementAdd.prototype.add = function() {
    if (this._elementCount.value < this._maxElements) {
        var node = document.getElementsByName(this._name + '[0]')[0].cloneNode(true);
        node.name = this._name + '[' + this._elementCount.value + ']';
        node.value = '';
        $(this._name + 'ElementAdd').parentNode.appendChild(node);
        $(this._name + 'ElementAdd').parentNode.appendChild(document.createElement('br'));

        this._elementCount.value++;
    }

    if (this._elementCount.value >= this._maxElements) {
        Element.remove($(this._name + 'ElementAdd'));
    }
};



/**
 * Macht aus einem Input Feld einen Slider.
 */
FormClass.Slider = Class.create();

/**
 * Die Id des Input Feldes.
 * 
 * @var (String)
 */
FormClass.Slider.prototype._id = undefined;

/**
 * Format für die Anzeige des aktuellen Wertes.
 * 
 * @var (String)
 */
FormClass.Slider.prototype._format = undefined;

/**
 * Aktualisiert den angezeigten Wert.
 * 
 * @param   {Integer}   v   Der neue Wert für die Anzeige.
 */
FormClass.Slider.prototype._updateDisplay = function(v) {
    $(this._id).value = v;
    $(this._id + 'Display').innerHTML = this._format.replace(/%s/, v);

    var oEvent;
    if (document.createEvent) {
        oEvent = document.createEvent('Event');
        oEvent.initEvent('change', true, true);
        $(this._id).dispatchEvent(oEvent);
    } else {
        oEvent = document.createEventObject();
        $(this._id).fireEvent('onchange', oEvent);
    }
};

/**
 * Wandelt das Feld um.
 * 
 * @param   {String}    id      Die Id des Elements.
 * @param   {Object}    options Die Optionen des Sliders.
 */
FormClass.Slider.prototype.initialize = function(id, options) {
    this._id = id;
    this._format = options.format;

    var sliderHTML = '<div id="' + this._id + 'Track" class="SliderTrack" style="width: ' + options.width + 'px;">';
    sliderHTML += '    <div id="' + this._id + 'Handle" class="SliderHandle"> </div>';
    sliderHTML += '</div>';
    sliderHTML += '<span id="' + this._id + 'Display" class="SliderDisplay"> </span>';

    new Insertion.After(this._id, sliderHTML);
    Element.hide(this._id);

    var slider = new Control.Slider(
        this._id + 'Handle',
        this._id + 'Track',
        {
            range: $R(options.min, options.max),
            values: options.values,
            onSlide: this._updateDisplay.bind(this),
            onChange: this._updateDisplay.bind(this)
        }
    );
    slider.setValue($(this._id).value);
};