/**
 * Make shure there is an 'WebsiteRoot' javascript variable available
 * something like the following can be used:
var WebsiteRoot = '<?= $_ENGINE->Config->WebsiteRoot; ?>';

 * Needed HTML layout per text-field with autocompletion
 * (other elements/attributes can be added as you wish)
<div class="RfsTeaser">
    <input type="text" id="{elementId}" />
    <span id="{elementId}Indicator" style="display: none;"><img src="images/upc/spinner.gif" alt="Loading..." /></span>
    <div id="{elementId}SelectionDiv"></div>
</div>

*/


/**
 * Example RFS Teaser element set-up
 * Add elements in order of the form! (incl. the dependeds)
    var options = {
	    type: 'city'
	};
	
	var rfsElementCity = new RfsTeaserElement('NAW_City', options);
	//var rfsElementCity = new RfsTeaserElement('NAW_City', 'type="city"');
	rfsElementCity.setErrorMessage('Zadejte, prosím, platný název města');
	rfsElementCity.addDependedElementId('NAW_Subcity');
	rfsElementCity.addDependedElementId('NAW_Street');
	rfsElementCity.addDependedElementId('NAW_HouseNumber');
	
	var options = {
	    type: 'subcity',
	    city: '${id.NAW_City}'
	};
	
	var rfsElementSubcity = new RfsTeaserElement('NAW_Subcity', options);
	//var rfsElementSubcity = new RfsTeaserElement('NAW_Subcity', 'type="subcity"&city=${id.NAW_City}');
	rfsElementSubcity.setErrorMessage('Zadejte, prosím, platný název části města');
	rfsElementSubcity.addQueryElementId('NAW_City');
	rfsElementSubcity.addDependedElementId('NAW_Street');
	rfsElementSubcity.addDependedElementId('NAW_HouseNumber');
	
	var options = {
	    type: 'street',
	    city: '${id.NAW_City}',
	    subcity: '${id.NAW_Subcity}'
	};
	
	var rfsElementStreet = new RfsTeaserElement('NAW_Street', options);
	//var rfsElementStreet = new RfsTeaserElement('NAW_Street', 'type="street"&city=${id.NAW_City}&subcity=${id.NAW_Subcity}');
	rfsElementStreet.setErrorMessage('Zadejte, prosím, platný název ulice');
	rfsElementStreet.addQueryElementId('NAW_City');
	rfsElementStreet.addQueryElementId('NAW_Subcity');
	rfsElementStreet.addDependedElementId('NAW_HouseNumber');
	
	var options = {
	    type: 'housenr',
	    city: '${id.NAW_City}',
	    subcity: '${id.NAW_Subcity}',
	    street: '${id.NAW_Street}'
	};
	
	var rfsElementHouseNumber = new RfsTeaserElement('NAW_HouseNumber', options);
	//var rfsElementHouseNumber = new RfsTeaserElement('NAW_HouseNumber', 'type="housenr"&city=${id.NAW_City}&subcity=${id.NAW_Subcity}&street=${id.NAW_Street}');
	rfsElementHouseNumber.setErrorMessage('Zadejte, prosím, platné popisné a orientační číslo');
	rfsElementHouseNumber.addQueryElementId('NAW_City');
	rfsElementHouseNumber.addQueryElementId('NAW_Subcity');
	rfsElementHouseNumber.addQueryElementId('NAW_Street');
	
	var rfsElements = [ // Array
	                    rfsElementCity,
	                    rfsElementSubcity,
	                    rfsElementStreet,
	                    rfsElementHouseNumber
	];
	
	initializeRfsTeaserObject(rfsElements,  // array of Element objects
	                          WebsiteRoot + 'snippets/rfsteaser_ajaxdata.php',  // url for requesting data
	                          'rfsTeaserForm',      // id of teaser <form.. element
	                          'rfs_teaser_submit'   // id of teaser <input.. submit element
	);
*/

var rfsTeaser = null;

function initializeRfsTeaserObject(elements, url, formId, formSubmitId) {
    rfsTeaser = new RfsTeaser('rfsTeaser', elements, url, formId, formSubmitId);
    rfsTeaser.initialize();
};

