/**
 * Magento Enterprise Edition
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Magento Enterprise Edition License
 * that is bundled with this package in the file LICENSE_EE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.magentocommerce.com/license/enterprise-edition
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Varien
 * @package     js
 * @copyright   Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
 * @license     http://www.magentocommerce.com/license/enterprise-edition
 */
VarienForm = Class.create();
VarienForm.prototype = {
    initialize: function(formId, firstFieldFocus){
        this.form       = $(formId);
        if (!this.form) {
            return;
        }
        this.cache            = $A();
        this.currLoader       = false;
        this.currDataIndex    = false;
        this.validator        = new Validation(this.form);
        this.elementFocus     = this.elementOnFocus.bindAsEventListener(this);
        this.elementBlur      = this.elementOnBlur.bindAsEventListener(this);
        this.childLoader      = this.onChangeChildLoad.bindAsEventListener(this);
        this.highlightClass   = 'highlight';
        this.extraChildParams = '';
        this.firstFieldFocus  = firstFieldFocus || false;
        this.bindElements();
        if(this.firstFieldFocus){
            try{
                Form.Element.focus(Form.findFirstElement(this.form))
            }
            catch(e){}
        }

        Validation.add('validate-phone','Incorrect number!<br>Example: 800-555-1234, 8005551234, 0 800.555.1234', 
                         function (value)
                         {
                              var pattern = new RegExp("^[01]?[- .]?(\\([2-9]\\d{2}\\)|[2-9]\\d{2})[- .]?\\d{3}[- .]?\\d{4}$");
                              return value!='' ? pattern.test(value) : true;
                         },
                   {
//                   pattern : new RegExp("^[2-9]{1}[0-9]{2}[\\s\\-\\.]?[0-9]{3}[\\s\\-\\.]?[0-9]{4}$"), //,"gi"),
//                   minLength : 7, // value must be at least 6 characters
//                   maxLength : 14, // value must be no longer than 13 characters
                   });
                   
    },

    submit : function(url){
        if(this.validator && this.validator.validate()){
             this.form.submit();
        }
        return false;
    },

    bindElements:function (){
        var elements = Form.getElements(this.form);
        for (var row in elements) {
            if (elements[row].id) {
                Event.observe(elements[row],'focus',this.elementFocus);
                Event.observe(elements[row],'blur',this.elementBlur);
            }
        }
    },

    elementOnFocus: function(event){
        var element = Event.findElement(event, 'fieldset');
        if(element){
            Element.addClassName(element, this.highlightClass);
        }
    },

    elementOnBlur: function(event){
        var element = Event.findElement(event, 'fieldset');
        if(element){
            Element.removeClassName(element, this.highlightClass);
        }
    },

    setElementsRelation: function(parent, child, dataUrl, first){
        if (parent=$(parent)) {
            // TODO: array of relation and caching
            if (!this.cache[parent.id]){
                this.cache[parent.id] = $A();
                this.cache[parent.id]['child']     = child;
                this.cache[parent.id]['dataUrl']   = dataUrl;
                this.cache[parent.id]['data']      = $A();
                this.cache[parent.id]['first']      = first || false;
            }
            Event.observe(parent,'change',this.childLoader);
        }
    },

    onChangeChildLoad: function(event){
        element = Event.element(event);
        this.elementChildLoad(element);
    },

    elementChildLoad: function(element, callback){
        this.callback = callback || false;
        if (element.value) {
            this.currLoader = element.id;
            this.currDataIndex = element.value;
            if (this.cache[element.id]['data'][element.value]) {
                this.setDataToChild(this.cache[element.id]['data'][element.value]);
            }
            else{
                new Ajax.Request(this.cache[this.currLoader]['dataUrl'],{
                        method: 'post',
                        parameters: {"parent":element.value},
                        onComplete: this.reloadChildren.bind(this)
                });
            }
        }
    },

    reloadChildren: function(transport){
        var data = eval('(' + transport.responseText + ')');
        this.cache[this.currLoader]['data'][this.currDataIndex] = data;
        this.setDataToChild(data);
    },

    setDataToChild: function(data){
        if (data.length) {
            var child = $(this.cache[this.currLoader]['child']);
            if (child){
                var html = '<select name="'+child.name+'" id="'+child.id+'" class="'+child.className+'" title="'+child.title+'" '+this.extraChildParams+'>';
                if(this.cache[this.currLoader]['first']){
                    html+= '<option value="">'+this.cache[this.currLoader]['first']+'</option>';
                }
                for (var i in data){
                    if(data[i].value) {
                        html+= '<option value="'+data[i].value+'"';
                        if(child.value && (child.value == data[i].value || child.value == data[i].label)){
                            html+= ' selected';
                        }
                        html+='>'+data[i].label+'</option>';
                    }
                }
                html+= '</select>';
                Element.insert(child, {before: html});
                Element.remove(child);
            }
        }
        else{
            var child = $(this.cache[this.currLoader]['child']);
            if (child){
                var html = '<input type="text" name="'+child.name+'" id="'+child.id+'" class="'+child.className+'" title="'+child.title+'" '+this.extraChildParams+'>';
                Element.insert(child, {before: html});
                Element.remove(child);
            }
        }

        this.bindElements();
        if (this.callback) {
            this.callback();
        }
    }
}

