
/*

ClickPop/HoverPop USAGE
-----------------------------

There are two ways to create a popover. The first, shown in myPop1,
lets you pass in a MooTools HTML element. The second, shown in myPop2,
lets you pass in the url of a zml file (use the existing popovers in 
/popovers as an example).

Options:
----------
href: /path/to/popover
title: Text to be displayed at the top of the popover
close: true/false, whether the popover should have a close button
html: MooTools HTML element to be the body of the popover
position: top/bottom/left/right, where around the element the popover
            will be placed

-----------------------------

window.addEvent('domready', function() {
    var myPop1 = new ClickPop('#clickableElement','#elementToPopAround',
                                {'position':'top',
                                'title', 'Popover Title',
                                'html', htmlElementVar,
                                'close': false});
    
    var myPop2 = new HoverPop('#clickableElement','#elementToPopAround',
                                {'position':'top',
                                'href':'/popovers/myPopover.zml'});
});

*/

var Popover = new Class({
    Implements: Options,
    options: {
        'href': null,
        'title': null,
        'close': true,
        'html': null,
        'popoverId': null,
        'customClass':null,
        'cache': true,
        'fixed':false,
        'afterRequest': function() {},
        'beforeDisplay': function() {},
        'afterDisplay': function() {},
        'position': 'null'
    },
    
    initialize: function(options) {
        var self = this;
        this.setOptions(options);
        
        this.title = this.options['title'];
        this.href = this.options['href'];
        this.html = this.options['html'];
        this.close = this.options['close'];
        this.customClass = this.options['customClass'];
        this.fixed = this.options['fixed'];
        
        this.popover = new Element('div', {'id': this.options['popoverId'], 'class':'popover'});
        if(this.customClass)
            this.popover.addClass(this.customClass);
        
        this.popover.setStyles({
            'float':'left',
            'position':'absolute',
            'z-index':'10001',
            'background':'#fff'    
        });
        window.popover = this.popover;
        this.cached = false;
    },
    
    makeDiv: function() {
        if(!this.popover.getElement('h3')) {
            var wrapDiv = new Element('div');
            var title = new Element('h3', { 'text': this.title });
            wrapDiv.grab(title);
            if(this.close) {
                var close = new Element('a', { 
                    'html':'close window',
                    'href':'/',
                    'class':'close'
                });
                wrapDiv.grab(close);
            }
            var contentDiv = new Element('div');
            contentDiv.grab(this.options.html);
            wrapDiv.grab(contentDiv);
            this.popover.grab(wrapDiv);
        }
    },
    
    display: function(element) {
        if(this.options.html == null){
            this._getPopover(element);
        } else {
            if(this.title) {
                this.makeDiv();
            } else {
                this.popover.grab(this.options.html);
            }
            var self = this;
            self.popover.getElements('.close').each(function(el){
                el.addEvent('click',function(e){
                   e.preventDefault();
                   self.popover.dispose(); 
                });
            });
            this._display(element);
        }
    },
    
    hide: function() {
        if(this.popover.getParent())
            this.popover.dispose();
    },
    
    _getPopover: function(element) {
        if (this.options['cache'] && this.cached) {
            this._display(element);
        } else {
            var self = this;
            var request = new Request.HTML({
                onComplete: function() {
                    if (self.cached)
                        self.popover.dispose();
                    self.popover.set('html', request.response.html);
                    self.options['afterRequest'].call(self, self.popover); 
                    self.popover.getElements('.close').each(function(el){
                        el.addEvent('click',function(e){
                           e.preventDefault();
                           self.popover.dispose(); 
                        });
                    });
                    self.cached = true;
                    self._display(element);
                }
            }).get(this.href + '?' + $time().toString());
        }
    },
    
    _display: function(element) {
        this.options['beforeDisplay'].call(this, this.popover);
        if (this.popover.getParent())
            this.popover.dispose();
        $(document.body).grab(this.popover);
        this.position[this.options['position']].call(this, element);
        this.options['afterDisplay'].call(this, this.popover, element);
    },
    
    _clickEvent: function(e) {
        e.preventDefault();
        this._getPopover();
    },
    
    position: {
        'null': function() {},
        
        'centerScreen': function() {
            var width = document.getCoordinates().width - 200;
            if (width > 800) width = 800;
            this.popover.setStyles({
                'top':document.getScroll().y + 132,
                'width':width
            });
            this.popover.setStyle('left', 
                document.getScroll().x + 
                Math.floor(document.getCoordinates().width / 2) - 
                Math.floor(this.popover.getStyle('width').toInt() / 2)
            );
        },
        
        'top': function(element) {
            var eleSize = element.getSize();
            var width = this.popover.getSize().x;
            if (width > 500) { 
                width = 350;
                this.popover.setStyles({
                    'width':width
                });
            }
            
            var docWidth = document.getCoordinates().width;
            var popSize = this.popover.getSize();
            var elePos = element.getCoordinates();

            this.popover.setStyle('right',
                docWidth - (elePos.left + (eleSize.x / 2)) - (popSize.x / 2)
            );

            if(this.fixed){
                this.popover.setStyle('top',
                    elePos.top - popSize.y + document.getScroll().y - 15
                );
            } else {
                this.popover.setStyle('top',
                    elePos.top - popSize.y - 15
                );
            }
            
            this.popNotch = new Element('img', {'class':'notch', 'src':'/imgs/popovers/popNotchTop.20091110183750.gif'}); 
            this.popNotch.setStyle('bottom', -16);
            this.popNotch.setStyle('left',
                (popSize.x / 2) - 10
            );

            this.popover.grab(this.popNotch);
        },

        'bottom': function(element) {
            var eleSize = element.getSize();
            var width = this.popover.getSize().x;
            if (width > 500) { 
                width = 350;
                this.popover.setStyles({
                    'width':width
                });
            }

            var docWidth = document.getCoordinates().width;
            var popSize = this.popover.getSize();
            var elePos = element.getCoordinates();

            this.popover.setStyle('right',
                docWidth - (elePos.left + (eleSize.x / 2)) - (popSize.x / 2)
            );
            
            if(this.fixed){
                this.popover.setStyle('top',
                    elePos.top + eleSize.y + document.getScroll().y + 20
                );
            } else {
                this.popover.setStyle('top',
                    elePos.top + eleSize.y + 20
                );
            }

            this.popNotch = new Element('img', {'class':'notch', 'src':'/imgs/popovers/popNotchBottom.20091110183750.gif'}); 
            this.popNotch.setStyle('top', -16);
            this.popNotch.setStyle('left',
                (popSize.x / 2) - 10
            );

            this.popover.grab(this.popNotch);
        },
        
        'right': function(element) {
            var eleSize = element.getSize();
            var width = this.popover.getSize().x;
            if (width > 500) { 
                width = 350;
                this.popover.setStyles({
                    'width':width
                });
            }
            
            var popSize = this.popover.getSize();
            var elePos = element.getPosition();
            
            this.popover.setStyle('left',
                elePos.x + eleSize.x + 25
            );
            
            if(this.fixed){
                this.popover.setStyle('top',
                    elePos.y - (popSize.y / 2) + (eleSize.y / 2) + document.getScroll().y
                );
            } else {
                this.popover.setStyle('top',
                    elePos.y - (popSize.y / 2) + (eleSize.y / 2)
                );
            }
            
            this.popNotch = new Element('img', {'class':'notch', 'src':'/imgs/popovers/popNotchRight.20091110183750.gif'}); 
            this.popNotch.setStyle('left', -16);
            this.popNotch.setStyle('top',
                (popSize.y / 2) - 14
            );

            this.popover.grab(this.popNotch);
            
        },
        
        'left': function(element) {
            var eleSize = element.getSize();
            var width = this.popover.getSize().x;
            if (width > 500) { 
                width = 350;
                this.popover.setStyles({
                    'width':width
                });
            }
            
            var docWidth = document.getCoordinates().width;
            var popSize = this.popover.getSize();
            var elePos = this.element.getPosition();
            
            this.popover.setStyle('right',
                docWidth - elePos.x + 25
            );
            
            if(this.fixed){
                this.popover.setStyle('top',
                    elePos.y - (popSize.y / 2) + (eleSize.y / 2) + document.getScroll().y
                );
            } else {
                this.popover.setStyle('top',
                    elePos.y - (popSize.y / 2) + (eleSize.y / 2)
                );
            }

            this.popNotch = new Element('img', {'class':'notch', 'src':'/imgs/popovers/popNotchLeft.20091110183750.gif'}); 
            this.popNotch.setStyle('right', -16);
            this.popNotch.setStyle('top',
                (popSize.y / 2) - 14
            );

            this.popover.grab(this.popNotch);            

        }
    },
    
    _error: function(fn, msg) {
        throw("Popover Error in " + fn + ": " + msg);
    }
});

