
brand.product.swatchSet = Class.create(Widget, {    
    sortType: "",    
    isContainer: true,
    isActive: false,
    _started: false,
    _loaded: null,
    _dataMethod: "sort",
    _dataParam: "",
    _activeSet: "",
    _initialized: 0,
    
    // _swatchSelected: Boolean
    // flag true when a sku has been selected
    _swatchSelected: false,

    // initDefault: Boolean
    // start with first swatch selected by default
    initDefault: false,
    
    shadedType: "solo",
    isDiscontinued: false,
    selectedSku: "",

    // productType: String (optional)
    // additional identifier to distinguish btwn products appearing more than once on page.
    // ex: cross-sell vs. main product
    productType: "",
    
    skus: "",
    product: "",
    smooshImg: "",

    sorters: {},
    filters: {},
    
    initialize: function($super, arguments, node) {
        this.setProperties(arguments);
        this.id = node.id; 
        var self = this;
        this._loaded = {};
        this.skus = this.product.skus;        
 
        this.sortType = (this.sortType !== "" ? this.sortType : "color");
        this._dataParam = this.sortType;
        //console.log(this.product.name + " has productType = "+this.productType);

        if (this.isMultiShadedSingleSku) {
            //console.log("brand.product.swatches.initialize: isMultiShadedSingleSku");
            var sku = this.skus[0];
        
            // check for multiple values (arrays) in single sku
            if (Object.isArray(sku.smoosh) && sku.smoosh.length > 0) {
                this.smooshes = {};        
            }
            // save shade info (alternate to sku.smoosh, etc...)
            var idbase = this.product.product_id + "_" + this.productType;
            //console.log("isMultiShadedSingleSku " + this.product.name + " idbase = "+idbase);
            for (var i = 0; i < sku.color.length; i++) {
                var id = "swatch_" + idbase + i.toString();
                if (this.smooshes) {
                    this.smooshes[id] = sku.smoosh[i];        
                }          
            }            
        } else {        
            // template has a sort order
            if (this.product.sorters) {
                this.sorters = this.product.sorters;
            } else {
                // creates default sort order from order of skus in page_data
                var set = []; 
                this.skus.each(function(sku, idx) { 
                    set[idx] = [idx];
                });
                this.sorters[this._dataParam] = set;
            }
        }
         
        $super();
        
        // set first sku as selected if specified selectedSku isn't found in data
        if (this.initDefault && !this._swatchSelected && this._loaded[0]) {
            this.setSwatch(this._loaded[0], { event: "load" });
        }
    },
    
    setSwatch: function(child, args) { 
        //console.log("setSwatch: "+child.id+" / sku path = "+child.sku.path+" args = ",args);        
        //if (args && args.event !== "load") { // on user click event
        if (child && child.sku) { // send event even on initial load
           // fire event broadcaster for external use (e.g coremetrics or shop together)
           document.fire("swatch:click", { sku: child.sku, shadeIdx: child.idx });
        }
        if (!child || this.selectedChildWidget == child) { 
            this.onSelectCallback(child);
            return;
        }
        var sku = child.sku;
        
        this._updateSelected(child, this.selectedChildWidget);
        this.selectedChildWidget = child;
        if (!this.isMultiShadedSingleSku && this.skuField) {
            this.skuField.value = child.sku.path;
        }
        this.onSelectCallback(child, args);
        this._swatchSelected = true;
    },
    
    onSelectCallback: function(child, args) {
        // for external callback use
    },

    processData: function(method, param, nocache) {
        //console.log("brand.product.swatchSet.processData");
        if (!nocache && this.started && (this._dataMethod === method && this._dataParam === param)) { return; }
        this._dataMethod = method;
        this._dataParam = param;

        var set;
        if (method === "sort") {
            if (param === "status") {
                var sorters = this.sorters[param];
                for (var i = 1; i <= 4; i++) {
                    var sub = sorters[i.toString()];
                    if (!set) {
                        set = sub;
                    } else {
                        set.concat(sub);
                    }
                }
            } else {
                set = this.sorters[param];
            }
        } else {
            if (param === "all") {
                this._dataMethod = "sort";
                set = this.sorters[this.sortType];
            } else {
                var filters = this.filters;
                if (filters[param]) {
                    set = filters[param];
                }
            }
        }
        
        this._activeSet = set;
        this._updateSet();
    },

    _updateSet: function() { 
        var children = this.children;
        if (children && this._initialized > 0) {
            var childrenCount = children.length;
            for (var i = 0; i < childrenCount; ++i) {
                var child = children[i];
                $(child.id).style.display = "none";
            }
        }
        
        this._initialized++;
        var ids = this._activeSet;
        //console.log("_updateSet "+ids.length+" this._started = "+this._started);
        if (!ids) return;
        
        var idsCount = ids.length;
        for (var i = 0; i < idsCount; ++i) {
            var idx = ids[i];
            var swatch = this._loaded[idx];
            //console.log("add/show swatch: "+idx+" / "+swatch.sku.shade_name);
            if (!swatch) {
                console.log("idx = "+idx+" ids = ",ids);
                continue;
            }
            var swatchNode = $(swatch.id);
            if (!swatchNode) continue;
            swatchNode.style.display = "block";
            this.domNode.appendChild(swatchNode);
            if (this._addClassByColumn) {
                this._addClassByColumn(swatch, i);
            }
            
            if (!this._started) {
                this.loadSwatch(swatch);
            }
        }
              
    },
     
    loadSwatch: function(swatch) {
        //console.log("loadSwatch");
        if (this.selectedSku && (this.selectedSku === swatch.sku.sku_id )) {
            this.setSwatch(swatch, { event: "load" });
        }
    },

    _updateSelected: function(newChild, oldChild) {        
        if (oldChild) {
            oldChild.selected = false;
            this.toggleSelectedState(oldChild, false);
        }
        newChild.selected = true;
        this.toggleSelectedState(newChild, true);
    }
    
});