RegionUpdater = Class.create();
RegionUpdater.prototype = {
    initialize: function (countryEl, regionTextEl, regionSelectEl, regions, disableAction, zipEl)
    {
        this.countryEl = $(countryEl);
        this.regionTextEl = $(regionTextEl);
        this.regionSelectEl = $(regionSelectEl);
        this.zipEl = $(zipEl);
        this.regions = regions;

        this.disableAction = (typeof disableAction=='undefined') ? 'hide' : disableAction;
        this.zipOptions = (typeof zipOptions=='undefined') ? false : zipOptions;

        if (this.regionSelectEl.options.length<=1) {
            this.update();
        }

        Event.observe(this.countryEl, 'change', this.update.bind(this));
    },

    update: function()
    {
        if (this.regions[this.countryEl.value]) {
            var i, option, region, def;

            if (this.regionTextEl) {
                def = this.regionTextEl.value.toLowerCase();
                this.regionTextEl.value = '';
            }
            if (!def) {
                def = this.regionSelectEl.getAttribute('defaultValue');
            }

            this.regionSelectEl.options.length = 1;
            for (regionId in this.regions[this.countryEl.value]) {
                region = this.regions[this.countryEl.value][regionId];

                option = document.createElement('OPTION');
                option.value = regionId;
                option.text = region.name;

                if (this.regionSelectEl.options.add) {
                    this.regionSelectEl.options.add(option);
                } else {
                    this.regionSelectEl.appendChild(option);
                }

                if (regionId==def || region.name.toLowerCase()==def || region.code.toLowerCase()==def) {
                    this.regionSelectEl.value = regionId;
                }
            }

            if (this.disableAction=='hide') {
                if (this.regionTextEl) {
                    this.regionTextEl.style.display = 'none';
                }

                this.regionSelectEl.style.display = '';
            } else if (this.disableAction=='disable') {
                if (this.regionTextEl) {
                    this.regionTextEl.disabled = true;
                }
                this.regionSelectEl.disabled = false;
            }
            this.setMarkDisplay(this.regionSelectEl, true);
        } else {
            if (this.disableAction=='hide') {
                if (this.regionTextEl) {
                    this.regionTextEl.style.display = '';
                }
                this.regionSelectEl.style.display = 'none';
                Validation.reset(this.regionSelectEl);
            } else if (this.disableAction=='disable') {
                if (this.regionTextEl) {
                    this.regionTextEl.disabled = false;
                }
                this.regionSelectEl.disabled = true;
            } else if (this.disableAction=='nullify') {
                this.regionSelectEl.options.length = 1;
                this.regionSelectEl.value = '';
                this.regionSelectEl.selectedIndex = 0;
                this.lastCountryId = '';
            }
            this.setMarkDisplay(this.regionSelectEl, false);
        }

        // Make Zip and its label required/optional
        var zipUpdater = new ZipUpdater(this.countryEl.value, this.zipEl);
        zipUpdater.update();
    },

    setMarkDisplay: function(elem, display){
        elem = $(elem);
        var labelElement = elem.up(0).down('label > span.required') ||
                           elem.up(1).down('label > span.required') ||
                           elem.up(0).down('label.required > em') ||
                           elem.up(1).down('label.required > em');
        if(labelElement) {
            inputElement = labelElement.up().next('input');
            if (display) {
                labelElement.show();
                if (inputElement) {
                    inputElement.addClassName('required-entry');
                }
            } else {
                labelElement.hide();
                if (inputElement) {
                    inputElement.removeClassName('required-entry');
                }
            }
        }
    }
}


