CopyCatFieldSets = Class.create({
    initialize: function(masterElt, slaveElt, triggerElt) {
        this.masterEltTitle = masterElt.title;
        this.slaveEltTitle = slaveElt.title;
        this.masterEltFormFields = masterElt.select('input, select, textarea');
        this.slaveEltFormFields = slaveElt.select('input, select, textarea');
        this.slaveFieldList= $A();
        this.trigger = triggerElt;
        this.trigger.observe('click', this.initObservers.bind(this));
        this.initObservers();
    },

    initObservers : function() {
        if($F(this.trigger)) {
            this.masterEltFormFields.each(function(masterField) {
                var slaveFieldId = this.slaveEltTitle + masterField.id.sub(this.masterEltTitle, "");
                if($(slaveFieldId)){
                    this.slaveFieldList[this.slaveFieldList.size()] = $(slaveFieldId);
                    $(slaveFieldId).setValue($F(masterField));
                    masterField.observe('change', function() {
                        if($F(this.trigger)) $(slaveFieldId).setValue($F(masterField));
                    }.bind(this));
                    if(!$(slaveFieldId).hasClassName('noDisable'))
                        $(slaveFieldId).disable();
                }
            }.bind(this));
        } else {
            this.slaveFieldList.invoke('enable');
        }
    }
});

var Dependent = Class.create({
    initialize: function(childSelectBox, parentSelectBox) {
        this.childSelectBox = childSelectBox;
        this.parentSelectBox = parentSelectBox;

        // Having use cross cutting abilities in Dojo, I missed that feature in Prototype until I found way to do it. Vary Powerful, Like it  
        // Wrapping setValue to work around unavailability of events when control is disabled
        this.parentSelectBox.setValue= this.parentSelectBox.setValue.wrap(this.setValueWrapper.bind(this));
        // add event handler to parent select box value change event
        // seems redundant but its not. When setValue is called change event is not fired, and When change event is fired, setValue is not called, they are mutually exclusive
        this.parentSelectBox.observe('change', this.parentValueChangeListener.bind(this));

        this.childSelectBox.setValue= this.childSelectBox.setValue.wrap(function (proceed,value){
            proceed(value);
            this.simulate('change');
            return true;
        });

        // Keep data for future use.
        this.childSelectOptions = this.childSelectBox.childElements().clone();
        this.setChildOptions();
    },

    // event handler for change in value of parent. change event is not fired for disabled control. May not use this for while
    parentValueChangeListener: function(event) {
        var element = Event.element(event);
        this.setChildOptions();
    },

    setValueWrapper: function (proceed,value){
        proceed(value);
        this.setChildOptions();
        return true;
    },
    setChildOptions: function(){
        var parentTitle = this.parentSelectBox.options[this.parentSelectBox.selectedIndex].title;
        this.childSelectBox.update(); //Removed old options.
        for (var index = 0; index < this.childSelectOptions.length; ++index) {  // Not using each on array because for some reason reference to this is lost.
            var item = this.childSelectOptions[index];
            // adding support for old style DependentSelectBoxes which haven't started using <optgroup/>
            if($(item).label == parentTitle || $(item).hasClassName(parentTitle)){
                this.childSelectBox.appendChild(item);
                // break;
            }
        }
        if(!this.childSelectBox.down('[selected=selected]'))
            this.childSelectBox.selectedIndex = 0;

    }
});