function RfsTeaser (name, elements, url, formId, formSubmitId) {
    // Name of the RfsTeaser variable
    this.name = name;
    
    // Url to the script to execute requests to
    this.url = url;
    
    // Array of Element objects to work with
    this.elements = elements;
    
    this.elementAutoCompleteClass = [];
    
    // Name of drop down div (placed after elementId)
    this.elementDivPostfixText = 'SelectionDiv';
    
    // Name of indicator (placed after elementId)
    this.elementIndicatorPostfixText = 'Indicator';
    
    // id of the teaser <form.. element
    this.formId = formId;
    
    // id of the teaser <input.. submit element
    this.formSubmitId = formSubmitId;
    
    /**
     * initialize
     *
     * Executes initializing tasks
     */
    this.initialize = function () {
        // Initialize teaser form
        var domFormElement = document.getElementById(this.formId);
        if (domFormElement != 'undefined' && domFormElement != null) {
            domFormElement.setAttribute('onSubmit', 'return ' + rfsTeaser.name + '.onSubmit();');
        }
        
        // Initialize autocomplete field elements
	    for (var i = 0; i < this.elements.length; i++) {
	        var element = this.elements[i];
            
            // Add autocompleter to Element
            rfsTeaser.setAutoComplete(element.id);
            
            var domElement = document.getElementById(element.id);
            //onkeydown="rfsTeaser.onKeyDown(elementId);"
            domElement.setAttribute('onkeydown', rfsTeaser.name + '.onKeyDown(\'' + element.id + '\');');
            
            // Disable depended elements
            if (element.dependedElementIds.length > 0) {
                for (var d = 0; d < element.dependedElementIds.length; d++) {
	                var dependedElementId = element.dependedElementIds[d];
	                if (rfsTeaser.elementHasValue(dependedElementId) == true) {
	                    // enable element
	                    document.getElementById(dependedElementId).disabled = false;
	                } else {
	                    rfsTeaser.disableElement(dependedElementId);
	                }
	            }
            }
	    }
    }
    
    /**
     * setAutoComplete
     *
     * Set Ajax.AutoComplete for given element
     *
     * elementId = elementId
     */
    this.setAutoComplete = function (elementId) {
        var element = rfsTeaser.getElementObjectById(elementId);
        
        // Add autocompleter to current Element
        rfsTeaser.elementAutoCompleteClass[element.id] = null;
        rfsTeaser.elementAutoCompleteClass[element.id] = new Ajax.Autocompleter(
            element.id,
            rfsTeaser.getDivElement(element.id),
            rfsTeaser.url,
            {
                paramName: 'search',
                indicator: rfsTeaser.getIndicatorElement(element.id),
                afterUpdateElement: rfsTeaser.enableNextElement,
                autoSelect: true,
                fields: element.getQueryString()
            }
        );
    };
    
    /**
     * onKeyDown
     *
     * Function to execute on <input.. field elements
     *
     * elementId = elementId
     */
    this.onKeyDown = function (elementId) {
        rfsTeaser.disableDependedElementsById(elementId, true);
    };
    
    /**
     * onSubmit
     *
     * Function to execute on the <form.. submit action 
     */
    this.onSubmit = function () {
        var hasErrors = false;
        // Validate values
        for (var i = 0; i < rfsTeaser.elements.length; i++) {
            var element = rfsTeaser.elements[i];
            var domElement = null;
            domElement = document.getElementById(element.id);
            var errorElement = document.getElementById(element.id + 'warning');
            // Remove old error element
            if (errorElement != null && errorElement != 'undefined') {
                domElement.parentNode.removeChild(errorElement);
            }
            if (rfsTeaser.elementHasValue(element.id) != true) {
                // Create span element for the error message
                var domSpanErrorElement = null;
                domSpanErrorElement = document.createElement('span');
                domSpanErrorElement.setAttribute('id', element.id + 'warning');
                var agt = navigator.userAgent.toLowerCase();
                if (agt.indexOf("msie") != -1) {
                    domSpanErrorElement.setAttribute('className', 'warning');
                } else {
                    domSpanErrorElement.setAttribute('class', 'warning');
                }
                
                // Create the error message text
                var errorMessageElement = document.createTextNode(element.getErrorMessage());
                // Add the error message text to the error message span element
                domSpanErrorElement.appendChild(errorMessageElement);
                
                var domBrElement = null;
                domBrElement = document.createElement('br');
                
                // Insert error element
                domElement.parentNode.insertBefore(domSpanErrorElement, domElement);
                domElement.parentNode.insertBefore(domBrElement, domElement);
                
                // Set that we had an error
                hasErrors = true;
            }
        }
        // debugging
        
        if (hasErrors == true) {
            return false;
        }
        return true;
    };
    
    /** 
     * getElementObjectById
     *
     * Get the Element object of given elementId 
     * 
     * elementId = elementId
     *
     * returns Element object when found, false otherwise
     */
    this.getElementObjectById = function (elementId) {
        for (var i = 0; i < rfsTeaser.elements.length; i++) {
            if (elements[i].id == elementId) {
                return elements[i];
            }
        }
        return false;
    }

    /**
     * getDivElement
     *
     * Get div (drop down box) element of given elementId
     *
     * elementId = elementId 
     *
     * return element
     */
    this.getDivElement = function (elementId) {
        return document.getElementById(elementId + rfsTeaser.elementDivPostfixText);
    }
    
    /**
     * getIndicatorElement
     *
     * Get indicator (span, loading) element of given elementId
     *
     * elementId = elementId 
     *
     * return element
     */
    this.getIndicatorElement = function (elementId) {
        return document.getElementById(elementId + rfsTeaser.elementIndicatorPostfixText);
    }
    
    /**
     * disableElement
     *
     * Disable given element in the document
     *
     * elementId = elementId
     */
    this.disableElement = function (elementId, clear) {
        if (clear == true) {
            document.getElementById(elementId).value = '';
        }
        //document.getElementById(elementId).disabled = true;
    };
    
    /**
     * disableDependedElements
     *
     * Disable depended elements of given element in the document
     *
     * element = RfsTeaserElement object
     */
    this.disableDependedElements = function (element, clear) {
        for (var d = 0; d < element.dependedElementIds.length; d++) {
            var dependedElementId = element.dependedElementIds[d];
            rfsTeaser.disableElement(dependedElementId, clear);
        }
    };
    
    /**
     * disableDependedElementsById
     *
     * Disable depended elements of given elementId in the document
     *
     * elementId = elementId
     */
    this.disableDependedElementsById = function (elementId, clear) {
        var element = rfsTeaser.getElementObjectById(elementId);
        if (element != 'undefined' && element != null) { 
            rfsTeaser.disableDependedElements(element, clear);
        }
    }
    
    /**
     * enableNextElement
     *
     * Enable the first depended element of the given DomElement object
     *
     */
    this.enableNextElement = function (DomElement) {
        var element = rfsTeaser.getElementObjectById(DomElement.id);
        if (element != 'undefined' && element != null) {
            // Enable first depended element
            if (element.dependedElementIds.length >= 1) {
                var dependedElementId = element.dependedElementIds[0];
                var dependedElement = document.getElementById(dependedElementId);
                // enable first depended element
                dependedElement.disabled = false;
                dependedElement.value = '';
                dependedElement.focus();
		    }
        }
    }
    
    /**
     * elementHasValue
     *
     * Check if given element has a value
     *
     * elementId = elementId
     *
     * returns true when element has a value, false otherwise
     */
    this.elementHasValue = function (elementId) {
        var element = document.getElementById(elementId);
        if (element != 'undefined' && element != null && element != false && element.value != '' ) {
            return true;
        }
        return false;
    };
    
};