brand.product.hexSwatchSet = Class.create(brand.product.swatchSet, 
{
    templateKey : "hexSwatchSet",
    templateString: '<div id="#{id}" class="swatchset-hex-container"></div>',
    
    // skuField: DOM node
    // input field for storing selected sku
    skuField: null,
    
    selectedClass: "swatch_hex_container_selected",
    selectedHexClass: "swatch_hex_selected", 
    
    postCreate: function() {
        //console.log("brand.product.hexSwatchSet.postCreate "+this.id); 
        var skuCount = this.skus.length;
        for (var i = 0; i < skuCount; ++i) { 
            var sku = this.skus[i];
            var cid = "swatch_" + sku.sku_id; 
            if (this.product.video_prod) {
                this.video_prod = true;
                cid = "video_" + cid;
            }
            //console.log("brand.product.hexSwatchSet.postCreate, this.product.video_prod = "+this.product.video_prod+" cid = "+cid);
            
            var swatch = new brand.product.hexSwatch({
                id: cid,
                sku: sku,
                containerId: this.id,
                parentId: this.id,
                idx: i
            });                
            this._loaded[i] = swatch;
            
        }
        
        this.processData(this._dataMethod, this._dataParam);
        this._started = true;
    },
    
    toggleSelectedState: function(child, state) {
        if (!child || !this.selectedClass) return;
        if (state) {
            child.domNode.addClassName(this.selectedClass);
            child.hexNode.addClassName(this.selectedHexClass);
        } else {
            child.domNode.removeClassName(this.selectedClass);
            child.hexNode.removeClassName(this.selectedHexClass);
        }
    }
    
});