CountyUpdater = Class.create();
CountyUpdater.prototype = {
    initialize: function (addressObj, addressEls, countyTextEl, countySelectEl, countyFieldsRowEl, countyRowEl, counties, disableAction, taxexemptEl, taxexemptRowEl, radioEl)
    {
        
//        this.regionEl         = $(regionEl);
        this.regionId         = null;
        this.addressObj       = addressObj;
        this.countyTextEl     = $(countyTextEl);
        this.countySelectElId = countySelectEl;
        this.countySelectEl   = $(countySelectEl);
        this.counties         = counties;
        this.countyFieldsRowEl= $(countyFieldsRowEl);
        this.countyRowEl      = $(countyRowEl);
        this.taxexemptEl      = $(taxexemptEl);
        this.taxexemptRowEl   = $(taxexemptRowEl);
        this.radioEl          = $(radioEl);
        this.WisconsinID      = 64;

        this.disableAction    = (typeof disableAction=='undefined') ? 'hide' : disableAction;

        if (this.countySelectEl.options.length<=1) {
            this.update();
        }

        for (i=0;i<addressEls.length;i++)
        {
            if ($(addressEls[i])) 
            { 
                Event.observe($(addressEls[i]), 'change', this.update.bind(this)); 
                Event.observe($(addressEls[i]), 'click', this.update.bind(this)); 
            }
        }
        Event.observe(this.countySelectEl, 'change', this.updateText.bind(this));

    },

    updateText: function()
    {
          var sel_val = this.countySelectEl.value;
          
          if (sel_val=="0")
          {
               this.countyTextEl.value = "";
               this.countyTextEl.disabled = false;
               this.countyRowEl.style.display = "";
          }
          else if (sel_val!="")
          {
               this.countyTextEl.value = this.countySelectEl.options[this.countySelectEl.selectedIndex].text;
               this.countyTextEl.disabled = true;
               this.countyRowEl.style.display = "none";
          } 
          else
          {
               this.countyTextEl.value = "";
               this.countyTextEl.disabled = true;
               this.countyRowEl.style.display = "none";
          }

    },

    update: function()
    {                                            
        this.regionId = this.addressObj.getRegionId();

//        this.taxexemptRowEl.style.display = (this.regionId!=this.WisconsinID || (this.radioEl && this.radioEl.checked)) ? "none":"";
        this.taxexemptRowEl.style.display = "none"; //(this.radioEl && this.radioEl.checked) ? "none":"";
//        if (this.regionId!=this.WisconsinID || this.taxexemptEl.checked || (this.radioEl && this.radioEl.checked))
        if (this.taxexemptEl.checked || (this.radioEl && this.radioEl.checked))
        {
            // hide county when in Billing address form radio-box "billing:use_for_shipping_no" is checked
            // don't show County if address don't use for shipping
            this.countyFieldsRowEl.style.display='none';
            return;
        }
        else 
        {
            this.countyFieldsRowEl.style.display='';
        }

        this.countyRowEl.style.display = "none";
        this.countySelectEl   = $(this.countySelectElId);

        if (this.counties[this.regionId]) {
          
            // UPDATE FORM IF EXIST COUNTIES FOR SELECTED REGION
            
            var i, option, county;

            if (this.countyTextEl) {
                this.countyTextEl.value = '';
            }


            this.countySelectEl.options.length = 1;

            for (countyId in this.counties[this.regionId]) {
                county = this.counties[this.regionId][countyId];
                this.addOption(this.countySelectEl, countyId, county.name);
            }

            this.addOption(this.countySelectEl, "0", "other...");

            if (this.disableAction=='hide') 
            {
                if (this.countyTextEl) 
                {
                    this.countyTextEl.style.display = 'none';
                }
                this.countySelectEl.style.display = '';
            } 
            else if (this.disableAction=='disable') 
            {
                if (this.countyTextEl) 
                {
                    this.countyTextEl.disabled = true;
                }
                this.countySelectEl.disabled = false;
            }
            this.setMarkDisplay(this.countySelectEl, true);
            
        } else { // UPDATE FORM IF NOT EXISTS COUNTIES FOR SELECTED REGION
        
            //this.countySelectEl.options.length = 1; // incorrect work in Google Chrome
            this.removeOptions(this.countySelectEl,1);
            this.addOption(this.countySelectEl, "0", "other...");
            this.countySelectEl.value = "0";
            this.countySelectEl.disabled = false;
            this.countyRowEl.style.display = "";
            this.countyTextEl.value = "";
            this.countyTextEl.disabled = false;
            Validation.reset(this.countySelectEl);

        }

    },

    removeOptions: function(selEl,startIdx)
    {
        if (!selEl.options || !selEl.options.length) { return; }
        qty = selEl.options.length-startIdx;
        for (i=startIdx;i<qty;i++) { selEl.remove(startIdx); } // index must 1 (not i)
    },
    
    addOption: function(selEl,val,txt)
    {
        is_exists = false;
        if (selEl.options) { for (i=0;i<selEl.options.length;i++) { if (selEl.options[i].value==val && selEl.options[i].text==txt) { is_exists=true; } } }
        if (!is_exists)
        {
            option = document.createElement('OPTION');
            option.value = val;
            option.text = txt;
            if (selEl.options.add) {
                selEl.options.add(option);
            } else {
                selEl.appendChild(option);
            }
        }
    },
    
    setMarkDisplay: function(elem, display){
        elem = $(elem);
        var labelElement = elem.up(0).down('label > span.required') ||
                           elem.up(1).down('label > span.required') ||
                           elem.up(0).down('label.required > em') ||
                           elem.up(1).down('label.required > em');
        if(labelElement) {
            inputElement = labelElement.up().next('input');
            if (display) {
                labelElement.show();
                if (inputElement) {
                    inputElement.addClassName('required-entry');
                }
            } else {
                labelElement.hide();
                if (inputElement) {
                    inputElement.removeClassName('required-entry');
                }
            }
        }
    }
}