/**
 * RfsTeaserElement class
 *
 * id = elementId to work on
 * postQueryString = Object containing all post query vars 
 *                   queryVar names that are replaced when
 *                   added via the addQueryVar() function
 *                   ${id.elementId} where id is the elementId within the document
 *                              to use the value of the element
 *                              The elementId has to be added thry the addQueryElementId() function 
 *                   ${city}    queryVar name that should be replaced with the
 *                              value added thru the addQueryVar() function
 *                   example:
 *                      var options = {
 *                          type: 'subcity',
 *                          city: '${id.NAW_City}'
 *                      };
 */
function RfsTeaserElement(id, postQueryString) {
    // elementId
    this.id = id;
    this.postQueryString = postQueryString;
    this.dependedElementIds = []; // Array
    this.errorMessage = '';
    
    /**
     * var postQueryVars
     *
     * name/value combinations for replacing name
     * within postQueryString with given value
     * 
     * Array layout:
     * Array(
     *    [0] = Array(
     *             [0] = name,
     *             [1] = value
     *          ),
     *    [1] = Array(
     *             [0] = name,
     *             [1] = value
     *          ),
     *    ...
     * )
     */
    this.postQueryVars = []; // Array
    
    /**
      * var postQueryElementIds
      *
      * RfsTeaserElement id's where to use the value of
      */
    this.postQueryElementIds = []; // Array
    
    /**
     * addQueryVar
     *
     * Add queryVar name/value used for replacing vars
     * in the postQueryString
     * 
     * name = String to be replaced within postQueryString
     *        without the '${' and '}'
     * value = the value to fill in the postQueryString
     */
    this.addQueryVar = function (name, value) {
        var queryVar = [name, value];
        this.postQueryVars.push(queryVar);
    };
    
    /**
     * addQueryElementId
     * 
     * Add elementId used for replacing vars
     * in the postQueryString with the value of the given elementId
     * 
     * id = element id
     */
    this.addQueryElementId = function (id) {
        this.postQueryElementIds.push(id);
    };
    
    /**
     * getQueryString
     * 
     * Get the queryString as given by the user
     *
     * return String queryString
     */
    this.getQueryString = function () {
        var queryString = this.postQueryString;

        return queryString;
    };
    
    /**
     * addDependedElement
     *
     * Add an element id of an element that is
     * depended of this (current) element
     */
    this.addDependedElementId = function (id) {
        this.dependedElementIds.push(id);
    };
    
    /**
     * setErrorMessage
     *
     * Set the error message for this element
     */
    this.setErrorMessage = function (message) {
        this.errorMessage = message;
    };
    
    /**
     * getErrorMessage
     *
     * Get the error message for this element
     *
     * return string Error message
     */
    this.getErrorMessage = function () {
        return this.errorMessage;
    }
};