/**
 * General utility classes for the Nokia Product Pages.
 * @author Adam J. McIntyre | adam.mcintyre@molecular.com
 */
var MOLECULAR = {};

MOLECULAR.browser = {
    ie6 : $.browser.msie == true && $.browser.version < 7,    
    ie7 : $.browser.msie == true && $.browser.version < 8
}

$.browser.ie6 = MOLECULAR.browser.ie6;

MOLECULAR.isIE6Gallery = false;

MOLECULAR.ProductPage = function(){
    var preloads = null;
    var iteration = 0;
    var body;
    var intvl = null;
    
    return{
        levelContent : function(){
			$('.promo:even').each(function(){
                // We must make sure that we take RVP markup into account
                // when levelling content
                var myBdHeight, nextBdHeight, isRVP, isNextRVP = false;
                
                var el = $(this);
                if(el.find('#recentlyViewedProductsHolder').length > 0){
                    var myHd = el.find('div.pp_tsr_header_medium, div.tsr_container_small h2');
                    var myBd = el.find('div.pp_tsr_medium_container, div.tsr_container_small'); 
                    var myCta = el.find('ul a');
                    myBdHeight = myBd.height() - myHd.height();  
                    isRVP = true;    
                    // Alternate view?                 
                    if($('div#recentlyViewedContainerId ul.standard_list').length > 0){
                        var ul = $('div#recentlyViewedContainerId ul.standard_list');
                        myBd.append(ul);                        
                    }
                    if(myBd.find('span.bl, span.br').length == 0){
                        myBd.append('<span class="corner bl"></span><span class="corner br"></span>');
                    }
                }
                else{
                    var myHd = el.find('div.hd');
                    var myBd = el.find('div.bd'); 
                    var myCta = el.find('h4.cta a');
                    myBdHeight = myBd.height();                    
                }
 
				var next = $(this).next();
                if(next.length == 0) return true;
                
                if(next.find('#recentlyViewedProductsHolder').length > 0){
                    var nextHd = next.find('div.pp_tsr_header_medium, div.tsr_container_small h2');
                    var nextBd = next.find('div.pp_tsr_medium_container, div.tsr_container_small'); 
                    var nextCta = next.find('ul a');   
                    nextBdHeight = nextBd.height() - nextHd.height(); 
                    isNextRVP = true; 
                    // Alternate view?                 
                    if($('div#recentlyViewedContainerId ul.standard_list').length > 0){
                        var ul = $('div#recentlyViewedContainerId ul.standard_list');
                        myBd.append(ul);                        
                    }
                    if(myBd.find('span.bl, span.br').length == 0){
                        myBd.append('<span class="corner bl"></span><span class="corner br"></span>');
                    }                                         
                }
                else{
                    var nextHd = next.find('div.hd');
                    var nextBd = next.find('div.bd'); 
                    var nextCta = next.find('h4.cta a');                   
                    nextBdHeight = nextBd.height();
                }

                if(parseInt(myHd.height()) > parseInt(nextHd.height())){
                    nextHd.css('height',myHd.height());    
                    myHd.css('height',myHd.height());
                }
                else{
                    myHd.css('height',nextHd.height());                    
                    nextHd.css('height',nextHd.height());
                }
                
                var maxHeight = Math.max(myBdHeight, nextBdHeight);

                if(isNextRVP){
                    var parentUl = nextBd.find('ul');
                    parentUl.height(parentUl.get(0).offsetHeight).css('padding-top',0).css('padding-bottom',0);                    
                    $('#recentlyViewedContainerId').css('height',
                        maxHeight - parentUl.height() + parseInt(myBd.css('padding-bottom'),10));                                                
                }
                else{
                    nextBd.css('height',maxHeight);                        
                }
                
                if(isRVP){
                    var parentUl = myBd.find('ul');
                    parentUl.height(parentUl.get(0).offsetHeight).css('padding-top',0).css('padding-bottom',0);
                    $('#recentlyViewedContainerId').css('height',
                        maxHeight - parentUl.height() + parseInt(nextBd.css('padding-bottom'),10));    
                }
                else{
                    myBd.css('height',maxHeight);                                                                   
                }  
                
                if(MOLECULAR.browser.ie6){
                    nextBd.find('span.corner').css('bottom','-1px');
                    myBd.find('span.corner').css('bottom', '-1px');
                }                             

                if(myCta.text().length > 0){
                    myCta.css({ position : 'absolute', bottom : '10px' });                    
                }
                else{
                    myCta.css('display','none');
                }
                
                if(nextCta.text().length > 0){
                    nextCta.css({ position : 'absolute', bottom : '10px' });                    
                }
                else{
                    nextCta.css('display','none');
                }
            });
        },
        // Preloads all images linked from root tag
        preload : function(tag){
            if(! preloads){
                preloads = $('a','#'+tag); 
                body = $('body:eq(0)');   
            }
            
            // Do a little preloading bit for the enlarged thumb view
            if(iteration < preloads.length){
                body.append('<img class="preload" src="'+preloads[iteration].href+'"/>'); 
                iteration++;              
            } 
            else{
                clearInterval(intvl);
            }           
            
            intvl = setInterval(function(){                
                MOLECULAR.ProductPage.preload();  
            },1000);  
        },
        // Lock Elements of the Overview page into place
        init_overview : function(){
            if(! MOLECULAR.browser.ie6){
                setTimeout(function(){
                    var hero = $('#overview_hero'); 
                    //hero.height(hero.height() - parseInt(hero.css('padding-bottom')));
                    //$('#picker_container, #features_overview').css({
                     //   position : 'absolute',
                     //   bottom : '0'   
                    //});              
                    // Force Opera to leave the features overview on the left side of the page
                    if($.browser.opera && MOLECULAR.direction) {
                        $('#features_overview').css('left','15px');
                    }                      
                },300); 
				               
            }  
			if(MOLECULAR.browser.ie6){
                setTimeout(function(){
                    var hero = $('#overview_hero'); 
                    hero.height(hero.height() + parseInt(hero.css('padding-bottom')));
					
                                        
                },300);                  
            }            
        },
        // Set up the features page navigation
        init_features : function(){
            var o = this;
            var menu = $('#features_nav_list');
            if(menu.length == 0) return false;
            var menuItems = $('div.menu','#product_container'); 
            menuItems.each(function(index){
                var mEl = $(this);
                var pId = mEl.parent().attr('id');
                var name = pId.substr(0, pId.indexOf('_container'));
                if(index == 0){
                    menu.append('<li class="first active"><a href="javascript:void(0)" rel="' + name +'">' + mEl.html() + '</a></li>');    
                }
                else if(index == menuItems.length - 1){
                    menu.append('<li class="last"><a href="javascript:void(0)" rel="' + name +'">' + mEl.html() + '</a></li>');                        
                }
                else{
                    menu.append('<li><a href="javascript:void(0)" rel="' + name +'">' + mEl.html() + '</a></li>');                        
                }
                mEl.remove();
            });   
            $('a','#features_nav_list').click( function(){
                o.swapFeature(this);
            });
            
            var anchorIndex = window.location.href.indexOf('#');
            var paramIndex = window.location.href.indexOf('currentFeature=');

            if(anchorIndex > 0 || paramIndex > 0){
                var aHash = '';
                if(paramIndex > 0){
                    var match = window.location.href.match(/[\\?&]currentFeature=([^&#]*)/);
                    if(match.length > 1){
                        aHash = match[1];
                    }                                        
                }
                else if(anchorIndex > 0){
                    aHash = window.location.href.substr(window.location.href.indexOf('#') + 1);                    
                }

                var linkEl = $('a[rel='+aHash+']','#features_nav_list');
                
                if(linkEl.length > 0){
                    o.swapFeature(linkEl[0]);                   
                }
                else{
                    o.swapFeature($('a','#features_nav_list')[0]);
                }
            }   
            else{
                o.swapFeature($('a','#features_nav_list')[0]);
            }   
            MOLECULAR.ProductPage.flyout.init_features();               
        },
        swapFeature : function(el){
            var target_subnav = $(el).parent().parent().find('li.active').removeClass('active').end().end().addClass('active').end().attr('rel');
            if (target_subnav == 'blank'){
                return;          
            }                
            $('div.f_content','#content_target').html($('#' + target_subnav + '_container').html());

            var bgImage = $('#' + target_subnav + '_container div.hidden[style]');

            if(bgImage.length > 0 && bgImage.css('backgroundImage') != 'none'){
                if(MOLECULAR.browser.ie6) {
                    var newSrc = bgImage.css('backgroundImage').replace(/url\(["']?/i,'').replace(/["']?\)$/,'');                    
                    var phoneBg = $('div.f_phone').get(0);
                    
                    if(! phoneBg.getAttribute('originalFilter')){
                        phoneBg.setAttribute('originalFilter',
                            $(phoneBg).css('backgroundImage').replace(/url\(["']?/i,'').replace(/["']?\)$/,''));
                    }                    
                    
                    phoneBg.style.filter = 
                        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + newSrc + "', sizingMethod='image')";
                    phoneBg.style.backgroundImage = 'none';                    
                }
                else{
                    $('div.f_phone').css('backgroundImage', bgImage.css('backgroundImage'));                    
                }
            }
            else{
                if(MOLECULAR.browser.ie6){
                    var phoneBg = $('div.f_phone').get(0);
                    var newSrc = phoneBg.getAttribute('originalFilter') || phoneBg.css('backgroundImage').replace(/url\(["']?/i,'').replace(/["']?\)$/,'');                    
                    phoneBg.style.filter = 
                        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + phoneBg.getAttribute('originalFilter') + "', sizingMethod='image')";                   
                    phoneBg.style.backgroundImage = 'none';
                    if(! phoneBg.getAttribute('originalFilter')){
                        phoneBg.setAttribute('originalFilter',newSrc);
                    }
                }
                else{
                    $('div.f_phone').removeAttr('style');                    
                }
            }

            this.setHash(el.rel);          
        },
		init_mini_gallery : function(){	       
            if(MOLECULAR.browser.ie6){
                $('ul#product_shots li').bind('click',function(){
                    $(this).parent().find('li.selected').removeClass('selected').end().end().addClass('selected');
                })    
            }
            else{
                if($('ul#color_picker').length == 0){
                    $('ul#product_shots').addClass('no_picker');
                }                 
				$('div#picker_container ul#product_dn_arr, div#picker_container ul#color_picker, div#picker_container ul#product_shots').bind('click',function(e){
    				e.preventDefault();
                    if ($('div#picker_container').hasClass('off')) {
    			    	$('div#picker_container').parent().find('div.off').removeClass('off').end().end().addClass('on').end().end();
        			}
        			return;
    			});
    			
    			$('div#picker_container .close a').bind('click',function(e){
                    e.preventDefault();
    				if ($('div#picker_container').hasClass('on')) {
    				    $('div#picker_container').parent().find('div.on').removeClass('on').end().end().addClass('off').end().end();
    			    }
        			return
    			});                
            }			
		},
        setHash : function(newHash){
            var h = window.location.href;
            if(h.indexOf('#') > 0){
                window.location.href = h.substr(0,h.indexOf('#')) + '#' + newHash;                
            }   
            else{
                window.location.href += '#' + newHash;
            } 
        },
        /*** 
         * Code to initialize carousel as scroll amount must be independent of page
         * @param {HTMLElement|jQuery} el Element we'd like to make a carousel
         */
        init_carousel : function(el){
            el = $(el);

            if(el.hasClass('carousel_2items')){
                this._buildCarousel(el,2);                
            }
            else if(el.hasClass('carousel_3items')){
                this._buildCarousel(el,3);                
            }
            else if(el.hasClass('carousel_4items')){
                this._buildCarousel(el,4);                
            }
            else{    // Default: Scroll a single item
                this._buildCarousel(el,1);                
            }
        },	
        /***
         * Wraps call to jCarousel. Also handles RTL carousel item shift.
         * @param {jQuery} el Element we'd like to make a carousel
         * @param {Number} scrollAmount Number of positions we'd like the carousel to scroll on each click.
         */		   
        _buildCarousel : function(el,scrollAmount){
            var cLength = el.children('li').length;
            var startItem = MOLECULAR.direction ? cLength : 1;

            // IE6 will hang if we try to set a number of visible items to more than the
            // actual number of items in the carousel itself.
            if(scrollAmount > cLength) scrollAmount = cLength;           
            el.jcarousel({ scroll : scrollAmount, start : startItem, visible : scrollAmount });    

            if(MOLECULAR.isIE6Gallery){
                el.width(el.width() + 10);                    
            }

            if(cLength <= scrollAmount){
                el.parents('.jcarousel-container').find('.jcarousel-prev, .jcarousel-next').hide();
                // Reset the width of list-items to their natural amount.
                if(! MOLECULAR.browser.ie6){
                    setTimeout(function(){                     
                        el.children('li').each(function(){
                            this.style.width = '';
                        });
                    },250);                     
                }
            } 
        }
    }
}();

/***
 * Simple accordion function.
 * Expects the markup structure found in ul#product_accordion.
 * 
 * To use: pass the ID of the parent UL into accordion's init function. It will do the rest.
 */
MOLECULAR.ProductPage.accordion = function(){
    var parentEl = "";
    var initialHeight = null;
    var parentHeight = null;
    
    return{
        open : function(li){
            var openHeight = li.find('div.bd div.container')[0].offsetHeight;
            
            this.close(parentEl.find('li.open'));  
            if(initialHeight && openHeight > initialHeight){
                var hero = $('#overview_hero');
                parentHeight = hero.height();
                $('#overview_hero').height(hero.height() + (openHeight - initialHeight));    
            }
            else if(parentHeight){
                $('#overview_hero').height(parentHeight);               
            }   

            li.find('div.bd').animate({
                height : openHeight
            },250).end().addClass('open'); 
            
            if($.browser.opera) {
                // Force Opera to redraw
                document.body.style += '';
            }
            
            if(! initialHeight){
                setTimeout(function(){
                    initialHeight = openHeight;
                },260);
            }
        },
        close : function(li){
            li.find('div.bd').animate({
                height : 0
            },250).end().removeClass('open');
        },
        handleClick : function(li){
            var el = $(li);
            if(el.hasClass('open')){
                return true;
            }
            else{
                this.open(el);
            }
        },
        init : function(parent){
            var o = this;
            parentEl = $('#'+parent);
            if(! parentEl.hasClass('accordion__')){
                $('li',parentEl[0]).bind('click',function(){
                    o.handleClick(this);
                }).filter(':eq(0)').click();
                parentEl.addClass('accordion__');                
            }

        }        
    }
}();

/***
 * Flyouts and rollovers for various buttons, icons, and other elements.
 * 
 * Expects a markup structure like
 * a.button + div > div.flyout_content
 * or
 * dl.flyout > dd + dt
 */
MOLECULAR.ProductPage.flyout = function(){
    var flyoutHtml = '<div id="{id}" class="flyout"><div class="hd"><span class="corner top"></span><span class="corner tl"></span><span class="corner tr"></span></div>';                                                
        flyoutHtml += '<div class="bd"><span class="corner left side"></span><span class="corner right side"></span><a href="#" class="close"></a></div>';            
        flyoutHtml += '<div class="ft"><span class="corner br"></span><span class="corner bl"></span><span class="corner btm"></span></div></div>';
    var offRegex = /\s(.*_button)\s?/;
    var onRegex = /\s(.*_button_on)\s?/;
    
    return{
        getClass : function(className){
            var buttonClass = className.match(offRegex);   
            
            if(buttonClass != null){
                return buttonClass[1] + '_on';
            }
            else{
                return '';
            }
        },
        getOnClass : function(className){
            var buttonClass = className.match(onRegex);        
            if(buttonClass != null){
                return buttonClass[1];
            }
            else{
                return '';
            }            
        },
        turnOn : function(el){
            var buttonClass = this.getClass(el.className);
            if(buttonClass){
                $(el).addClass(buttonClass).addClass('button_on');
            }  
            else{
                setTimeout(function(){
                    $(el).addClass('button_on');                        
                },10);
            }         
            
            if(MOLECULAR.browser.ie7 || MOLECULAR.browser.ie6){
                var parentEl = $(el);                
                parentEl.find('.corner').each(function(){
                    var c = $(this);
                    if(c.css('height') == '100%' || c.css('height') == 'auto'){
                        c.css('height',parentEl.height());                            
                    }
                });
            }  
            return this; 
        },
        turnOff : function(el){
            var buttonClass = this.getOnClass(el.className);
            
            if(buttonClass){
                $(el).removeClass(buttonClass).addClass(buttonClass.substr(0,buttonClass.indexOf('_on'))).removeClass('button_on');
            }   
            else{
                $(el).removeClass('button_on');
            }  
            return this;           
        },
        // Generate unique IDs for our flyouts so that we can track them a bit better.
        getId : function(){
            return 'flyout_' + parseInt(Math.random() * 1000000);    
        },
        hideAll : function(curEl){
            var o = this;
                    
            $('div.flyout:visible').hide();
            $('a.button_on','#product_container').each(function(){
                if(this !== curEl) o.turnOff(this);    
            });  
            return this;          
        },
        init_features : function(){
            var o = this;
            
            $('a','#features_nav_list').hoverIntent({
                over : function(){
                    var el = $(this);

                    // Don't hover on active tab...
                    if(el.parent().hasClass('active')){
                        return true;
                    }

                    var oEl = this;
                    o.hideAll();

                    /* Set "_on" class for this button */
                    o.turnOn(this);

                    if(el.attr('data-flyoutid')){
                        $('#' + $(this).attr('data-flyoutid')).show(); 
                    }
                    else{
                        var pos = el.offset();
                        var flyout = el.find('div.flyout_content');
                        var content = flyout.html();    // Will be null if there's no flyout element 
                    
                        if(content){
                            // Generate and place a unique ID for our flyout...
                            var flyoutId = o.getId();
                            el.attr('data-flyoutid',flyoutId);
                            $('body').append(flyoutHtml.replace('{id}',flyoutId));

                            var bd = $('#' + flyoutId + ' div.bd').parent().addClass('flyout__ features_icon_flyout features_icon_flyout__').end();
                            bd.find('span.left').before(content).end().parent().css({visibility : 'hidden'});

                            // Ensure that we are setting a proper width so that 
                            // long feature names are not broken
                            if(! MOLECULAR.browser.ie6){
                                var width = bd.get(0).offsetWidth;
                                if(MOLECULAR.browser.ie6 || (MOLECULAR.browser.ie7 && MOLECULAR.direction)){
                                    bd.css('float','left');
                                    width = bd.get(0).offsetWidth;
                                    bd.css('float','none');
                                }
                                if(width > 150){    // 150px -> 120px standard width + 30px padding
                                    bd.addClass('feature_flyout_sized');    
                                }                                
                            }
                            else{                      
                                bd.width('1%');  // Fall back on the old IE6 1% width hack
                            }
                            
                            var topCoord = pos.top - bd[0].offsetHeight / 2;   
                            
                            // Adjust the header and footers for IE7
                            if(MOLECULAR.browser.ie7){
                                if(MOLECULAR.direction){
                                    bd.css('float','left');
                                }
                                bd.width(bd.width()).parent()
                                    .width(bd.get(0).offsetWidth + parseInt(bd.css('margin-left')) + parseInt(bd.css('margin-right')));
                                if(MOLECULAR.direction){
                                    bd.css('float','none');
                                }
                            }

                            if(MOLECULAR.direction){
                                var leftCoord = pos.left - el.width() - bd.width() - bd.find('span.right').width();                                
                            }
                            else{
                                var leftCoord = pos.left + el.width()/2 + 5;                                
                            }
                            
                            bd.parent().css({
                                top : topCoord,
                                left : leftCoord,
                                visibility : 'visible'   
                            });        
                        }                        
                    }  
                },
                out : function(e){
                    var el = $(this);
                          
                    // If we accidentally mouse onto the flyout layer, ignore it
                    if(e.relatedTarget.className.indexOf('flyout') > -1){
                        // Add a mouseout to this particular item to be sure we can close it

                        $('#' + el.attr('data-flyoutid')).bind('mouseleave',function(e){
                            if($(e.relatedTarget).parents('#features_nav_list').length == 0){
                                $(this).hide();    
                            }
                        });
                        return false;
                    }
                    $('#' + el.attr('data-flyoutid')).hide();
                },
                timeout : 250
            }).bind('click',function(){
                $('#' + $(this).attr('data-flyoutid')).hide();                
            });  
        },
        init : function(){
            var o = this;
            $('a.button:not(.link), div.button.top_button:not(.link)').each(function(){
                var linkEl = $(this);
                if(linkEl.attr('id') == 'button_compare'){
                    o.init_compare(linkEl);
                    return true;
                }
                var eventType = linkEl.hasClass('hover') ? 'mouseenter' : 'click';
                
                linkEl.find('a').bind('click',function(e){ 
                    linkEl.click();
                    e.preventDefault();
                    return false; 
                })
        
                $(this).bind(eventType, function(e){
                    e.preventDefault();
                    var el = $(this);                    
                    o.hideAll(this);
                    
                    if(el.hasClass('button_on')){
                        /* Remove button's "_on" class */
                        o.turnOff(this);
                        if(linkEl.attr('id') == 'button_compare'){                
                            hideCompareTray();
                        }                        
                    }
                    else{                                                        
                        /* Set "_on" class for this button */
                        o.turnOn(this);

                        if($(this).attr('data-flyoutid')){
                            $('#' + $(this).attr('data-flyoutid')).show(); 
                        }
                        else{
                            var flyout = el.next().find('div.flyout_content');
                            if((MOLECULAR.browser.ie6 || (el.hasClass('top_button') && MOLECULAR.browser.ie7)) 
                                && MOLECULAR.direction){
                                flyout.css({'visibility':'hidden', 'position' : 'absolute'})
                                    .parent().css({'visibility' : 'visible', 'display' : 'block'});
                                if(MOLECULAR.browser.ie7){
                                    flyout.css('float','left')
                                }
                                var foOffset = flyout.parent().width();
                                flyout.css({'float' : 'none','display' : 'none'});
                            }
                            var content = flyout.html();    // Will be null if there's no flyout element 

                            // On the Overview page, the PAN application flyout is shared, so 
                            // if we are on that page and content is null, fetch the flyout from elsewhere.
                            // We will also store this as a flag in reusePAN.
                            var reusePAN = $('#product_container').hasClass('overview') && ! content;                         
                            if(reusePAN){
                                content = $('#when_button').next().find('div.flyout_content').html();        
                            }

                            var constrained = flyout.hasClass('constrained');
                            var top = ! (flyout.hasClass('no_top'));
                            var align = flyout.hasClass('right') || reusePAN ? 'right' : 'left';
                            var orient = flyout.hasClass('vertical_align');
                            var icon = flyout.hasClass('icon');
                        
                            if(content){                                
                                var pos = el.offset();                             
                                // Generate and place a unique ID for our flyout...
                                var flyoutId = o.getId();
                                el.attr('data-flyoutid',flyoutId);
                                $('body').append(flyoutHtml.replace('{id}',flyoutId));
    
                                var bd = $('#' + flyoutId + ' div.bd');
                                var parentEl = bd.parent(); 
                                
                                // Set appropriate classNames as we're now moving directly below the body tag...
                                var classes = parentEl[0].className.split(' ');
                                for(var i = 0; i < classes.length; i++){                                    
                                    parentEl.addClass(classes[i] + '__')
                                }
                                                                                                
                                bd.find('span.left').before(content).end().end().each(function(){
                                    if(constrained){
                                        var totalWidth = el[0].offsetWidth - parseInt(bd.css('padding-left'),10) - parseInt(bd.css('padding-right'),10);
                                        bd.css('width',totalWidth);
                                    }
                                    
                                    if(! top){
                                        $('#' + flyoutId + ' div.hd').remove();
                                    }                                 
                                }).css({visibility : 'visible'});
                                if(! reusePAN) flyout.empty();    // Remove duplicated content so we don't wind up with duplicate IDs

                                if(icon){
                                    parentEl.addClass('flyout_icon flyout_icon__');                                   
                                    if(! MOLECULAR.browser.ie6){
                                        var width = bd.get(0).offsetWidth;
                                        if(MOLECULAR.browser.ie6 || (MOLECULAR.browser.ie7 && MOLECULAR.direction)){
                                            bd.css('float','left');
                                            width = bd.get(0).offsetWidth;
                                            bd.css('float','none');
                                        }
                                        if(width > 150){    // 150px -> 120px standard width + 30px padding
                                            bd.addClass('feature_flyout_sized');    
                                        }                                
                                    }
                                    else{
                                        bd.width('1%');  // Fall back on the old IE6 1% width hack
                                    }
                                                                        
                                    // Adjust the header and footers for IE7
                                    if(MOLECULAR.browser.ie7){
                                        if(MOLECULAR.direction){
                                            bd.css('float','left');
                                        }
                                        bd.width(bd.width()).parent()
                                            .width(bd.get(0).offsetWidth + parseInt(bd.css('margin-left')) + parseInt(bd.css('margin-right')));
                                        if(MOLECULAR.direction){
                                            bd.css('float','none');
                                        }
                                    }                            
                                }
                                if(reusePAN){
                                    parentEl.addClass('flyout__ gradient_flyout gradient_flyout__');
                                }

                                // If we haven't already constrained the width...                                
                                if(MOLECULAR.browser.ie6 || (MOLECULAR.direction && MOLECULAR.browser.ie7)){ 
                                    bd.css('float','left').css('direction','ltr');

                                    if(MOLECULAR.browser.ie6 && reusePAN){
                                        var forms = bd.find('form');
                                        forms.css('float','left').find('.clearfix').removeClass('clearfix').addClass('wasClearfix');                                        
                                    }
                                    if(typeof foOffset === 'number'){
                                        foOffset = Math.min(foOffset, bd.width());
                                        bd.width(foOffset);
                                    }
                                    else{
                                        bd.width(bd.width());                                        
                                    }                                    

                                    bd.css('float','none'); 
                                    
                                    if(MOLECULAR.browser.ie6 && reusePAN){
                                        forms.css('float','none').find('.wasClearfix').removeClass('wasClearfix').addClass('clearfix');                                          
                                    }  

                                }
                                else if(! constrained && ! orient){
                                    var bdWidth = bd.width();
                                    bd.prev().width(bdWidth + parseInt(bd.css('padding-left'))).end().width(bdWidth);    // Fix div.bd's width
                                }
                               
                                var leftCoord = bd.find('span.left').width() * -1;

                                if(align == 'right' && ! MOLECULAR.direction){
                                    var pad = parseInt(bd.css('padding-left'));
                                    leftCoord = pos.left + el.width() - (bd[0].offsetWidth + pad) - bd.find('span.left').width() + bd.prev().find('span.tr').width();

                                    // The top, PAN application button likes to get a couple pixels off...
                                    if(reusePAN){
                                        leftCoord += bd.prev().find('span.tr').width() / 2;     
                                    } 
                                    else if(el.attr('id') === 'button_when'){  
                                        leftCoord -= bd.find('span.right').width() / 2;    
                                    } 

                                    if(MOLECULAR.browser.ie6){
                                        leftCoord += 15;
                                    }
                                } 
                                else if(constrained){
                                    leftCoord = pos.left - parseInt(bd.css('margin-left'));
                                }
                                else if(orient){
                                    leftCoord = pos.left + 10;
                                }
                                else{
                                    leftCoord = pos.left - el.width() - 2 * bd.find('span.left').width();
                                    if(MOLECULAR.direction && align == 'right'){
                                        if(MOLECULAR.browser.ie6){
                                            leftCoord = leftCoord - parseInt(bd.css('padding-left'),10);                                            
                                        }
                                        else if(MOLECULAR.browser.ie7){
                                            if(el.hasClass('top_button') && MOLECULAR.direction){
                                                leftCoord = leftCoord - bd.find('span.left').width();                                        
                                            }   
                                            else{
                                                leftCoord = leftCoord + 2 * bd.find('span.left').width();                                                                                                                                    
                                            }  
                                        }  
                                        else{       
                                            if(el.hasClass('top_button') && MOLECULAR.direction){
                                                leftCoord = leftCoord + bd.find('span.left').width();                                                                                                                                    
                                            }   
                                            else{
                                                leftCoord = leftCoord + 2 * bd.find('span.left').width();                                                                                                                                    
                                            }                                 
                                        } 
                                    }
                                    else if(MOLECULAR.direction){
                                        // We'll also need to nudge these over a bit by the left corner width
                                        leftCoord = leftCoord - bd.prev().find('span.tl').width();
                                    }
                                }
                                
                                var topCoord = pos.top + el.height()

                                if(icon){
                                    topCoord = topCoord - 9;    // 9 -> the "top" height for these icons - 7px of overhand for the "on" state of the icon 
                                    if(MOLECULAR.browser.ie6 && ! (MOLECULAR.direction && align == 'right')){
                                        topCoord -= 15;
                                    }
                                    else if(MOLECULAR.browser.ie6 && MOLECULAR.direction && align == 'right'){
                                        topCoord -= 10;
                                    }
                                }
                                else if(orient){
                                    topCoord = topCoord - (bd[0].offsetHeight / 2);
                                }  
                                else if(MOLECULAR.browser.ie6 && constrained){
                                    topCoord += 5;
                                }                               
                                else if(MOLECULAR.browser.ie6){
                                    topCoord -= bd.prev().height() / 2;
                                }                        
                                
                                parentEl.css({
                                    top : topCoord,
                                    left : leftCoord,
                                    visibility : 'visible'
                                }).addClass(flyout.hasClass('gradient') ? 'gradient_flyout gradient_flyout__' : '');                                      
                                 
                                // Wire up "Close" X actions
                                bd.find('a.close').bind('click', function(e){
                                    e.preventDefault();
                                    o.hideAll().turnOff(el[0]);    
                                });
                                                            
                                // Reset AddThis
                                if(bd.find('.addthis_toolbox').length > 0){
                                    addthis.ost = 0;
                                    addthis.ready();
                                }  
                                
                                // Remove alt text from Overview features icons
                                if(el.find('img').hasClass('feature_icon')){
                                    el.attr('title','');
                                } 
                                
                                // Fix up the IEs' display problems
                                if(MOLECULAR.browser.ie7){
                                    el.find('.corner').height(el.height());
                                    bd.nextAll('div.ft').width(bd.width() + parseInt(bd.css('padding-left'),10));
                                    if(icon){
                                        if(bd.find('span.side:eq(0)').height() > bd.height()){
                                            bd.find('span.side').height(bd.height());
                                        }
                                    }
                                }   
                                
                                if(MOLECULAR.direction && MOLECULAR.browser.ie7){
                                    bd.prevAll('div.hd').width(bd.width() + parseInt(bd.css('padding-left'),10));
                                }                                                                               
                            }                        
                        }                        
                    }
                });                            
            
                if(linkEl.hasClass('hover')){
                    linkEl.bind('mouseleave',function(e){
                        var mouseEl = $(e.relatedTarget);
                        if(mouseEl.hasClass('flyout') || mouseEl.parents('div.flyout').length > 0){
                            mouseEl.parents('div.flyout').bind('mouseleave',function(){
                                linkEl.removeClass('button_on');
                                $(this).hide();    
                            });
                            return true;    
                        }
                        linkEl.removeClass('button_on');
                        $('#'+linkEl.attr('data-flyoutid')).hide();    
                    });
                }
                
                if(MOLECULAR.browser.ie7){
                    $(this).find('.corner').height($(this).height());
                }
            });
            
            // Turn off behaviors on the compare button, which won't be matched above
            $('#button_compare.link #ppCompareTrayLink a').each(function(){
                // Find the link element and remove its mouseover - Trac #259
                this.onmouseover = function(){ return true; }; 
            });            
        },
        init_compare : function(btn){
            var o = this;
            o.intvl = null;
            
            var eventType = btn.hasClass('hover') ? 'mouseenter' : 'click';
            
            btn.find('a').bind('click',function(e){ 
                btn.click();
                e.preventDefault();
                e.stopPropagation();
                return false; 
            }).unbind('mouseover').each(function(){
                // Make sure the FnC tray is configured properly
                $(this).removeAttr('onmouseover').get(0).onmouseover = function(){ return true; };
            });
            $('body').append($('#ppCompareTrayLink').clone().hide());
            $('#ppproductNavi span#ppCompareTrayLink').attr('id','ppCompareTrayLink_MOLECULAR');

            if(typeof ppTrayHandler === 'undefined'){
                ppTrayHandler = function(){};
            }
            else{
                ppTrayHandler();
            }

            $(btn).bind(eventType, function(e){
                // Make sure the FnC tray is configured properly
                var linkEl = btn.find('a').get(0);
                if(linkEl) linkEl.onmouseover = function(){ return true; };
                
                e.preventDefault();
                var el = $(this);
                var oEl = this;                    
                o.hideAll(this);

                window.ppTrayHandler = function(){ 
                    var trayElement = document.getElementById("tray"); 
    
                    if (trayElement.style.display == "none"){ 
                        trayElement.style.display = "block"; 
                        document.getElementById("ppCompareTrayLink").className = "compareLinkActive"; 
                    } 
                    else { 
                        trayElement.style.display = "none"; 
                        document.getElementById("ppCompareTrayLink").className = "compareLink"; 
                        try { 
                            if (document.all && document.getElementById("buyNowModule")) { showRegBnElement(); } 
                        } 
                        catch (Exception) { } 
                    }      
                    showCompareTray();                      
                }   

                ppTrayHandler();                                            
                
                if(o.intvl){
                    clearInterval(o.intvl);
                }
                else{
                    // Setting an interval to monitor when these items are loaded.
                    o.intvl = setInterval(function(){
                        window.ppTrayHandler = function(){ 
                            return true;
                        } 
                        // From ppTrayHandler...
                        var trayElement = document.getElementById("tray"); 
                        if(trayElement){
                            trayElement.style.display = "block"; 
                            var compareLink = document.getElementById("ppCompareTrayLink");
                            compareLink.className = "compareLinkActive"; 
                            compareLink.onmouseover = function(){};
                            showCompareTray(); 
                            
                            var trayItems = $('.ppCompareTraySingleItem','#ppCompareTrayItemHolderR6');

                            if(trayItems.length == 0){
                                if(! $('#ppCompareTrayItemHolderR6').hasClass('has_item')){
                                    $('#ppCompareTrayItemHolderR6').addClass('no_product');     
                                }                                 
        
                                // Initial link configuration...
                                $('div.pp_compare_button_remove','#ppCompareTrayLinksId').addClass('hidden');
								  $('div.pp_compare_button_add','#ppCompareTrayLinksId').one('click',function(){
                                    $('div.pp_compare_button_remove','#ppCompareTrayLinksId').removeClass('hidden');
                                   // $('#ppCompareTrayItemHolderR6').removeClass('has_item');   
                                }).removeClass('hidden');                            
                            }                        
                            else{
                                $('#ppCompareTrayItemHolderR6').removeClass('no_product').addClass('has_item'); 
            
                                // Initial link configuration...
								$('div.pp_compare_button_remove','#ppCompareTrayLinksId').one('click',function(){
                                    $('div.pp_compare_button_add','#ppCompareTrayLinksId').removeClass('hidden');
                                   // $('#ppCompareTrayItemHolderR6').removeClass('has_item');   
                                }).removeClass('hidden');                                    
                            }     
                            if(trayItems.length < 4){
                                $('#trayCounterNotification, #trayIsFullNotification').hide();
                            }                                  
                        } 
                    },150);                    
                }
                                                
                setTimeout(function(){
                    // We've worked in ppTrayHandler functionality throughout this function...
                    var trayElement = document.getElementById("tray"); 

                    window.ppTrayHandler = function(){ 
                        return true;
                    }
                    
                    if(el.hasClass('button_on')){
                        /* Remove button's "_on" class */
                        o.turnOff(oEl);

                        // From ppTrayHandler...
                        trayElement.style.display = "none"; 
                        document.getElementById("ppCompareTrayLink").className = "compareLink"; 
                        try { 
                            if (document.all && document.getElementById("buyNowModule")) { showRegBnElement(); } 
                        } 
                        catch (Exception) { } 
                        if(btn.attr('id') == 'button_compare'){                
                            hideCompareTray();
                        } 
                        setTimeout(function(){
                            clearInterval(o.intvl);  
                        },150);
                        o.intvl = null;  
                    }
                    else{   
                        // From ppTrayHandler...                      
                        trayElement.style.display = "block"; 
                        document.getElementById("ppCompareTrayLink").className = "compareLinkActive"; 
                        //showCompareTray();
                                                                                               
                        /* Set "_on" class for this button */
                        o.turnOn(oEl);
    
                        if($(oEl).attr('data-flyoutid')){
                            if($('#tray').css('display') == 'none'){                                
                               ppTrayHandler();
                               setTimeout(function(){
                                   $('#' + $(oEl).attr('data-flyoutid')).show();
                               },100); 
                            }
                            else{
                                $('#' + $(oEl).attr('data-flyoutid')).show();     
                            }                            
                        }
                        else{
                            var flyout = el.next().find('div.flyout_content');
                            var content = flyout.html();    // Will be null if there's no flyout element 
    
                            // On the Overview page, the PAN application flyout is shared, so 
                            // if we are on that page and content is null, fetch the flyout from elsewhere.
                            // We will also store this as a flag in reusePAN.
                            var reusePAN = $('#product_container').hasClass('overview') && ! content;                         
                            if(reusePAN){
                                content = $('#when_button').next().find('div.flyout_content').html();        
                            }
    
                            var constrained = flyout.hasClass('constrained');
                            var top = ! (flyout.hasClass('no_top'));
                            var align = flyout.hasClass('right') || reusePAN ? 'right' : 'left';
                            var orient = flyout.hasClass('vertical_align');
                            var icon = flyout.hasClass('icon');
                        
                            if(content){                                
                                var pos = el.offset();                             
                                // Generate and place a unique ID for our flyout...
                                var flyoutId = o.getId();
                                el.attr('data-flyoutid',flyoutId);
                                $('body').append(flyoutHtml.replace('{id}',flyoutId));
    
                                var bd = $('#' + flyoutId + ' div.bd');
                                var parentEl = bd.parent().bind('mouseover',ppTrayHandler); 
                                
                                // Set appropriate classNames as we're now moving directly below the body tag...
                                var classes = parentEl[0].className.split(' ');
                                for(var i = 0; i < classes.length; i++){                                    
                                    parentEl.addClass(classes[i] + '__')
                                }
                                                                                                
                                bd.find('span.left').before(content).end().end().each(function(){
                                    if(constrained){
                                        var totalWidth = el[0].offsetWidth - parseInt(bd.css('padding-left'),10) - parseInt(bd.css('padding-right'),10);
                                        bd.css('width',totalWidth);
                                    }
                                    
                                    if(! top){
                                        $('#' + flyoutId + ' div.hd').remove();
                                    }                                 
                                }).css({visibility : 'visible'});
                                if(! reusePAN) flyout.empty();    // Remove duplicated content so we don't wind up with duplicate IDs
    
                                if(icon){
                                    parentEl.addClass('flyout_icon flyout_icon__');                                   
                                    if(! MOLECULAR.browser.ie6){
                                        var width = bd.get(0).offsetWidth;
                                        if(MOLECULAR.browser.ie6 || (MOLECULAR.browser.ie7 && MOLECULAR.direction)){
                                            bd.css('float','left');
                                            width = bd.get(0).offsetWidth;
                                            bd.css('float','none');
                                        }
                                        if(width > 150){    // 150px -> 120px standard width + 30px padding
                                            bd.addClass('feature_flyout_sized');    
                                        }                                
                                    }
                                    else{
                                        bd.width('1%');  // Fall back on the old IE6 1% width hack
                                    }
                                                                        
                                    // Adjust the header and footers for IE7
                                    if(MOLECULAR.browser.ie7){
                                        if(MOLECULAR.direction){
                                            bd.css('float','left');
                                        }
                                        bd.width(bd.width()).parent()
                                            .width(bd.get(0).offsetWidth + parseInt(bd.css('margin-left')) + parseInt(bd.css('margin-right')));
                                        if(MOLECULAR.direction){
                                            bd.css('float','none');
                                        }
                                    }                            
                                }
                                if(reusePAN){
                                    parentEl.addClass('flyout__ gradient_flyout gradient_flyout__');
                                }
    
                                // If we haven't already constrained the width...                                
                                if(MOLECULAR.browser.ie6 || (MOLECULAR.direction && MOLECULAR.browser.ie7)){ 
                                    bd.css('float','left');
                                    if(MOLECULAR.browser.ie6 && reusePAN){
                                        var forms = bd.find('form');
                                        forms.css('float','left').find('.clearfix').removeClass('clearfix').addClass('wasClearfix');                                        
                                    }
    
                                    bd.width(bd.width());
                                    bd.css('float','none'); 
                                    
                                    if(MOLECULAR.browser.ie6 && reusePAN){
                                        forms.css('float','none').find('.wasClearfix').removeClass('wasClearfix').addClass('clearfix');                                          
                                    }  
    
                                }
                                else if(! constrained && ! orient){
                                    var bdWidth = bd.width();
                                    bd.prev().width(bdWidth + parseInt(bd.css('padding-left'))).end().width(bdWidth);    // Fix div.bd's width
                                }
                               
                                var leftCoord = bd.find('span.left').width() * -1;
                                
                                if(align == 'right' && ! MOLECULAR.direction){
                                    var pad = parseInt(bd.css('padding-left'));
                                    leftCoord = pos.left + el.width() - (bd[0].offsetWidth + pad) - bd.find('span.left').width() + bd.prev().find('span.tr').width();
    
                                    // The top, PAN application button likes to get a couple pixels off...
                                    if(reusePAN){
                                        leftCoord += bd.prev().find('span.tr').width() / 2;     
                                    } 
                                    else if(el.attr('id') === 'button_when'){  
                                        leftCoord -= bd.find('span.right').width() / 2;    
                                    } 
    
                                    if(MOLECULAR.browser.ie6){
                                        leftCoord += 15;
                                    }
                                } 
                                else if(constrained){
                                    leftCoord = pos.left - parseInt(bd.css('margin-left'));
                                }
                                else if(orient){
                                    leftCoord = pos.left + 10;
                                }
                                else{
                                    leftCoord = pos.left - el.width() - 2 * bd.find('span.left').width();
                                    if(MOLECULAR.direction && align == 'right'){
                                        leftCoord = leftCoord + 2 * bd.find('span.left').width();
                                    }
                                    else if(MOLECULAR.direction){
                                        // We'll also need to nudge these over a bit by the left corner width
                                        leftCoord = leftCoord - bd.prev().find('span.tl').width();
                                    }
                                }
                                
                                var topCoord = pos.top + el.height()
                                if(icon){
                                    topCoord = topCoord - 9;    // 9 -> the "top" height for these icons - 7px of overhand for the "on" state of the icon 
                                    if(MOLECULAR.browser.ie6){
                                        topCoord -= 15;
                                    }
                                }
                                else if(orient){
                                    topCoord = topCoord - (bd[0].offsetHeight / 2);
                                }  
                                else if(MOLECULAR.browser.ie6 && constrained){
                                    topCoord += 5;
                                }       
                                else if(MOLECULAR.browser.ie6){
                                    topCoord -= bd.prev().height() / 2;
                                }                                  
    
                                parentEl.css({
                                    top : topCoord,
                                    left : leftCoord,
                                    visibility : 'visible'
                                }).addClass(flyout.hasClass('gradient') ? 'gradient_flyout gradient_flyout__' : '');                                      
                                 
                                // Wire up "Close" X actions
                                bd.find('a.close').bind('click', function(e){
                                    e.preventDefault();
                                    o.hideAll().turnOff(el[0]);  
                                    clearInterval(o.intvl); 
                                    o.intvl = null;
                                });
                                                            
                                // Reset AddThis
                                if(bd.find('.addthis_toolbox').length > 0){
                                    addthis.ost = 0;
                                    addthis.ready();
                                }  
                                
                                // Remove alt text from Overview features icons
                                if(el.find('img').hasClass('feature_icon')){
                                    el.attr('title','');
                                } 
                                
                                // Fix up the IEs' display problems
                                if(MOLECULAR.browser.ie7){
                                    el.find('.corner').height(el.height());
                                    bd.nextAll('div.ft').width(bd.width() + parseInt(bd.css('padding-left'),10));
                                    if(icon){
                                        if(bd.find('span.side:eq(0)').height() > bd.height()){
                                            bd.find('span.side').height(bd.height());
                                        }
                                    }
                                }   
                                
                                if(MOLECULAR.direction && MOLECULAR.browser.ie7){
                                    bd.prevAll('div.hd').width(bd.width() + parseInt(bd.css('padding-left'),10));
                                }                                                                               
                            }                        
                        }                        
                    }                    
                },250);
            });                            
        
            if(btn.hasClass('hover')){
                btn.bind('mouseleave',function(e){
                    var mouseEl = $(e.relatedTarget);
                    if(mouseEl.hasClass('flyout') || mouseEl.parents('div.flyout').length > 0){
                        mouseEl.parents('div.flyout').bind('mouseleave',function(){
                            btn.removeClass('button_on');
                            $(this).hide();    
                        });
                        return true;    
                    }
                    btn.removeClass('button_on');
                    $('#'+btn.attr('data-flyoutid')).hide();    
                });
            }
            
            if(MOLECULAR.browser.ie7){
                $(this).find('.corner').height($(this).height());
            }          
        }
    }
}();

/***
 * Image swapper utility for swapping hero product views.
 * 
 * To use: pass the ID of the picker UL and the thumbs UL we'll be swapping
 */
MOLECULAR.ProductPage.picker = function(){
    var loadEl = null, isSwapping = false;
    var fileReg = /[^\/]*$/;
    var count = 0;
    return {
        getSrc : function(currentColor,currentDirectory,src,color,newDirectory){
            var reg = new RegExp(currentColor,'ig');

            var fileName = src.match(fileReg);
            if(fileName){
                fileName = fileName[0];
                return newDirectory + fileName.replace(reg,color);
            }
            else{
                return src;
            }            
        },
        init : function(picker,thumbs){
            var picker = $('#'+picker);
            var o = this;
            
            picker.find('li').bind('click',function(e){     
                // Flag our state we do not wind up with extra rapid clicks
                if(o.isSwapping){ return false; }         
                else{ o.isSwapping = true; }
                e.preventDefault();              
                
                var selectedEl = $(this).parent().find('li.on');
                if(selectedEl === $(this)) return false;
                
                var previousColor = selectedEl.attr('data-swatch');
                var previousDirectory = selectedEl.attr('data-path');
                var color = this.getAttribute('data-swatch');
                var baseDirectory = this.getAttribute('data-path');
                picker.find('li').removeClass('on');
                $(this).addClass('on');
                
                $('#'+thumbs+' li').find('a').each(function(){                                      
                    this.href = o.getSrc(previousColor,previousDirectory,this.href,color,baseDirectory);

                    $(this).find('img').each(function(){
                        if(MOLECULAR.browser.ie6){
                            $(this).parent().get(0).style.filter = 
                                "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + o.getSrc(previousColor,previousDirectory,this.src,color,baseDirectory) + "', sizingMethod='scale')";
                        }
                        this.src = o.getSrc(previousColor,previousDirectory,this.src,color,baseDirectory);    
                    });                        
                });
                $('#hero_link').each(function(){                                        
                    this.href = o.getSrc(previousColor,previousDirectory,this.href,color,baseDirectory);    
                }) 
                $('#product_hero').each(function(){
                    var img = $(this);
                    var src = img.attr('src');
                                        
                    o.showLoading(img);

                    setTimeout(function(){
                        img.one('load',function(){
                            o.hideLoading(img);
                            if(MOLECULAR.browser.ie6){
                                img.parent().get(0).style.filter = 
                                    "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + o.getSrc(previousColor,previousDirectory,src,color,baseDirectory) + "', sizingMethod='scale')";
                            }                            
                        }).attr('src', o.getSrc(previousColor,previousDirectory,src,color,baseDirectory));                
                    },250);                      
   
                });
                o.isSwapping = false;
            });
        },
        init_lightboxPick : function(jPicker){
            var o = this;
            
            jPicker.find('li').bind('click',function(e){
                e.preventDefault();

                var el = $(this);
                var img = $('#nyroModalImg');
                var src = img.attr('src');

                // Normalize the domain, just in case it's missing the host/domain part
                var tmpImg = new Image();
                tmpImg.src = src;
                src = tmpImg.src;
                
                var selectedEl = $(this).parent().find('li.on');
                
                var previousColor = selectedEl.attr('data-swatch');
                var previousDirectory = selectedEl.attr('data-path');
                var color = el.attr('data-swatch');
                var baseDirectory = el.attr('data-path');

                // Make sure our loading image is up...
                o.showLoading(img);               
                setTimeout(function(){
                    img.one('load',function(){
                        o.hideLoading(img);
                        if(MOLECULAR.browser.ie6){
                            img.parent().get(0).style.filter = 
                                "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + o.getSrc(previousColor,previousDirectory,src,color,baseDirectory) + "', sizingMethod='scale')";
                            // IE6 likes to zap the close button among other things
                            $('#closeBut, #nyroModalContent').css('visibility','visible');
                        }                         
                    }).attr('src',o.getSrc(previousColor,previousDirectory,src,color,baseDirectory));                
                },250);  
                
                jPicker.find('li').removeClass('on');
                $(this).addClass('on');              
            });
        },
        showLoading : function(el){
            if (MOLECULAR.browser.ie6) {
                el = el.parent();
            }
    
            if(! loadEl){                
                var pos = el.position();
                
                loadEl = $('<div class="loading_bar__" style="display:none;"></div>');
                el.before(loadEl);                
                loadEl.css({
                    top : pos.top + (el.height()/2) - loadEl.height(),
                    left : pos.left + el.parent().width()/2 - loadEl.width()/2,
                    position : 'absolute'
                });
            }
            if(MOLECULAR.browser.ie6){
                el.css('visibility','hidden');
            }
            else{
                el.animate({
                    opacity : 0
                },250);                 
            }

            setTimeout(function(){
                loadEl.show();   
            },250);
        },
        hideLoading : function(el){
            if(MOLECULAR.browser.ie6){
                el = el.parent();
                el.css('visibility','visible');
            }
            else{
                el.animate({
                    opacity : 1
                },250);                
            }
            loadEl.hide();
        }        
    }
}();

/***
 * Image swapper utility for swapping hero product views.
 * 
 * To use: pass the ID of the parent UL we'll be clicking on and the image we're swapping to the init function.
 */
MOLECULAR.ProductPage.swapper = function(){
    var loadEl = null;
    
    return{
        handleClick : function(li,swapEl){
            var o = this;
            var el = $(li);
            var swapImg = $('#'+swapEl);
            var newSrc = el.find('a:eq(0)').attr('href'); 
            
            el.parent().find('li').removeClass('selected').end().end().addClass('selected');
            
            o.showLoading(swapImg);
            // Make sure our loading image is up...
            if(MOLECULAR.browser.ie6){
                setTimeout(function(){
                    swapImg.one('load',function(){
                        o.hideLoading(swapImg);
    
                        // Need to set this to largest dimensions by convention
                        $('#product_hero').parent()[0].style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + newSrc.replace(/604x604/g,'302x302') + "', sizingMethod='scale')";        
                        $('#hero_link').attr('href',newSrc);
                    }).attr('src',newSrc.replace(/604x604/g,'302x302'));                
                },250);                
            }
            else{
                setTimeout(function(){
                    swapImg.one('load',function(){
                        o.hideLoading(swapImg);
    
                        // Need to set this to largest dimensions by convention
                        $('#hero_link').attr('href',newSrc);
                    }).attr('src',newSrc.replace(/604x604/g,'302x302'));                
                },250);                
            }
        },
        showLoading : function(el){
            if(! loadEl){
                loadEl = $('<div class="loading_bar__" style="display:none;"></div>');
                el.parent().append(loadEl);
                
                loadEl.css({
                    top : el.height()/2,
                    left : (loadEl.width() + el.width())/2,
                    position : 'absolute',					
                    zIndex : '99'
                });
            }
            loadEl.show();
           if(! MOLECULAR.browser.ie7){
		    el.animate({
                opacity : 0
            },250); 
		  };  
        },
        hideLoading : function(el){
             if(! MOLECULAR.browser.ie7){
			el.animate({
                opacity : 1
            },250);
			};
            loadEl.hide();
        },
        init : function(listEl,swapEl){
            var o = this;
            $('#'+listEl+' li').bind('click',function(e){
                e.preventDefault();
                o.handleClick(this,swapEl)    
            });                
        }    
    }
}();

/***
 * Fisheye/hover + grow type widget
 */
MOLECULAR.ProductPage.fisheye = function(){
    return {
        init : function(parentEl){
            //if(MOLECULAR.browser.ie6) return false;
            
            $('#'+parentEl+' li').bind('mouseenter',function(e){
                var el = $(this).find('img').stop();
                if(MOLECULAR.browser.ie6){
                    el = el.parent();
                }
                var curEl = this;
                if(! el.attr('data-height')){
                    el.attr('data-height',el.height()).attr('data-width',el.width());                      
                }
    
                var width = el.width() / 0.75; 
                
                // If we're operating on an Element at about 500px, we need to make sure it doesn't scroll 
                // out of its parent's visible portion (overflow:hidden is on).
                
                // The first tests determines if this item is the first visible in an rtl-language gallery
                // and since IE reports the coordinates incorrectly we work around that.
                if(((MOLECULAR.browser.ie6 || MOLECULAR.browser.ie7) && MOLECULAR.direction) && (
                    el.parent().parent().position().left + el.parent().parent().parent().position().left == 0)){
                    el.stop().animate({
                        height : el.attr('data-height') / 0.75,
                        left : el.attr('data-width') * -.05,
                        width : el.attr('data-width') / 0.75
                    },250).css('z-index',99);                         
                }
                else if(MOLECULAR.direction && (el.parent().parent().offset().left < 2 * el.parent().parent().width())){
                    el.stop().animate({
                        height : el.attr('data-height') / 0.75,
                        left : el.attr('data-width') * -.05,
                        width : el.attr('data-width') / 0.75
                    },250).css('z-index',99);                    
                }
                else if(el.parent().parent().position().left > 500){
                    el.stop().animate({
                        height : el.attr('data-height') / 0.75,
                        left : -1 * (el.attr('data-width') / 4),
                        width : el.attr('data-width') / 0.75
                    },250).css('z-index',99);                    
                }
                else{
                    el.stop().animate({
                        height : el.attr('data-height') / 0.75,
                        left : el.attr('data-width') * -.10,
                        width : el.attr('data-width') / 0.75
                    },250).css('z-index',99);                    
                }
                
                if(! MOLECULAR.browser.ie7){
                    $(this).parent().find('li').each(function(){
                    	if(curEl !== this){
                            $(this).stop().animate({ opacity: 0.65 },350);     
                        }   
                    });                    
                }
            }).bind('mouseleave',function(){
                var el = $(this).find('img');
                if(MOLECULAR.browser.ie6){
                    el = el.parent();
                }
                var curEl = this;
                
                el.stop().animate({
                    height : el.attr('data-height'),
                    left : 0,
                    width : el.attr('data-width')
                },100).css('z-index',2);  
                
                if(! MOLECULAR.browser.ie7){
                    $(this).parent().find('li').each(function(){
                    	if(curEl !== this){
                            $(this).stop().animate({ opacity: 1 },250);    
                        }   
                    });                     
                }                                 
            }).find('img').attr('alt','');
        }
    }    
}();

/***
 * Handles the configuration/lightboxing of the Specifications view
 */
MOLECULAR.ProductPage.specs = function(){
    return {
        init : function(){
            $('div.specs','#product_specs').each(function(){
                var el = $(this);
                var anchors = el.find('dt').wrapInner('<a href="#"></a>').find('a');
                // We need to construct the HTML to allow us to lightbox the content associated with each item
                anchors.each(function(){
                    var a = $(this);
                    // Capture HTML ('Dimensions', etc.) and use that to create an ID for our content Element
                    var text = jQuery.trim(a.text());
                    var tmpId = text.replace(/[#;&,\.\+\*~'\:"\!\^$\[\]\(\)=>\|\/\s]/g,'-');                    
                    var section = el.find('div.hd h2').text();

                    a.attr('href','#'+tmpId).attr('title',section);    // Give this a title; used as lightbox title.
                    // Here's the meat of it: we construct the HTML in the DD that's the anchor tag's sibling.
                    // Then, we need to fake the width for the modal dialog, so we capture the widths of each of our 
                    // content Element's children. We'll also position any "specs" images correctly in the content flow, too.
                    a.parent().next().prepend('<h2>' + text + '</h2>').wrapInner('<div><div class="container"></div></div>')
                        .find('img.specs').each(function(){
                            $(this).parent().parent().append($(this).clone()).end().end().remove();
                        }).end().find('div:first-child:eq(0)').attr('id',tmpId).addClass('modal').each(function(){
                            // May want to zap this for IE6 + 7
                            var w = 40;    // 40 = set padding on div.bd in pop-up
                            $(this).children().each(function(){
                                w += $(this).width();
                            });
                            $(this).width(w);
                        });
                });
                anchors.nyroModal();                
            });
        }
    }
}()

// Add a JavaScript-enabled class to our root Element on document load.
// We'll be operating on this class in our CSS selectors.
$(document).ready(function(){
    var bodyTag = $('body').addClass('MOLECULAR');
    MOLECULAR.direction = bodyTag.attr('dir') == 'rtl';
    
    var container = $('#product_container').addClass('js_enabled').removeClass('no_js');    
    if(container.hasClass('articles')){
        MOLECULAR.ProductPage.levelContent();     
		if (MOLECULAR.browser.ie6) {
			if(typeof DD_belatedPNG !== 'undefined'){
	            DD_belatedPNG.fix('div.bd_articles .left');
			}
		}             
    }    
    else if(container.hasClass('overview')){   
        MOLECULAR.ProductPage.accordion.init('product_accordion');        
        MOLECULAR.ProductPage.picker.init('color_picker','product_shots');       
        MOLECULAR.ProductPage.swapper.init('product_shots','product_hero');
        MOLECULAR.ProductPage.preload('product_shots');
		MOLECULAR.ProductPage.init_mini_gallery();
        MOLECULAR.ProductPage.init_overview();        

        $('#hero_link').nyroModal();              
        
        setTimeout(MOLECULAR.ProductPage.levelContent,250);              

        
        // Recently Viewed Products corners and shadows
        $('#recentlyViewedContainerId').append('<span class="corner tr"></span><span class="corner tl"></span>')
            .find('.ppRecProdContainer:has(a)').append('<span class="product_dropshadow"></span>');
        $('.pp_tsr_medium','#recentlyViewedProductsHolder').append('<span class="corner br"></span><span class="corner bl"></span>');  
		
		// Buy Now Drop Downs
		$('dl.dropDown dd').hide();
	  
		$('dl.dropDown dt').click(function(){
			if ($(this).hasClass('expanded')) {
				$(this).removeClass('expanded').next().hide();
			}
			else{
				$(this).addClass('expanded').next().show();	
			}
		});	
			
	$('dl.dropDown dt').hover( function(){  $(this).addClass('hovered'); }, function(){ $(this).removeClass('hovered');  });    
	            

        if(MOLECULAR.browser.ie6){
            $('.pp_tsr_medium .corner','#recentlyViewedProductsHolder').css('zoom',1);

            if(typeof DD_belatedPNG !== 'undefined'){
                DD_belatedPNG.fix('#color_picker div.frame, #recentlyViewedContainerId img');
                $('ul.product_carousel img').each(function(){
                    $(this).wrap('<div></div>').parent().each(function(){
                        var img = $(this).find('img').addClass('png_fixed');
                        this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + img.attr('src') + "', sizingMethod='scale')";        
                        $(this).css({
                            zoom : 1,
                            cursor : 'hand',
                            width : img.width(),
                            height : img.height()
                        });
                    }).end().css('visibility','hidden');
                });
                $('#product_hero').wrap('<div></div>').parent().each(function(){
                    var img = $('#product_hero').addClass('png_fixed');
                    this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + img.attr('src') + "', sizingMethod='scale')";        
                    $(this).css({
                        zoom : 1,
                        cursor : 'hand',
                        width : img.width(),
                        height : img.height(),
                        'float' : 'left'                        
                    });                   
                }).end().css('visibility','hidden');
                
                $('ul#product_shots a').each(function(){
                    var aEl = $(this);
                    var img = aEl.children('img').css('visibility','hidden');
                    
                    aEl.css({ 'display' : 'block', 'width' : '100%', 'height' : '100%' }).get(0).style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + img.attr('src') + "', sizingMethod='scale')";    
                });
            }
            setTimeout(function(){         
                $('#whenCanI .corner').each(function(){
                    var c = $(this);
                    var p = c.parent();
                    c.height(p[0].offsetHeight);
                    p.height(p[0].offsetHeight - parseInt(p.css('padding-top')) - parseInt(p.css('padding-bottom')));                    
                });
                       
                $('#product_accordion .grad, #whenCanI .grad').each(function(){
                    var c = $(this);
                    var p = c.parent();
                    c.height(p[0].offsetHeight);
                    p.height(p[0].offsetHeight - parseInt(p.css('padding-top')) - parseInt(p.css('padding-bottom')));
                    c.width(p[0].offsetWidth);
                });           
            }, 1000);            
        }            
    }
    else if(container.hasClass('gallery')){       
        MOLECULAR.ProductPage.picker.init('color_picker','product_shots');      
        
        MOLECULAR.ProductPage.fisheye.init('product_shots');
        
        // Wire up lightboxing. Also, we're no-opping the gallery count function
        $('a','#product_shots').attr('title',' ').addClass('picker').nyroModal({galleryCounts : function(){}});   
        
        if(MOLECULAR.browser.ie6){
            if(MOLECULAR.direction){
                MOLECULAR.isIE6Gallery = true;    
            } 
            
            if(typeof DD_belatedPNG !== 'undefined'){
                DD_belatedPNG.fix('ul#color_picker div.frame');                         
            }


            $('ul#product_shots img').each(function(){
                var el = $(this).addClass('png_fixed').wrap('<div class="ie6_shim"></div>').parent();                    
                el.get(0).style.filter = 
                    "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "', sizingMethod='scale')";                
                this.style.visibility = 'hidden'; 
            }); 

            setTimeout(function(){$('body').addClass('ie6_load');},10);
        }   
        setTimeout(MOLECULAR.ProductPage.levelContent,250);  
    }
    else if(container.hasClass('features')){
        MOLECULAR.ProductPage.init_features();
               
        // Fix up IE6's corners
        if(MOLECULAR.browser.ie6){
            if(typeof DD_belatedPNG !== 'undefined') {
                setTimeout(function(){
                    DD_belatedPNG.fix('#content_target .features_ft, #features_nav_list li');
                },500);
            }
            
            $('div.f_phone').height($('#content_target').height()).each(function(){
                var phoneBg = $(this).css('backgroundImage').replace(/url\(["']?/i,'').replace(/["']?\)$/,'');
                if(! this.getAttribute('originalFilter')){
                    this.style.filter = 
                        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + phoneBg + "', sizingMethod='image')"; 
                    this.setAttribute('originalFilter',phoneBg);
                    this.style.backgroundImage = 'none';                                      
                }
            });
            setTimeout(function(){$('body').addClass('ie6_load');},10);
        }           
    }
    else if(container.hasClass('specs_nojs')){
        container.removeClass('specs_nojs').addClass('specs_full');
        MOLECULAR.ProductPage.specs.init();
        MOLECULAR.ProductPage.levelContent();
        
        // Fix up IE6's corners
        if (MOLECULAR.browser.ie6) {
            setTimeout(function(){                
                $('div.promo span.corner').each(function(){
                    var c = $(this);
                    var p = c.parent()[0];
                    if (c.height() < p.offsetHeight) {
                        c.height(p.offsetHeight);
                    }
                });
            }, 1000);
        }     
    }
    else if(container.hasClass('find_products')){
		
         //open layer 
		$('div.promoOverlay').css('visibility','hidden');		
		$('.expandable_phones').click(function(){
			
			$('#find_phones_popup').show().css('visibility','visible');
			if (MOLECULAR.browser.ie6) {
					$('div.lookin_for_device select').hide().end();
				}
			
		});	
		$('.expandable_accessories').click(function(){
			
			$('#find_accessories_popup').show().css('visibility','visible');
			if (MOLECULAR.browser.ie6) {
					$('div.lookin_for_device select').hide().end();
				}
			
		});	
		$('.expandable_maps').click(function(){
			
			$('#find_maps_popup').show().css('visibility','visible');
			
		});	
		
		//close button
		$('.close_btn').click(function(){
			if ($(this).parents().hasClass('promoOverlay')){
				$(this).parents('.promoOverlay').hide();
				if (MOLECULAR.browser.ie6) {
					$('div.lookin_for_device select').show().end();
				}
			}else{
				 return;
		    }
        });
		
         // Fix up IE6's corners
        if (MOLECULAR.browser.ie6) {
			if(typeof DD_belatedPNG !== 'undefined'){
	            DD_belatedPNG.fix('div img');
				DD_belatedPNG.fix('ul.lookin_for li');
				DD_belatedPNG.fix('div.find_phones_features dl dt');
				DD_belatedPNG.fix('div.find_phones_maps ul.find_phones_carousel li img');
				DD_belatedPNG.fix('div.find_phones_model');
				//DD_belatedPNG.fix('div#product_container ul.trapster li');
				//DD_belatedPNG.fix('.trapster a.cta_left');
				DD_belatedPNG.fix('div.lookin_for_device');
				DD_belatedPNG.fix('div.lookin_for_pdt');
			}
		}  
        
		 ddaccordion.init({//2nd level headers initialization
        	headerclass: "headerbar", //Shared CSS class name of headers group
        	contentclass: "submenu", //Shared CSS class name of contents group
        	revealtype: "click", //Reveal content when user clicks or onmouseover the header? Valid value: "click" or "mouseover
        	mouseoverdelay: 200, //if revealtype="mouseover", set delay in milliseconds before header expands onMouseover
        	collapseprev: true, //Collapse previous content (so only one open at any time)? true/false
        	defaultexpanded: [0], //index of content(s) open by default [index1, index2, etc] [] denotes no content
        	onemustopen: true, //Specify whether at least one header should be open always (so never all headers closed)
        	animatedefault: false, //Should contents open by default be animated into view?
        	persiststate: true, //persist state of opened contents within browser session?
        	toggleclass: ["off", "on"], //Two CSS classes to be applied to the header when it's collapsed and expanded, respectively ["class1", "class2"]
        	togglehtml: ["", "", ""], //Additional HTML added to the header when it's collapsed and expanded, respectively  ["position", "html1", "html2"] (see docs)
        	animatespeed: "normal", //speed of animation: integer in milliseconds (ie: 200), or keywords "fast", "normal", or "slow"
        	oninit:function(headers, expandedindices){ //custom code to run when headers have initalized
        		//do nothing
        	},
        	onopenclose:function(header, index, state, isuseractivated){ //custom code to run whenever a header is opened or closed
        						
        	}
        });
        
		$('#select_megapixels').change(function(){
			window.location=$(this).val();
		});
						
		$('#select_model').change(function(){
			window.location=$(this).val();
		});
		
    }
    else if(container.hasClass('email_friend') && MOLECULAR.browser.ie6){
        var h3 = $('button h3');
        var width = $('body').append('<span id="tmp__" style="visibility:hidden;"></span>');
        h3.width($('#tmp__').html(h3.html()).width());
        $('#tmp__').remove();
    }

    // Initalize all flyouts
    MOLECULAR.ProductPage.flyout.init(); 
    /*** 
     * Initalize all carousels
     * This would be done by removing each of the carousel init blocks above, and feeding them to jQuery like this:
    */
    $('ul.carousel').each(function(){
        MOLECULAR.ProductPage.init_carousel(this);
    });   
     
    /***
     * IE6 and IE7 have a bug where they drop the hash from URLs during a redirect. This affects the 
     * Overivew page's features icons. We work around that by changing the hash to a parameter, which
     * we will do for all browsers to keep things consistent.
    */  
    $('a.hover','#features_overview').each(function(){
        var href = this.href;
        if(href.indexOf('#') > 0){
            var anchorIndex = href.indexOf('#');
            if(href.indexOf('?') == -1){    // Do we need to add a ? for our param
                var newHref = href.substr(0,anchorIndex) + '?currentFeature=' + href.substr(anchorIndex + 1);
            }
            else{
                var newHref = href.substr(0,anchorIndex) + '&currentFeature=' + href.substr(anchorIndex + 1);                    
            }
            $(this).attr('href',newHref)
        }    
    });
        
    if(MOLECULAR.browser.ie6){
        var linkSpan = $('#ppproductNavi').css('width','auto');
        var parentEl = linkSpan.parent(); 
        if(parentEl.length > 0){
            linkSpan.width(parentEl.get(0).offsetWidth);            
        }       

        linkSpan.find('.corner').height(parseInt(linkSpan.height(),10) + 1);        
        $('body').addClass('ie6 no_png');
        $('#product_header').width(726);        
        if(MOLECULAR.direction){
            container.addClass('ie6_load');    // Add a class to enforce an IE6 redraw
        }
        // Set promo image PNG transparency
        $(window).bind('load',function(){
            setTimeout(function(){               
                $('div.promo div.bd img[src$=".png"]:not(.png_fixed)').each(function(){
                    var img = $(this);                    
                    var el = img.addClass('png_fixed').wrap('<span class="ie6_shim"></span>').parent();

                    el.get(0).style.filter = 
                        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "', sizingMethod='image')";                

                    if(img.hasClass('left')){
                        el.addClass('left');
                    }
                    if(img.hasClass('right')){
                        el.addClass('right');
                        el.css('right',img.css('right'));
                    }
                    this.style.visibility = 'hidden';  
                });                
            },750);
            if(container.hasClass('overview')){
                $('#overview_hero').height($('#overview_hero').height())
                    .css({
                        'overflow' : 'hidden',
                        'padding-bottom' : '20px'
                }).find('div.sidebar').css('position','relative');                   
            }          
        });        
    }
    else if(MOLECULAR.browser.ie7){
        $('body').addClass('ie7');
    }
});

// Override default PNG fix function so that we can use our own
function pngfix(){
    return true;
}