brand.product.thumbSwatchSet = Class.create(brand.product.swatchSet, 
{

    templateKey : "thumbSwatchSet",
    templateString: '<div id="#{id}" class="swatchset-thumbs-container"></div>',

    selectedClass: "swatch-thumb-selected",
    
    // skuField: DOM node
    // input field for storing selected sku
    skuField: null,

    // arrays for multiple values associated w/ each sku (ex: multi-colored skus)
    smooshes: null,
    
    // # of thumbs on each horizontal line
    columns: 7,

/*    
    initialize: function($super, arguments, node) {
        $super(arguments, node);
    },
*/
                        
    postCreate: function() {
        //console.log("brand.product.thumbSwatchSet.postCreate "+this.id); 
        var idbase = this.product.product_id + "_" + this.productType;
        //console.log("brand.product.thumbSwatchSet.postCreate idbase = "+idbase);
        
        if (this.isMultiShadedSingleSku) {
            var sku = this.skus[0];
            var itemCount = sku.shade_name.length;
            for (var i = 0; i < itemCount; i++) { 
                var cid = "swatch_" + idbase + i.toString();
                var name = (sku.shade_name[i] ? sku.shade_name[i] : "");
                var hex = (sku.color[i] ? sku.color[i].toString() : null);
                var swatch = new brand.product.thumbSwatch({
                    id: cid,
                    sku: sku,
                    idx: i,
                    name: name,
                    smooshThumb: sku.smoosh_thumb[i],
                    hex: hex,
                    parentId: this.id,
                    parentIsSingleSku: this.isMultiShadedSingleSku                   
                });
                if (this._addClassByColumn) {
                    this._addClassByColumn(swatch, i);
                }
            }
            
        } else {        
            var skuCount = this.skus.length;
            for (var i = 0; i < skuCount; ++i) { 
                var sku = this.skus[i];
                var cid = "swatch_" + sku.sku_id;           
                var swatch = new brand.product.thumbSwatch({
                    id: cid,
                    sku: sku,
                    containerId: this.id,
                    idx: i,
                    parentId: this.id
                });                
                this._loaded[i] = swatch;
    
            }
            
            this.processData(this._dataMethod, this._dataParam);
        }
        
        this._started = true;
    },
    
    toggleSelectedState: function(child, state) {
        if (state) {
            child.shadeNode.addClassName(this.selectedClass);
        } else {
            child.shadeNode.removeClassName(this.selectedClass);
        }
    },
    
    _addClassByColumn: function(swatch, positionIdx) {        
        // get column position
        var columns = this.columns;
        var col = 1;
        if (columns) {
            var num = (positionIdx + 1); // start from 1 instead of 0
            if (num > columns) {
                var multiplyby = Math.floor(positionIdx / columns);
                col = (num - (columns * multiplyby));
            } else {
                col = num;
            }
            // save class name to assign on mouseover
            // NOTE: saving for later since removing/adding classnames at this stage for all swatches would affect perfomance on prods w/ lots of skus
            swatch.columnClass = "thumb-col"+col;
            swatch.resetColumnClass = true;
        }
    }
});


/** Individual Swatch Classes **/

brand.product.swatch = Class.create(Widget,
{

    sku: null,
    name: null,
    type: "solo",
    selected: false,
    hex: null,
    rgb: "",
    idx: 0, // sku index 
    
    // smooshThumb: String
    // thumb jpg path: required for thumbSwatch, optional for hexSwatch
    smooshThumb: null, 

    initialize: function($super, arguments) { 
        this.setProperties(arguments);
        
        var sku = this.sku;
        this.smooshThumb = arguments.smooshThumb || sku.smoosh_thumb;
        this.hex = arguments.hex || (sku.color[0] ? sku.color[0].toString() : null);
        this.name = arguments.name || sku.shade_name;
		if(sku.shoppable == 0){ // Show sold out in tooltip if sku isn't shoppable
			this.name += " ("+sku.inventory_status_message+")";
		}
        this.rgb = brand.hexToRGB(this.hex);
        
        $super();
    },
    
    postCreate: function() { 
        if ( this.rgb ) { 
            this._setTextColor(this.rgb);
        }
    },

    _onClick: function(e) {
        if (e) e.preventDefault();
        this.parent.setSwatch(this, { event: e });
    },
    
    _setTextColor: function(rgb) {
        if (!rgb || !this.tooltipNode) { return; }
        // if color is light, set text to black for appropriate contrast
        if (this._isBright(rgb)) {
            this.tooltipNode.style.color = "#000";
        }
    },
    
    _getBrightness: function(rgb) {
        if (!rgb) { return; }
        var total = rgb[0] + rgb[1] + rgb[2];
        return total;
    },

    _isBright: function(rgb) {
        if (!rgb) { return; }
        var isBright = this._getBrightness(rgb) > 450;
        return isBright;
    }
    
});