var ClickPop = new Class({
    options: {
        'href': null,
        'title': null,
        'close': true,
        'html': null,
        'popoverId': null,
        'cache': true,
        'customClass':null,
        'fixed':false,
        'afterRequest': function() {},
        'beforeDisplay': function() {},
        'afterDisplay': function() {},
        'position': 'null'
    },
    
    initialize: function(clickElement, popToElement, options) {
        this.displayPop = new Popover(options);
        var that = this;
        if (document.getElement(clickElement))
            document.getElement(clickElement).addEvent('click', function(event) {
                event.preventDefault();
                that.displayPop.display(document.getElement(popToElement));
            });
    },
    
    hide: function() {
        this.displayPop.hide();
    }
});

var HoverPop = new Class({
    options: {
        'href': null,
        'title': null,
        'close': true,
        'html': null,
        'popoverId': null,
        'cache': true,
        'customClass':null,
        'fixed':false,
        'afterRequest': function() {},
        'beforeDisplay': function() {},
        'afterDisplay': function() {},
        'position': 'null'
    },
    
    initialize: function(clickElement, popToElement, options) {
        var displayPop = new Popover(options);
        document.getElement(clickElement).addEvent('mouseover', function(event) {
            event.preventDefault();
            displayPop.display(document.getElement(popToElement));
        });
        document.getElement(clickElement).addEvent('mouseout', function(event) {
            event.preventDefault();
            displayPop.hide();
        });
        document.getElement(clickElement).addEvent('click', function(event) {
            event.preventDefault();
        });
    }
});

