/*globals window, define*/
/*jslint nomen:true, unparam: true*/

/**
 * Add functionality to a country selection field that the necessary template with corresponding form field is included.
 *
 * The `jQuery.shopwizardUiCountryvalidation()` changes the template depending on the selected country.
 *
 * ### Examples
 * Attach country validation to a select element.
 *
 * HTML:
 *     <select name="CountryID" id="CountryID">
 *        <option value="id1">country 1</option>
 *        <option value="id2">country 2</option>
 *     </select>
 *     <div id="wrapperID"></div>
 *
 * JavaScript:
 *
 *   $('#CountryID').shopwizardUiCountryvalidation({
 *       wrapper: $('#wrapperID'),
 *       countries: {
 *       'id1': {
 *           address: {
 *               street: {
 *                   selector: '#IdOfStreetInput',
 *                   value: 'ValueForStreetInput'
 *               }
 *           },
 *           template: '#IdForScriptTagWithTemplateCode',
 *           onBeforeRender: function () {
 *               // Code to be executed before the template is rendered
 *           },
 *           onAfterRender: function () {
 *               // Code to be executed after the template is rendered
 *           }
 *       },
 *       'id2': {
 *           address: {
 *               street: {
 *                   selector: '#IdOfStreetInput',
 *                   value: 'ValueForStreetInput'
 *               }
 *           },
 *           template: '#IdForScriptTagWithTemplateCode',
 *           onBeforeRender: function () {
 *               // Code to be executed before the template is rendered
 *           },
 *           onAfterRender: function () {
 *               // Code to be executed after the template is rendered
 *           }
 *       }
 *    }
 *   });
 *
 *
 * @class jQuery.ui.countryvalidation
 *
 * @uses jquery
 * @uses de_epages
 * @uses jQuery.ui.widget
 *
 * @since 6.17.22
 */

/**
 * See `jQuery.ui.countryvalidation` for details.
 *
 * @method countryvalidation
 * @member jQuery
 *
 * @since 6.17.22
 */

/*
 * @copyright       © Copyright 2006-2015, epages GmbH, All Rights Reserved.
 *
 * @module          ep.ui.countryvalidation
 *
 * @revision        $Revision: 1.2 $
 */

define("de_epages/shopwizard/ui/countryvalidation", [
    "jquery",
    "de_epages",

    "de_epages/presentation/ui/inputaction",
    "jquery/ui/widget"
], function ($, de_epages) {

    // Widget.
    $.widget('ui.shopwizardUiCountryvalidation', {
        options : {
            wrapper: $('body'),
            countries: {}
        },

        _create : function () {
            var self = this,
                o = self.options,
                elem = self.element;

            // add change handling for the country selection element
            elem.on('change.countryvalidation', function () {
                // render necessary template
                self._renderTemplate();
            });

            // set initialize value
            self.oldValue = -1;
            self._renderTemplate();
        },

        _renderTemplate: function () {
            var self = this,
                o = self.options,
                address = o.address,
                elem = self.element,
                countryID = elem.val(),
                // set new ID to the value of the selected option, to 'default' otherwise
                newID = o.countries[countryID] ? countryID : 'default',
                tmpl,
                _key;

            // if the ID has changed => change template
            if (newID !== self.oldValue){
                // execute callbacks (if handed over) for each country before rendering starts
                for (_key in o.countries) {
                    if (o.countries.hasOwnProperty(_key) && typeof o.countries[_key].onBeforeRender === 'function') {
                        o.countries[_key].onBeforeRender();
                    }
                }

                // if an entry for the previous selected country exists
                if (o.countries[self.oldValue]) {
                    // traverse over all properties of the previous selected country
                    for (_key in o.countries[self.oldValue].address) {
                        // save the values of the element corresponding to the selector
                        if (o.countries[self.oldValue].address.hasOwnProperty(_key)) {
                            o.countries[self.oldValue].address[_key].value = $(o.countries[self.oldValue].address[_key].selector).val();
                        }
                    }
                }

                // get the object for the currently selected country
                if (o.countries[newID].address) {
                    address = o.countries[newID].address;
                }

                // render template for the currently selected country
                tmpl = $(o.countries[newID].template).tmpl(address);
                // replace the previous template with the new one
                o.wrapper.html(tmpl);
                // metaparse the inputs inside the new template
                o.wrapper.find('input').metaparse();

                // execute callback (if handed over) for selected country after rendering ends
                if (typeof o.countries[newID].onAfterRender === 'function') {
                    o.countries[newID].onAfterRender(address);
                }
                if (typeof o.countries[newID].onChange === 'function') {
                    o.countries[newID].onChange();
                }

                // set the identifier for the old ID to the value of the selected option if an entry exists in the address object,
                // to 'default' otherwise
                if (o.countries[countryID]) {
                    self.oldValue = countryID;
                } else {
                    self.oldValue = 'default';
                }
            }

        },

        destroy : function () {
            var self = this,
                elem = this.element;

            this._superApply(arguments);
        }

    });

    return de_epages;
});