brand.product.hexSwatch = Class.create(brand.product.swatch,
{
    _swatchPath: "jsTemplates.product.hexSwatch",
    _swatchImagePath: "jsTemplates.product.hexSwatchImage",
     
    initialize: function($super, arguments) {
        this.setProperties(arguments);       
        this.templatePath = this._swatchPath;

        if ( this.sku.sku_multicolor_type ) { 
            this.type = this.sku.sku_multicolor_type;
        }
        if ( this.type === "duo" || ( this.type === "solo" && this._isDark(this.rgb) ) ) {
            this.templatePath = this._swatchImagePath;
        }
        
        $super(arguments);
    },
    
    _onMouseOver: function(e) {
        if (this.name && this.tooltipNode) {
            this.tooltipNode.style.visibility = "visible";
            this.domNode.style.zIndex = "10"; // fix for IE position+layering bug
        }
    },

    _onMouseOut: function(e) {
        if (this.name && this.tooltipNode) {
            this.tooltipNode.style.visibility = "hidden";
            this.domNode.style.zIndex = "1";
        }
    },

    _isDark: function(rgb) {
        if (!rgb) { return; }
        var isDark = this._getBrightness(rgb) < 100;
        return isDark;
    }
});


brand.product.thumbSwatch = Class.create(brand.product.swatch,
{

    templatePath: "jsTemplates.product.thumbSwatch",
    
    resetColumnClass: true,

    initialize: function($super, arguments) {
        this.setProperties(arguments);
        
        // rb keys for template
        if (!this.parentIsSingleSku) {
            this.text_select = site.product.rb["select"];        
            this.text_toshop = site.product.rb.to_shop;
        }
        
        $super(arguments);
    },
    
    postCreate: function($super) {
        this.shadeNode = this.domNode.select("A")[0];
        this.containerClasses = this.domNode.className || "";
        var smooshThumbNode = this.shadeNode.select("IMG")[0];
        try { // IE: avoid choking on invalid hex values
            smooshThumbNode.style.backgroundColor = this.hex;
        } catch(err) {}
        
        // attach event handler here instead of via widget class (workaround
        // for widget class not passing event & event needed for preventDefault)
        this.domNode.observe("click", this._onClick.bind(this));
        
        if (this.name) {
            // tooltip workaround for IE (handled via CSS for other browsers)
            if (generic.env.isIE && this.tooltipNode) {
                this.domNode.observe("mouseover", this._showToolTip.bind(this));
                this.domNode.observe("mouseout", this._hideToolTip.bind(this));
            } else {
                this.domNode.observe("mouseover", this._addClass.bind(this));
            }
        }
        
        $super();
    },

    _addClass: function(e) {
        if (!this.resetColumnClass || !this.columnClass) return;
        this.domNode.className = (this.containerClasses + " " + this.columnClass);
        this.resetColumnClass = false;
    },
    
    _showToolTip: function(e) {
        this._addClass(e);
        this.tooltipNode.style.visibility = "visible";
        this.domNode.style.zIndex = 50; // fix for IE position+layering bug
        this.shadeNode.style.zIndex = 50;
    },

    _hideToolTip: function(e) {
        this.tooltipNode.style.visibility = "hidden";
        this.domNode.style.zIndex = 1;
        this.shadeNode.style.zIndex = 1;
    }
    
});