CityUpdater = Class.create();
CityUpdater.prototype = {
    initialize: function (regionEl, cityTextEl, citySelectEl, cityRowEl, cities, disableAction)
    {
        this.regionEl = $(regionEl);
        this.cityTextEl = $(cityTextEl);
        this.citySelectEl = $(citySelectEl);
        this.cities = cities;
        this.cityRowEl = $(cityRowEl);

        this.disableAction = (typeof disableAction=='undefined') ? 'hide' : disableAction;

        if (this.citySelectEl.options.length<=1) {
            this.update();
        }

        this.cityRowEl.style.display = "none";
        Event.observe(this.regionEl, 'change', this.update.bind(this));
        Event.observe(this.citySelectEl, 'change', this.updateText.bind(this));
    },

    updateText: function()
    {
          var sel_val = this.citySelectEl.value;
          
          if (sel_val=="0")
          {
               this.cityTextEl.value = "";
               this.cityTextEl.disabled = false;
               this.cityRowEl.style.display = "";
          }
          else if (sel_val!="")
          {
               this.cityTextEl.value = this.citySelectEl.options[this.citySelectEl.selectedIndex].text;
               this.cityTextEl.disabled = true;
               this.cityRowEl.style.display = "none";
          } 
          else
          {
               this.cityTextEl.value = "";
               this.cityTextEl.disabled = true;
               this.cityRowEl.style.display = "none";
          }

    },
     
    update: function()
    {
        if (this.cities[this.regionEl.value]) {
            var i, option, city, def;

            if (this.cityTextEl) {
                def = this.cityTextEl.value.toLowerCase();
                this.cityTextEl.value = '';
            }
            if (!def) {
                def = this.citySelectEl.getAttribute('defaultValue');
            }

            this.citySelectEl.options.length = 1;
            for (cityId in this.cities[this.regionEl.value]) {
                city = this.cities[this.regionEl.value][cityId];

                option = document.createElement('OPTION');
                option.value = cityId;
                option.text = city.name;

                if (this.citySelectEl.options.add) {
                    this.citySelectEl.options.add(option);
                } else {
                    this.citySelectEl.appendChild(option);
                }

                if (cityId==def || city.name.toLowerCase()==def || city.code.toLowerCase()==def) {
                    this.citySelectEl.value = cityId;
                }
            }

            option = document.createElement('OPTION');
            option.value = "0";
            option.text = "other...";

            if (this.citySelectEl.options.add) {
                this.citySelectEl.options.add(option);
            } else {
                this.citySelectEl.appendChild(option);
            }


            if (this.disableAction=='hide') {
                if (this.cityTextEl) {
                    this.cityTextEl.style.display = 'none';
                }

                this.citySelectEl.style.display = '';
            } else if (this.disableAction=='disable') {
                if (this.cityTextEl) {
                    this.cityTextEl.disabled = true;
                }
                this.citySelectEl.disabled = false;
            }
            this.setMarkDisplay(this.citySelectEl, true);
        } else {
            if (this.disableAction=='hide') {
                if (this.cityTextEl) {
                    this.cityTextEl.style.display = '';
                }
                this.citySelectEl.style.display = 'none';
                Validation.reset(this.citySelectEl);
            } else if (this.disableAction=='disable') {
                if (this.cityTextEl) {
                    this.cityTextEl.disabled = false;
                }
                this.citySelectEl.disabled = true;
            } else if (this.disableAction=='nullify') {
                this.citySelectEl.options.length = 1;
                this.citySelectEl.value = '';
                this.citySelectEl.selectedIndex = 0;
                this.lastCountryId = '';
            }
            this.setMarkDisplay(this.citySelectEl, false);
        }

    },

    setMarkDisplay: function(elem, display){
        elem = $(elem);
        var labelElement = elem.up(0).down('label > span.required') ||
                           elem.up(1).down('label > span.required') ||
                           elem.up(0).down('label.required > em') ||
                           elem.up(1).down('label.required > em');
        if(labelElement) {
            inputElement = labelElement.up().next('input');
            if (display) {
                labelElement.show();
                if (inputElement) {
                    inputElement.addClassName('required-entry');
                }
            } else {
                labelElement.hide();
                if (inputElement) {
                    inputElement.removeClassName('required-entry');
                }
            }
        }
    }
}