var BrandListPop = new Class({
    initialize: function(brands) {
        console.time('Timing brand events');
        
        this.brands = brands;
        this.cache = [];
        this.bar = document.getElement('#brandAlpha');
        
        this.createEvents();
        
        this.notch = new Element('img',{'src':'/imgs/popovers/brandNotch.20091110183750.gif'});
        this.notch.setStyle('display', 'none');
        $(document.body).grab(this.notch);
        console.timeEnd('Timing brand events');
        
    },
    
    toggleList: function(letter, target) {
        var openDiv = document.getElement('.brandlist-popover');
        if(openDiv) {
            openDiv.dispose();
            this.notch.setStyle('display','none');
            document.getElement('#brandAlpha a.selected').removeClass('selected');
        }    
            
        if(!this.cache[letter]) {
            var letterDiv = this.createDiv(letter);
            this.cache[letter] = letterDiv;
            this.displayList(letterDiv, target);
        } else {
            if(this.cache[letter] == openDiv) {
                openDiv.setStyle('display','none');
                return;
            }
            
            this.displayList(this.cache[letter], target);
        }
    },
    
    createDiv: function(letter) {
        var wrapperDiv = new Element('div', {
            'class':'brandlist-popover',
            'events': {
                'click': function(event) {
                    event.stopPropagation();
                }
            }
        });
        var letterBrands = this.brands.filter(function(brand) {
            if(brand.match(new RegExp('^[' + letter + ']'))){
                return brand;
            }
        });
        
        var currUl;
        
        if(letterBrands.length == 0) {
            wrapperDiv.grab(new Element('p',{'text':'We do not currently carry any brands that begin with this letter.'}));
        } else if(letterBrands.length == 1) {
            currUl = new Element('ul');
            var cleanBrand = letterBrands[0].cleanASCII();
            var li = new Element('li');
            var anch = new Element('a', {
                'text':cleanBrand, 
                'href':'/search/' + cleanBrand
            });
            
            li.grab(anch);
            currUl.grab(li);
            wrapperDiv.grab(currUl);
        } else {
            for(var i = 0; i < letterBrands.length; i++) {
                if(i == 0 || i % Math.ceil(letterBrands.length/5) == 0) {
                    if(i != 0) { wrapperDiv.grab(currUl); }
                    currUl = new Element('ul');
                }

                var cleanBrand = letterBrands[i].cleanASCII();

                var li = new Element('li');
                var anch = new Element('a', {
                    'text':cleanBrand, 
                    'href':'/search/' + cleanBrand
                });

                li.grab(anch);
                currUl.grab(li);
            }
            wrapperDiv.grab(currUl);
        }
        return wrapperDiv;
    },
    
    displayList: function(brandList, target) {
        $(document.body).grab(brandList);
        brandList.setStyles({
            'display':'block',
            'z-index':1200,
            'width':962,
            'position':'absolute',
            'background':'#fff',
            'top':this.bar.getPosition(window).y + this.bar.getSize().y + 3,
            'right':this.bar.getPosition(window).x
        });
        
        target.addClass('selected');
        
        this.notch.setStyles({
            'display':'block',
            'position':'absolute',
            'z-index':1205,
            'left':target.getPosition(window).x + 2,
            'top':brandList.getPosition(window).y - 19
        });
    },
    
    createEvents: function() {
        var that = this;
        var alphlist = ['#list-a','#list-b','#list-c','#list-d','#list-e','#list-f','#list-g','#list-h','#list-i','#list-j','#list-k','#list-l','#list-m','#list-n','#list-o','#list-p','#list-q','#list-r','#list-s','#list-t','#list-u','#list-v','#list-w','#list-x','#list-y','#list-z'];
        var reglist = ['aA','bB','cC','dD','eE','fF','gG','hH','iI','jJ','kK','lL','mM','nN','oO','pP','qQ','rR','sS','tT','uU','vV','wW','xX','yY','zZ'];
        
        document.getElement('#list-spec').addEvent('click', function(event) {
            event.preventDefault();
            event.stopPropagation();
            that.toggleList('^A-Za-z', event.target);
        });        
        
        alphlist.each(function(alph, index) {
            document.getElement(alph).addEvent('click', function(event) {
                event.preventDefault();
                event.stopPropagation();
                that.toggleList(reglist[index], event.target);
            });
        });
        
        $(document.body).addEvent('click', function(event) {
            if($(event.target).getProperty('class') != 'brandlist-popover' && 
            document.getElement('.brandlist-popover')) {
                document.getElement('.brandlist-popover').dispose();
                document.getElement('#brandAlpha a.selected').removeClass('selected');
                that.notch.setStyle('display','none');
            }
        });
    }
});