var SelectableProductManager = Class.create({
    initialize: function(formElt) {
        this.formSubmit = formElt.down('input[type=submit]');
        this.featureSelectOptions = formElt.select('select');
        this.targetField = formElt.getInputs(null, 'add_product_id').first();
        this.toDisableFields = formElt.select('.toDisable');
        this.toUpdatePriceElts = formElt.select('.toUpdatePrice');

        this.original = $('original');
        this.emailProductId = $('emailProductId');
        this.mainImage = $('mainImage');

        if (formElt.getInputs(null, 'detailImageUrls').first())
          this.detailImageUrls = $F(formElt.getInputs(null, 'detailImageUrls').first()).evalJSON();
        if (formElt.getInputs(null, 'largeImageUrls').first())
          this.largeImageUrls = $F(formElt.getInputs(null, 'largeImageUrls').first()).evalJSON();
        if (formElt.getInputs(null, 'variantPrices').first())
          this.variantPrices = $F(formElt.getInputs(null, 'variantPrices').first()).evalJSON();
        if (formElt.getInputs(null, 'virtualVariant').first())
          this.virtualVariant = $F(formElt.getInputs(null, 'virtualVariant').first()).evalJSON();
        if (formElt.getInputs(null, 'variantProductIds').first())
          this.variantProductIds = $F(formElt.getInputs(null, 'variantProductIds').first()).evalJSON();
        if (formElt.getInputs(null, 'variantImages').first())
          this.variantImages = $F(formElt.getInputs(null, 'variantImages').first()).evalJSON();
        if (formElt.getInputs(null, 'variantCaptions').first())
          this.variantCaptions = $F(formElt.getInputs(null, 'variantCaptions').first()).evalJSON();
        if (formElt.getInputs(null, 'unavailableVariants').first())
          this.unavailableVariants = $F(formElt.getInputs(null, 'unavailableVariants').first()).evalJSON();

        this.initObservers();
    },

    initObservers: function() {
        obj = this;
        if(!this.featureSelectOptions.length) {
          this.formSubmit.removeClassName('disabled');
        } else {
          this.featureSelectOptions.each(function(elt, i) {
            if(this.featureSelectOptions.length - i - 1) {
              Event.observe(elt, 'change', function(evt) {
                obj.targetField.setValue('NULL');
                obj.toDisableFields.invoke('disable');
                //updateElements(null, obj.toUpdatePriceElts);
                obj.formSubmit.addClassName('disabled');
              });
            } else {
              Event.observe(elt, 'change', function(evt) {
                if($F(this)  && obj.isNotVirtual($F(this))) {
                  obj.targetField.setValue($F(this));
                  if (obj.emailProductId) {
                    obj.emailProductId.setValue($F(this));
                  }
                  obj.toDisableFields.invoke('enable');
                  //updateElements(obj.variantPrices[$F(this)], obj.toUpdatePriceElts);
                  obj.formSubmit.enable();
                  obj.formSubmit.removeClassName('disabled');
                } else {
                  obj.targetField.setValue('NULL');
                  obj.toDisableFields.invoke('disable');
                  //updateElements(null, obj.toUpdatePriceElts);
                  obj.formSubmit.addClassName('disabled');
                }
                obj.setVariantImage($F(this));
                obj.checkAvailability($F(this));
              });
            }
          }.bind(this));

          if(this.featureSelectOptions.first())
            Event.observe(this.featureSelectOptions.first(), 'change', function(evt) {
              if(obj.largeImageUrls[this.selectedIndex - 1]) {
                if(obj.original) obj.original.href = obj.largeImageUrls[this.selectedIndex - 1];
              } else {
                if(obj.original) obj.original.href = obj.largeImageUrls.first();
              }
              if(obj.detailImageUrls[this.selectedIndex - 1]) {
                if(obj.mainImage) obj.mainImage.src = obj.detailImageUrls[this.selectedIndex - 1];
              } else {
                if(obj.mainImage) obj.mainImage.src = obj.detailImageUrls.first();
              }
            });

          this.featureSelectOptions.reverse(false).each(function(elt, i) {
            if(this.last() != elt)
              new Dependent(elt, this[i+1]);
          }.bind(this.featureSelectOptions.reverse(false)));
        }
    },

    isNotVirtual: function(productId){
        return !(this.virtualVariant.member(productId));
    },

    setVariantImage: function(productId) {
       if(this.variantProductIds) {
           var i = this.variantProductIds.indexOf(productId);
           if(this.variantImages[i]) {
              if($('mainImage')) $('mainImage').src = this.variantImages[i];
              if($('originalImage')) $('originalImage').value = this.variantImages[i];
              if($('originalCaption')) $('originalCaption').update(this.variantCaptions[i]);
            }
       }
    },

    checkAvailability: function(productId) {
        if(this.unavailableVariants) {
            var i = this.unavailableVariants.indexOf(productId);
            if(i >= 0) {
                if($('outOfStock')) emailme.open();
                obj.toDisableFields.invoke('disable');
                obj.formSubmit.disable();
                obj.formSubmit.addClassName('disabled');
            }
        }
    }
});

SmartColumns = Class.create({
    initialize: function(){
        this.position();
        Event.observe(window,'resize',this.position.bind(this));
    },
    position: function(){
        var columns = $('columns');
        $(columns).setStyle({
            width: '100%'
        });
        this.resize();
    },
    resize: function(){
        var columns = $('columns');
        var dimensions = $(columns).getDimensions();
        var colWrap = $(dimensions).width;
        var colNum = Math.floor(colWrap / 200);
        var colFixed = Math.floor(colWrap / colNum);
 
        $(columns).setStyle({
            width: colWrap + 'px'
        });
 
        $$('.column-block').each(function(elm) {
            $(elm).setStyle({
                width: colFixed + 'px'
            });
        });
    }
});

var ShowMoreLessText = Class.create({
    initialize: function(){
        $$('a.more').each(function(element){
            element.observe('click',this.toggleMoreLess.bind(this));
        }, this);
    },
    toggleMoreLess: function (event){
        // console.log(event.element());
        var currentElement = Event.element(event);
        var showMoreLessContainer = $(currentElement).getAttribute('rel');
        var showMoreLessCaption = ($(currentElement).innerHTML.toLowerCase() == "more") ? "Less" : "More";

        $(currentElement).update(showMoreLessCaption);
        $(currentElement).addClassName('less');
        $(currentElement).removeClassName('more');

        if ($(showMoreLessContainer)) {
            if ($(showMoreLessContainer).hasClassName('lessInfo')) {
                $(showMoreLessContainer).removeClassName('lessInfo');
            } else {
                $(showMoreLessContainer).addClassName('lessInfo');
                $(currentElement).removeClassName('less');
                $(currentElement).addClassName('more');
            }
        }
    }
});
/*
var NavigationSubMenu= Class.create({
    initialize: function(){
        $$('#nav a').each(function (element) {
            var menu = $($A(element.classNames()).first() + "_menu");
            if(menu) {
                menu.hide();
                element.observe('mouseover',this.showSubNav.bind(this));
            }
        }, this);
    },
    showSubNav: function (event) {
        var button_class = $A(Event.element(event).classNames());
        var drop_div = $($A(Event.element(event).classNames()).first() + "_menu");
        if (drop_div) {
            $$('a.' + button_class).each(function (elm){
                button = elm.identify();
            });
            $$('div.drop').each(function (elm){
                elm.hide();
            });
            $(drop_div).show();
            $(drop_div).observe('mouseout', function() {
                clearTimeout(document.timer);
                document.timer = setTimeout(function() {$(drop_div).hide()},500);
            });
            $(drop_div).observe('mouseover', function() {
                $(drop_div).show();
                clearTimeout(document.timer);
            });
            $(button).observe('mouseout', function(){
                clearTimeout(document.timer);   
                document.timer = setTimeout( function() {$(drop_div).hide()},500);
            });
            $(button).observe('mouseover', function(){
                $(drop_div).show();
                clearTimeout(document.timer);
            });
        }
    }
});
*/