ZipUpdater = Class.create();
ZipUpdater.prototype = {
    initialize: function(country, zipElement)
    {
        this.country = country;
        this.zipElement = $(zipElement);
    },

    update: function()
    {
        // Country ISO 2-letter codes must be pre-defined
        if (typeof optionalZipCountries == 'undefined') {
            return false;
        }

        // Ajax-request and normal content load compatibility
        if (this.zipElement != undefined) {
            this._setPostcodeOptional();
        } else {
            Event.observe(window, "load", this._setPostcodeOptional.bind(this));
        }
    },

    _setPostcodeOptional: function()
    {
        this.zipElement = $(this.zipElement);
        if (this.zipElement == undefined) {
            return false;
        }

        // find label
        var label = $$('label[for="' + this.zipElement.id + '"]')[0];
        if (label != undefined) {
            var wildCard = label.down('em') || label.down('span.required');
        }

        // Make Zip and its label required/optional
        if (optionalZipCountries.indexOf(this.country) != -1) {
            while (this.zipElement.hasClassName('required-entry')) {
                this.zipElement.removeClassName('required-entry');
            }
            if (wildCard != undefined) {
                wildCard.hide();
            }
        } else {
            this.zipElement.addClassName('required-entry');
            if (wildCard != undefined) {
                wildCard.show();
            }
        }
    }
}

