﻿(function($) {
    var root = this;
    
    var LG = root.LipidGuide = {};
    
    LG._defaults = {
        ctaTriggerEvent: "mouseenter",
        toggleSelector: ".ctaToggle",
        inactiveSelector: ".inactiveContent",
        activeSelector: ".activeContent",
        initialSelector: ".initialContent",
        closeSelector: ".closeBtn",
        tabGroupSelector: "#lgTabs",
        tabsSelector: ".lgTab",        
        activeClass: "expanded",
        collapsedWidth: 230,
        expandedWidth: 470
    };
    
    $.extend(LG, {
        init: function(element, options) {
            this.options = $.extend({}, LG._defaults, options || {});
            this.element = $(element);            
            
            this._open = false;
            this._inProgress = false;
            this._tabsEnabled = false;
            this._currTab = null;
            
            // the height of the widget has to change for certain tabs
            this._tabHeightMap = {
                0: "",
                1: 428,
                2: 605
            };
            
            this._setBinds();
            this._query();
            
            this._setup();
            this._attach();
            
            return this;
        },
        
        $: function(selector) {
            return $(selector, this.element);
        },
        
        _setBinds: function() {
            var bound = this._bound = {};
            
            bound.show = $.proxy(function(event) {
                event.preventDefault();
                event.stopPropagation();
                this._show();
            }, this);
            bound.hide = $.proxy(function(event) {
                event.preventDefault();
                this._hide();
            }, this);
            
            bound.onTabClick = $.proxy(this._onTabClick, this);
            bound.onKnobClick = $.proxy(this._onKnobClick, this);
            
            return this;
        },
        
        // gets relevant elements
        _query: function() {
            var opts = this.options;
            
            this.doc = $(document);
            this._toggle            = this.$(opts.toggleSelector);
            this._inactivePanel     = this.$(opts.inactiveSelector);
            this._activePanel       = this.$(opts.activeSelector);
            this._initialContent    = this.$(opts.initialSelector);
            this._closeBtn          = this.$(opts.closeSelector);
            this._tabGroup          = this.$(opts.tabGroupSelector);
            this._tabs              = this.$(opts.tabsSelector);
            
            return this;
        },
        
        // inits content/slider objects
        _setup: function() {
            LG.SLIDER1.init();
            LG.SLIDER2.init();
            LG.SLIDER3.init();
            
            return this;
        },
                
        _attach: function() {
            var bound = this._bound,
                opts = this.options;
            
            this.doc.bind("lipidguide.meter1.drag", bound.onKnobClick);
                     
            this._toggle.bind(opts.ctaTriggerEvent, bound.show);
            this._closeBtn.bind("click", bound.hide);
            this._tabs.each(function(index, el) {
                $(el).bind("click", function(event) {
                    bound.onTabClick(event, index);
                });
            });            
            
            return this;
        },
        
        _show: function() {
            if (this._open || this._inProgress) return this;
            
            this._open = true;
            this._inProgress = true;
            
            var self = this,
                opts = this.options,
                inactive = this._inactivePanel,
                active = this._activePanel,
                initial = this._initialContent;            
            
            inactive.fadeOut();
            
            this.doc.trigger("lipidguide.opening");            
            active.animate({
                width: opts.expandedWidth
            }, 500, function() {
                initial.addClass(opts.activeClass);
                initial.fadeIn(500, function() {
                    self._inProgress = false;
                    self.doc.trigger("lipidguide.open");
                    self._onTabClick(null, self._currTab === null ? 0 : self._currTab);
                    //self.doc.trigger("lipidguide.showtab", [self._currTab]);
                });
            });
            
            
            return this;
        },
        
        _hide: function() {
            if (!this._open || this._inProgress) return this;
            
            this._open = false;
            this._inProgress = true;
            
            var self = this,
                opts = this.options,
                inactive = this._inactivePanel,
                active = this._activePanel,
                initial = this._initialContent,
                curr = this._currTab;
            
            // restore tab state
            if (curr !== null) {
                $(this._tabs[curr]).removeClass("lgActiveTab");
                this._tabGroup.removeClass("tabGroup" + curr);
                this.doc.trigger("lipidguide.hidetab", [curr]);                
                this._currTab = null;
            }
            this._initialContent.css("height", this._tabHeightMap[0]);
            
            this.doc.trigger("lipidguide.closing");
            initial.fadeOut(500, function() {
                initial.removeClass(opts.activeClass);
                active.animate({
                    width: opts.collapsedWidth
                }, 500, function() {
                    inactive.fadeIn(500, function() {
                        self.doc.trigger("lipidguide.close");
                        self._inProgress = false;                                                                         
                    });
                });            
            });

            return this;
        },
        
        _onKnobClick: function() {
            this.doc.unbind("lipidguide.meter1.drag", this._bound.onKnobClick);
            this._tabsEnabled = true;
            this._tabGroup.removeClass("disabled");
            
            return this;
        },
        
        _onTabClick: function(event, index) {
            if (!this._tabsEnabled) {
                event && event.preventDefault();
                return this;
            }
            
            var curr = this._currTab,
                tabs = this._tabs,
                tabGroup = this._tabGroup,
                doc = this.doc;
                                
            if (index === curr) return this;
            
            if (curr !== null) {
                $(tabs[curr]).removeClass("lgActiveTab");
                tabGroup.removeClass("tabGroup" + curr);
                doc.trigger("lipidguide.hidetab", [curr]);
            }
            
            $(tabs[index]).addClass("lgActiveTab");
            tabGroup.addClass("tabGroup" + index);            
            this._initialContent.css("height", this._tabHeightMap[index]);
            doc.trigger("lipidguide.showtab", [index]);
                        
            this._currTab = index;
        }
        
    });
    
    // slider base
    LG._sliderBase = {
        init: function() {
            var opts = this.options = $.extend({}, LG._sliderDefaults, this._defaults);            
            this.element = this.$(opts.element);
            this._setBinds();            
            this._query();
            this._attach();            
            if (opts.dragInitEvent) {
                this._delayDragStart();
            }
            else {
                this._makeDrag();
            }
            
            return this;
        },
        
        $: function(selector) {
            return $(selector, this.element);
        },
        
        _query: function() {
            var opts = this.options;
            this.doc = $(document);
            this._track = this.$(opts.trackSelector);
            this._knob = this.$(opts.knobSelector);
            this._meter = this.$(opts.meterSelector);
            return this;
        },
                
        
        _setBinds: function() {},
        
        _attach: function() {},
        
        _getDragOpts: function() {
            return {};
        },
        
        _delayDragStart: function() {
            var opts = this.options;
            
            var initDragOnce = $.proxy(function() {
                if (opts.dragInitFilter.apply(this, arguments)) {
                    this.doc.unbind(opts.dragInitEvent, initDragOnce);
                    this._makeDrag();
                }
            }, this);
            
            this.doc.bind(opts.dragInitEvent, initDragOnce);
                        
            return this;
        },
        
        _makeDrag: function() {
            var opts = this.options;

            this.drag = this._knob.draggable($.extend({}, LG._dragOpts, this._getDragOpts()));
            this._attachDragHandlers();            
            
            return this;            
        },
        
        _attachDragHandlers: function() {}
    };
    
    LG._sliderDefaults = {
        element: "",
        trackSelector: ".lgTrack",
        knobSelector: ".lgKnob",
        meterSelector: ".meter",
        
        dragInitEvent: "lipidguide.showtab",
        dragInitFilter: function() {return true;}
    };
    
    // base draggable options
    LG._dragOpts = {};
    
    // slider 1
    LG.SLIDER1 = $.extend({}, LG._sliderBase, {
        _defaults: {
            element: "#lgMeter1",           
            dragInitEvent: false,
            tabIndex: 0,
            dragInitFilter: function(event, index) {
                return this.options.tabIndex === index; 
            }
        },
        
        init: function() {
            LG._sliderBase.init.apply(this, arguments);
            
            // headlines
            var headlines = this._headlines,
                len = headlines.length;
            headlines.hide().each(function(index, el) {
                $(el).css({
                    position: "absolute",
                    left: 0,
                    top: 0,
                    zIndex: len - index
                });                
            });
            
            this._curr = 0;
            this._value = 0;
            
            $(headlines[0]).show();
            
            
            return this;
        },
        
        _query: function() {
            LG._sliderBase._query.apply(this, arguments);
            this._headlines = this.$(".lgMeterHeadline");
            this._knobIndicator = this.$(".lgMeterIndicator");
            
            return this;
        },
        
        _setBinds: function() {
            var bound = this._bound = {};
            
            bound.onDrag = $.proxy(this._onDrag, this);   
            bound.onDragStart = $.proxy(this._onDragStart, this);         
            bound.onDragStop = $.proxy(this._onDragStop, this);         
            
            return this;
        },
        
        _attach: function() {

            return this;
        },
        
        _getDragOpts: function() {            
            return {
                containment: this._track,
                snap: true,
                grid: [8, 0]
            };
        },
        
        _onDrag: function(value) {
            var curr = this._curr,
                headlines = this._headlines,                
                index = 0;
            
            if (value < 200) {
                index = 0;
                
            }
            else if (value >= 200 && value < 500) {
                index = 1;
            }
            else {
                index = 2;
            }
            
            if (index !== curr) {
                $(headlines[curr]).fadeOut();
                $(headlines[index]).fadeIn();
                this._meter[index === 0 ? "removeClass" : "addClass"]("meterHigh");
                
                this._curr = index;                
            }
            
            return this;
        },
        
        _onDragStart: function() {
            var self = this,
                knob = this._knob,
                indicator = this._knobIndicator,
                left,
                value;
            
            
            clearTimeout(this._timer);
            (function parseDrag() {
                self._timer = setTimeout(function() {
                    left = parseInt(knob.css("left"), 10);
                    left = !!!left ? 0 : left;
                    //if (left === NaN) left = 0;
                    
                    value = left / 8 * 10 + 100;
                    
                    /* end of the meter makes no sense...
                    if (value > 400) {
                        value = 400 + ( (value - 400) / 10 * 20 );
                    }
                    */
                    /*
                    if (value === 100) value = 0
                    */
                    indicator.html(value).show();
                    
                    self._value = value;
                    self.doc.trigger("lipidguide.meter1.drag", [value]);
                    self._onDrag(value);                    
                    
                    parseDrag();
                }, 75);
            }());
            
            return this;
        },
        
        _onDragStop: function() {
            clearTimeout(this._timer);
            this.doc.trigger("lipidguide.meter1.dragend", [this._value]);
            return this;
        },
        
        _attachDragHandlers: function() {            
            var bound = this._bound;
            this._knob.bind({ 
                mousedown: bound.onDragStart,
                mouseup: bound.onDragStop
            });
            
            return this;                
        }
        
    });


    // slider 2
    LG.SLIDER2 = $.extend({}, LG._sliderBase, {
        _defaults: {
            element: "#lgMeter2",           
            dragInitEvent: false,
            tabIndex: 1,
            dragInitFilter: function(event, index) {
                return this.options.tabIndex === index; 
            }
        },
        
        
        init: function() {
            LG._sliderBase.init.apply(this, arguments);
            
            // headlines
            var headlines = this._headlines,
                len = headlines.length;
            headlines.hide().each(function(index, el) {
                $(el).css({
                    position: "absolute",
                    left: 0,
                    top: 0,
                    zIndex: len - index
                });                
            });
            
            this._curr = 0;
            this._value = 0;
            $(headlines[0]).show();
            
            
            return this;
        },
        
        _query: function() {
            LG._sliderBase._query.apply(this, arguments);
            this._headlines = this.$(".lgMeterHeadline");
            this._knobIndicator = this.$(".lgMeterIndicator");
            this._finePrint = this.$(".lgFinePrint");
            return this;
        },
        
        _setBinds: function() {
            var bound = this._bound = {};
            
            bound.onDrag = $.proxy(this._onDrag, this);   
            bound.onDragStart = $.proxy(this._onDragStart, this);         
            bound.onDragStop = $.proxy(this._onDragStop, this);         
            
            return this;
        },
        
        
        _attach: function() {
            var self = this;
            this.doc.bind({
                "lipidguide.showtab": function(event, index) {
                    if (index === self.options.tabIndex) {
                        self._shown = true;
                        self.element.show();  
                    }                  
                },
                "lipidguide.hidetab": function(event, index) {
                    if (index === self.options.tabIndex && self._shown) {
                        self.element.hide();
                        self._reset();                    
                        self._shown = false;
                    }
                }
            });
            
            return this;
        },
        
        _getDragOpts: function() {            
            return {
                containment: this._track,
                snap: true,
                grid: [9, 0]
            };
        },
        
        _onDrag: function(value) {
            var curr = this._curr,
                headlines = this._headlines,                
                index = 0;
            
            if (value <= 39) {
                index = 1;                
            }
            else if (value >= 40 && value <= 59) {
                index = 2;
            }
            else {
                index = 3;
            }
            
            if (index !== curr) {
                $(headlines[curr]).fadeOut();
                $(headlines[index]).fadeIn();
                this._meter[index === 1 ? "addClass" : "removeClass"]("meterHigh");
                this._finePrint[index === 1 ? "show" : "hide"]();
                
                this._curr = index;
            }
            
            return this;
        },
        
        _onDragStart: function() {
            var self = this,
                knob = this._knob,
                indicator = this._knobIndicator,
                left,
                value;
            
            
            clearTimeout(this._timer);
            (function parseDrag() {
                self._timer = setTimeout(function() {
                    left = parseInt(knob.css("left"), 10);
                    left = !!!left ? 0 : left;
                    //if (left === NaN) left = 0;
                    value = left / 9 + 27;
                    
                    indicator.html(value).show();
                    
                    self._value = value;
                    self.doc.trigger("lipidguide.meter2.drag", [value]);
                    self._onDrag(value);
                    
                    parseDrag();
                }, 75);
            })();
            
            return this;
        },
        
        _onDragStop: function() {
            clearTimeout(this._timer);
            this.doc.trigger("lipidguide.meter2.dragend", [this._value]);
            return this;
        },
        
        _attachDragHandlers: function() {            
            var bound = this._bound;
            this._knob.bind({ 
                mousedown: bound.onDragStart,
                mouseup: bound.onDragStop
            });
            
            return this;                
        },        
        
        _reset: function() {
        
        }
        
    });    
    


    // slider 3
    LG.SLIDER3 = $.extend({}, LG._sliderBase, {
        _defaults: {
            element: "#lgMeter3",           
            dragInitEvent: false,
            tabIndex: 2,
            dragInitFilter: function(event, index) {
                return this.options.tabIndex === index; 
            }
        },
        
        
        init: function() {
            LG._sliderBase.init.apply(this, arguments);
            this._posMap = {
                0: 85,
                1: 153,
                2: 223
            };

            this._valueMap = {
                0: "&lt;100",
                1: "&lt;130",
                2: "&lt;160"
            };                        
            
            this._curr = null;
            
            return this;
        },
        
        _query: function() {
            LG._sliderBase._query.apply(this, arguments);
            this._knobIndicator = this.$(".lgMeterIndicator");
            this._toggles = this.$(".lgRadioSelect");
            this._finePrint = this.$(".meterFinePrint");
            
            return this;
        },
        
        _setBinds: function() {},
        
        
        _attach: function() {
            var self = this;
            this.doc.bind({
                "lipidguide.showtab": function(event, index) {
                    if (index === self.options.tabIndex) {
                        self._shown = true;
                        self.element.show();  
                    }                  
                },
                "lipidguide.hidetab": function(event, index) {
                    if (index === self.options.tabIndex && self._shown) {
                        self.element.hide();
                        self._reset();                    
                        self._shown = false;
                    }
                }
            });
            
            this._toggles.each(function(index, el) {
                $(el).bind("click", function() {
                    var curr = self._curr;
                    if (curr !== index) {                        
                        self._onDrag(index);
                    }
                });
            });
            
            return this;
        },
        
        _getDragOpts: function() {            
            return {
                containment: this._track,
                snap: true,
                grid: [9, 0]
            };
        },
        
        _onDrag: function(index) {
            var curr = this._curr,
                meter = this._meter,
                toggles = this._toggles,
                valueMap = this._valueMap,
                value = valueMap[index]
                            
            if (curr !== null) {
                $(toggles[curr]).removeClass("active");
                meter.removeClass("meterState" + curr);
            }
            
            $(toggles[index]).addClass("active");
            meter.addClass("meterState" + index);
            this._knobIndicator.html(value).show();
            this._knob.css("left", this._posMap[index]);
            
            this._finePrint.hide();
            $(this._finePrint[index]).show();
            
            
            this._curr = index;
            this.doc.trigger("lipidguide.meter3.click", [value]);
            return this;
        },        
        
        
        _attachDragHandlers: function() {            
            // disable the dragging
            this._knob.draggable("disable");
            
            return this;                
        },        
        
        _reset: function() {
        
        }
        
    });        
    
    
    /* TRACKING
    *************************/
        
    // handlers
    var trackHandlers = {};    
    trackHandlers.track20 = function(event, value) {
        // tracking code here
        var s = s_gi(s_account);
        s.linkTrackVars = 'prop9,eVar9,events';
        s.linkTrackEvents = 'event10';
        s.prop9 = value;
        s.eVar9 = value;
        s.events = 'event10';
        s.tl(window,'o','TG Slider Used');

    };
    trackHandlers.track21 = function(event, index) {
        if (index === 0) {
            // tracking code here
            var s=s_gi(s_account);
            s.linkTrackVars='events';
            s.linkTrackEvents='event11';
            s.events='event11';
            s.tl(window,'o','Lipid Quick Guide Guidelines');

        }
    };    
    trackHandlers.track22 = function(event, value) {
        // tracking code here        
        var s = s_gi(s_account);
        s.linkTrackVars = 'prop10,eVar10,events';
        s.linkTrackEvents = 'event12';
        s.prop10 = value;
        s.eVar10 = value;
        s.events = 'event12';
        s.tl(window,'o','HDL-C Slider Used');

    };    
    trackHandlers.track23 = function(event, value) {
        // tracking code here
        value = value.replace("&lt;", "<");
        value = value.replace("&gt;", ">");
                
        var s = s_gi(s_account);
        s.linkTrackVars = 'prop11,eVar11,events';
        s.linkTrackEvents = 'event13';
        s.prop11 = value;
        s.eVar11 = value;
        s.events = 'event13';
        s.tl(window,'o','LDL-C Option Selected');
        
    };    

    
    // bindings
    var doc = $(document);    
    doc.bind("lipidguide.meter1.dragend", trackHandlers.track20);
    doc.bind("lipidguide.showtab", trackHandlers.track21);    
    doc.bind("lipidguide.meter2.dragend", trackHandlers.track22);
    doc.bind("lipidguide.meter3.click", trackHandlers.track23);    


})(jQuery);
