/*!
 * BELL CANADA javascript UIKit v1.2583
 *
 * Development Team: Son Pham, Jean-Francois Payant
 * http://www.bellsolutionsweb.ca/
 *
 * Date: April 11th, 2011 -0500
 */
(function($) {
/***************************************************/
// plugin: scroller
//
// Developped by: Son Pham
//
// version: 2.5 (dec. 28, 2010) itemsContainer, scrollerContainer are now an array
// version: 2.0 (oct. 15, 2010)
// version: 1.0 (sept, 9, 2009)
//
// description: adds a scroller capability within a
//              container if scrolling is required
// 
// requirement: 1) jQuery 1.3.2+
//              2) jQuery ui 1.7+ (Slider)
//
//              3) elements structure required
//              3.1) Master Container of the content to be scrolled and scroller. Also this container will act as a MASK
//              3.2) Container that contains items of the scrolled content
//              3.3) Container that will contain the scroller
//              3.4) Container for footer
//
//              4) $.hasLayout() // IE6-IE7 support
//              5) $.setClassToNthPosition() // GridView
//              6) $.equalize() // Layout rendering
//              7) $.pageRender() // Layout rendering
//              8) $.scrollToElement() // animation
//				9) $.detect() // feature detection for touch devices
//
// usage: $(".selector").scroller({params})
//
// params : 
//  @fillSpace : (boolean) shows and sets the toggling behaviors onclick (gridView vs ScrollView) detault: true
//  @fillSpacePaddingRight : (integer) paddind-left between toggle button and scroller default: 120
//  @showNavigation : (boolean) shows left and right button navigation detault: true
//  @speed : (integer/string) scrolling speed if string then use "fast", "slow"  default: 1500
//  @toggle* : (boolean) shows toggle View Grid/scroller Note: fillSpace must be false in order to enable toggle detault: false
//  @toggleTitle*: (string) the toggle title via element attribute title default: "Display as scroller/grid"
//  @maskContainer: (string) Master Container of the content to be scrolled and scroller. Also this container will act as a MASK default: "cBox"
//  @itemsContainer: (string) Container that contains items of the scrolled content default: "refLine"
//  @scrollerContainer: (string) Container that will contain the scroller default: "cFoot"
//  @nthClassName: (string) which css ClassName determines the last of each row (will be used for gridView pagination) default : "colLast"
//  @pagerNavigationClassName: (string) css className of the <ul> containing the gridView page numbers list default : "pageCounter"
//  @gridViewModeClassName: (string) css className that will be added when scroller is in GridView mode  default: "cToggleView"
//  @minScrollBarWidth: (integer) minimum scrollBar width in pourcent of the scroller total width default : 33
//	@view: (string) defaults the view of the scroller (gridView or sliderView) default: "slider" // on touch device it will be "grid"
//	@disableGridContext: (string) sometimes gridView is not appropriate like in a lightBox.  That's why you can specify a parent className on wich default GridView will be slider
/**********************************************************/
/*global jQuery*/
jQuery.fn.scroller = function(settings) {
    var defaults, validateParams,
        languageResourceEnabled = $.isFunction($.getText),
        defToggleTitle = "Display as scroller / grid";
    
    defaults = {
        fillSpace: true,
        fillSpacePaddingRight: 120,
        showNavigation: true,
        speed: 1500,        
        toggle: false,
        toggleTitle: languageResourceEnabled?$.getText("scrollerTogglerToolTip"):defToggleTitle,
        togglerClassName: "tglBtn",
        maskContainer: "cBox",
        itemsContainer: ["refLine","colGroup"],
        scrollerContainer: ["cFoot", "cFooter"],
        emptyClassName: "hScrollBarEmpty",
        nthClassName: "colLast",
        pagerNavigationClassName: "pageCounter",
        gridViewModeClassName: "cToggleView",
        minScrollBarWidth: 33, // pourcent 33% of the scroller width
		view: "slider",
		disableGridContext: "lbFrame"
	};
    
    settings = $.extend(false, defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.fillSpace) !== "boolean") {
            settings.fillSpace = true;
        }
        if (isNaN(settings.fillSpacePaddingRight)) {
            settings.fillSpacePaddingRight = 125;
        }
        if (typeof(settings.showNavigation) !== "boolean") {
            settings.showNavigation = true;
        }
        if (isNaN(settings.speed)) {
            settings.speed = 1500;
        }
        if (typeof(settings.toggle) !== "boolean") {
            settings.toggle = false;
        }
        if (typeof(settings.toggleTitle) !== "string") {
            settings.toggleTitle = defToggleTitle;
        }
        if (typeof(settings.togglerClassName) !== "string") {
            settings.togglerClassName = "tglBtn";
        }       
        if (typeof(settings.maskContainer) !== "string") {
            settings.maskContainer = "cBox";
        }
        if (typeof(settings.itemsContainer) !== "object") {
            settings.itemsContainer = ["refLine","colGroup"];
        }
        if (typeof(settings.scrollerContainer) !== "object") {
            settings.scrollerContainer = ["cFoot", "cFooter"];
        }
        if (typeof(settings.emptyClassName) !== "string") {
            settings.emptyClassName = "hScrollBarEmpty";
        }
        if (typeof(settings.nthClassName) !== "string") {
            settings.nthClassName = "colLast";
        }
        if (typeof(settings.pagerNavigationClassName) !== "string") {
            settings.pagerNavigationClassName = "pageCounter";
        }
        if (typeof(settings.gridViewModeClassName) !== "string") {
            settings.gridViewModeClassName = "cToggleView";
        }
        if (isNaN(settings.minScrollBarWidth)) {
            settings.minScrollBarWidth = 33;
        }
        if (typeof(settings.view) !== "string") {
            settings.view = "slider";
        }
        if (typeof(settings.disableGridContext) !== "string") {
            settings.disableGridContext = "lbFrame";
        }
    };

    return this.each(function(idx){
        var $mask = $(this),
            maskWidth = $mask.innerWidth(),
            enableScroll, beenInitialized,
            $contents, $content, $contentVisible,
            contentItemWidth, margins, $contentChild,
            gridColMargin, contentWidth, childWidth,
            distanceToScroll, distanceToScrollRatio, $child, isVisible,
            $scroller, $scrollBar, $linkRewind, $linkForward,
            scrollBarWidget, scrollBarMinWidth,
            start, end, scrollBarWith,
            move, navigateStep, remainingStep,
            $handle, ratioBase, hundredPourcentGap,
            html, $tglBtn, $cToggle, displayText,
            widgetClassName = $.getJsClassName($mask),
            $cFoot;
            
        // Loading problem detection
        if (maskWidth === 0) {
            // When maskWidth = 0, it means that the element is there but
            // for some reason is not fully DOM loaded and therefore accessing
            // computedStyle will not work properly 
            /*global window, setTimeout */
            window.scrollerId = setTimeout(function() {
                $mask.scroller({
                    fillSpace: settings.fillSpace,
                    fillSpacePaddingRight: settings.fillSpacePaddingRight,
                    showNavigation: settings.showNavigation,
                    speed: settings.speed,
                    toggle: settings.toggle,
                    toggleTitle: settings.toggleTitle,
                    maskContainer: settings.maskContainer,
                    itemsContainer: settings.itemsContainer,
                    scrollerContainer: settings.scrollerContainer
                });
            }, 10);
        }
        
        if (window.scrollerId) { 
            /*global clearTimeout */
            clearTimeout(window.scrollerId); 
        }
        
        enableScroll = false;
        beenInitialized = false;
        
        //validateParams
        if (idx ===0) { 
            validateParams();
            
            if ($mask.hasClass("scrollerInitializedJs")) {
                beenInitialized = true; 
            }           
        }

		$.each(settings.itemsContainer, function(idx, value) {
			$contents = $mask.find("."+value);
			if ($contents.length) { return false; }
		});

        // Reset the scroller
        $mask.removeClass(settings.gridViewModeClassName).removeClass(widgetClassName).find(".emptyJs").each(function() {
            $(this).remove();                                                                                                             
        });
        
        if (beenInitialized) {
            $mask.removeClass(settings.emptyClassName);
            
            $contents.each(function() {
                $content = $(this);
                isVisible = $content.is(":visible");
                displayText = "block";
                    
                if (!isVisible) { displayText = "none"; }
                
                $content.removeAttr("style").css("display", displayText);
            });
        }

        if (!$contentVisible) {
			$.each(settings.itemsContainer, function(idx, value) {
				$contentVisible = $mask.find("."+value+":visible:last");
				if ($contentVisible.length) { return false; }
			});            
        }

        // content must be visible
        $content = $contentVisible;
        $.each(settings.itemsContainer, function(idx, value) {
			if (value.indexOf("#") !== -1) {
				$content = $(value);
				return false;  
			}		
		});

        if ($content.length) {
            $.scroller.resetNavigation($content);
            
            // plugin flags
            $content.addClass("scrollerContentJs");
            $mask.addClass("scrollerInitializedJs");
            
            // load images
            if ($.isFunction($.loadImages)) { 
                $.loadImages($content.find("img")); 
            }
            
            $contentChild = $content.children(":visible:not(.hide)");
            gridColMargin = parseInt($content.children(":last").css("margin-right"),10);
            contentWidth = 0;
            childWidth = 0;
            
			// footer
			$.each(settings.scrollerContainer, function(idx, value) {
				$cFoot = $mask.find("."+value).first();
				if ($cFoot.length) { return false; }			
			});
			    
            if ($contentChild.length) {
                childWidth = $($contentChild[0]).outerWidth();
                if (childWidth === 0) {
                    childWidth = parseInt($($contentChild[0]).css("width"),10);
                }
            }
            if ((childWidth*$contentChild.length) > maskWidth) {
                enableScroll = true;

                // Add JsClassName
                if (widgetClassName!=="") { $mask.addClass(widgetClassName); }
                
                // Compute total content width
                $contentChild.each(function() {
                    $child = $(this);
                    childWidth = $child.outerWidth();
                        
                    if (childWidth === 0) {
                        childWidth = parseInt($child.css("width"),10);
                    } 
                    margins = parseInt($child.css("marginLeft"),10) + parseInt($child.css("marginRight"),10);
                    contentItemWidth = margins + childWidth;
                    contentWidth += contentItemWidth;
                });
                $content.width(contentWidth);
        
                // slider needs to be initialize here in order
                // to generate the ui-handle.  After ui-handle generated,
                // we need to compute its start and end
                distanceToScroll = contentWidth-maskWidth-gridColMargin;
                if (distanceToScroll>0) {
                    // Delete previous scroller
                    $scroller = $mask.find(".scroller");
                    if ($scroller.length) { $scroller.remove(); }
                    
                    // Create scroller HTML markup
                    /*global document */
                    $scroller = $("<div class='scroller'></div>");
                    $scrollBar = $("<div class='scrollBar'></div>");
                    $linkRewind = $("<div class='scrollBarRewind scrollBarRewindInactive'></div>");
                    $linkForward = $("<div class='scrollBarForward'></div>");
                    
                    if (settings.showNavigation) {
                        $scroller.append($linkRewind).append($scrollBar).append($linkForward);
                    } else {
                        $scroller.append($scrollBar);
                        $scroller.css("paddingLeft",0).css("paddingRight",0);
                    }
					
                    $cFoot.append($scroller).append("<div class='clearer'><\/div>");
                    
                    // Must set scrollbar width
                    if (!settings.fillSpace) {
                        $cFoot.css("paddingRight", settings.fillSpacePaddingRight);
                    } else {
                        $cFoot.removeAttr("style");                     
                    }
                    scrollBarWidget = $scroller.width();
                    if (scrollBarWidget === 0) { 
                        scrollBarWidget = "100%";
                        $scrollBar.width(scrollBarWidget);
                        scrollBarWidget = maskWidth;
                    } else {
                        $scrollBar.width(scrollBarWidget);  
                    }
                    
                    
                    // Compute handle / scrollBar Witdh
                    // Slider component initialization
                    $scrollBar.slider({                           
                        value: start,
                        slide: function(event, ui) {
                            move = (distanceToScroll * (ui.value - start)) / remainingStep;
                            
                            $(this).find(".ui-slider-handle:first").addClass("scrollBarDrag");
        
                            if (ui.value >= start && ui.value <= end) {
                                $content.stop().css("left", -move+"px");
                                $linkForward.removeClass("scrollBarForwardInactive");
                                $linkRewind.removeClass("scrollBarRewindInactive");                         
                            } else if (ui.value < start) {
                                $content.stop().css("left", "0px");
                                $(this).slider("value",start);
                                
                                $linkForward.removeClass("scrollBarForwardInactive");                                   
                                $linkRewind.addClass("scrollBarRewindInactive");
                                return false;
                            } else if (ui.value >= end) {
                                $content.stop().css("left", -distanceToScroll+"px");    
                                $(this).slider("value",end);
        
                                $linkForward.addClass("scrollBarForwardInactive");
                                $linkRewind.removeClass("scrollBarRewindInactive");
                                return false;
                            }else {
                                return false;                               
                            }
                        },
                        stop: function() {
                            $(this).find(".ui-slider-handle:first").removeClass("scrollBarDrag");
							$.scroller.tracker($scrollBar, "slide", "center");
						}
                    });
                    
                    // After widget initialization
                    navigateStep = Math.ceil(maskWidth/contentItemWidth)*contentItemWidth;
                    
                    $scrollBar.find("a").html("<span></span>");
                    
                    $linkRewind.click(function() {
                        var curPosition = parseInt($content.css("left"),10);
                        if ((distanceToScroll-Math.abs(curPosition)+navigateStep) < distanceToScroll) {
                            curPosition += navigateStep;
                            $content.stop().animate({ "left": curPosition+"px"}, settings.speed);
                            $(this).removeClass("scrollBarRewindInactive");
                            $scrollBar.slider("value",parseInt(((Math.abs(curPosition)*remainingStep)+(distanceToScroll*start))/distanceToScroll,10));
                        } else {
                            $content.stop().animate({left :"0px"}, settings.speed);
                            $scrollBar.slider("value", start);                      
                            $(this).addClass("scrollBarRewindInactive");
                        }
						$.scroller.tracker($linkRewind,"slide", "left");
                        $linkForward.removeClass("scrollBarForwardInactive");                       
                        return false;                                                                 
                    });
        
                    $linkForward.click(function() {
                        var curPosition = parseInt($content.css("left"),10),
                            ending = end;
                            
                        if (isNaN(curPosition)) { curPosition = 0;}
                        if (Math.abs(curPosition)+navigateStep > distanceToScroll) {
                            $(this).addClass("scrollBarForwardInactive");
                            curPosition = -distanceToScroll;
                        } else {
                            $(this).removeClass("scrollBarForwardInactive");
                            curPosition -= navigateStep;
                            ending = parseInt(((Math.abs(curPosition)*remainingStep)+(distanceToScroll*start))/distanceToScroll,10);
                        }
						$linkRewind.removeClass("scrollBarRewindInactive");                     
                        $content.stop().animate({left : curPosition+"px"}, settings.speed);
                        $.scroller.tracker($linkForward,"slide", "right");
						
						$scrollBar.slider("value",ending);
                        return false;
                    });
        
                    
                    // Append extra markup to scrollBar
                    $scrollBar.append("<span></span>");
        
                    // Compute handle start / end / scrollbar-handle with
                    $handle = $mask.find(".ui-slider-handle");              
                    if ($handle.length) {
                        distanceToScrollRatio = (distanceToScroll/contentWidth)*100;
                        scrollBarWith = parseInt((Math.abs(distanceToScrollRatio-100)/100)*maskWidth,10);

                        if (!settings.fillSpace) {                          
                            scrollBarWith -= settings.fillSpacePaddingRight/2;
                        }
                        
                        // ScrollBar width size protection e.g scrollBar must have a minimum size in order
                        // to be usable by the user
                        if (scrollBarWith>scrollBarWidget) {
                            scrollBarWith = scrollBarWidget-Math.ceil((distanceToScrollRatio/100)*scrollBarWidget);
                            if (scrollBarWith>scrollBarWidget) {
                                scrollBarWith = scrollBarWidget/2;
                            } 
                        } else {
                            scrollBarMinWidth = Math.ceil((settings.minScrollBarWidth/100)*scrollBarWidget);
                            if (scrollBarWith < scrollBarMinWidth) {
                                scrollBarWith = scrollBarMinWidth;
                            }
                        }
                        
                        ratioBase = (scrollBarWith/scrollBarWidget)/2;
                        start = Math.round(ratioBase*Math.pow(10,3))/Math.pow(10,3)*100;
                        end = ((maskWidth-scrollBarWith)/maskWidth)*100;
                        end += start;
                        
                        hundredPourcentGap = (100)-start-end;
                        end += hundredPourcentGap;
                        
                        remainingStep = end-start;
                        
                        //  add margin negative in order to compensate -move
                        $handle.css("marginLeft", -parseInt(scrollBarWith,10)/2+"px").width(scrollBarWith);
                    }
                    // Push ui-handle to the left to compensate margin negative
                    $handle.css("left", start+"%");
                }
            } else {
                $mask.addClass(settings.emptyClassName).removeClass(widgetClassName);
                $cFoot.find(".scroller").remove();
            }
        }
        
        if (!settings.fillSpace) {
            // Toggle layout (scroll / grid)
            if (settings.toggle && enableScroll) {
                // Create HTML markup for fillSpace
                html = "";
                html += "<div class='tglBtn'>\n";
                html += "   <a href='#' title='"+decodeURIComponent(settings.toggleTitle).replace("'","`").replace("'","`")+"'>"+decodeURIComponent(settings.toggleTitle).replace("'","`").replace("'","`")+"<\/a>\n";
                html += "<\/div>\n";
    
                $tglBtn = $(this).find(".tglBtn");
                
                // Remove previous toggles
                if ($tglBtn.length) { $tglBtn.remove(); } 
                
                $cFoot.append(html);
                $tglBtn = $(this).find(".tglBtn");
                
                // Initialize toggleViews with scroll vs ListView
                $tglBtn.each(function() {
                    $(this).unbind("click").click(function() {
                        $cToggle = $(this).parents("."+settings.maskContainer+":first");
                        
						$.each(settings.itemsContainer, function(idx, value) {
							$content = $cToggle.find("."+value+":visible:first");
							if ($content.length) { return false; }					
						});
						
						$content.stop();

                        // cleanup previous show/hide state
                        $.scroller.resetNavigation($content);
                        
                        if ($cToggle.hasClass(widgetClassName)) { // GridView
							$.scroller.showMode("grid", $cToggle, $content, $tglBtn, widgetClassName, settings);              
                        } else { // Scroller View
							$.scroller.showMode("slider", $cToggle, $content, $tglBtn, widgetClassName, settings);              
                        }
                    });
                });
				
				// Touch devices
				if (($.detect.touch() || settings.view === "grid") && widgetClassName!=="" && $mask.parents(settings.disableGridContext+":first").length === 0) {
					if (!$.data($mask.get(0), "touchInitialized")) {
						$.scroller.showMode("grid", $mask, $contents , $tglBtn, widgetClassName, settings);		
						$.data($mask.get(0), "touchInitialized", true);
					}
				}
            } else {
                $mask.find("."+settings.togglerClassName+", ."+settings.pagerNavigationClassName).remove();
            }
        } else {
            $mask.find("."+settings.togglerClassName+", ."+settings.pagerNavigationClassName).remove();
        }
        // finally we update items count if applicable
        $.scroller.updateItemsCount($mask, "h2");

        if ($.isFunction($.pageRender)) {
            if ($mask.length) {
                if ($content) {
                    // equalize units
                    if ($.isFunction(jQuery.fn.equalize)) {
                        // TODO: find a way to not hardcode value here
                        $content.equalize({similarItem:"unit", siblings: false});
                    }
                }
                $.pageRender($mask, "scroller");
            }
        }
    });
};
jQuery.scroller = {
    count: function(maskContainer) {
        var result = 0,
            $container = $(maskContainer),
            $content;
            
        if ($container.length) {
            $content = $(".scrollerContentJs", $container);
            if ($content.length) {
                return $content.children(":visible:not(.hide):not(.emptyJs)").length;   
            }
        }
        return result;
    },
    // cleanup previous scroller items show/hide state
    resetNavigation: function(content) {
        var $child, $content, removeInlineFnEnable = $.isFunction($.removeInlineCSSProp);
        $content = $(content);
        $content.children().each(function() {
            if (this.className.indexOf("scrollerGridView") !== -1) {
                $child = $(this);
                $child.removeClass("scrollerGridViewShowJs").removeClass("scrollerGridViewHideJs");
                if (removeInlineFnEnable) {
                    $.removeInlineCSSProp($child,"display");
                }
            }
        });     
    },  
    // update container listing title when having multiple scrollers and toggles
    updateItemsCount : function(scroller, titleHtmlTag) {
        var $scroller = $(scroller),
            $title = $(titleHtmlTag+":first", $scroller),
            text = $title.text(),
            textIdx = text.indexOf("("),
            label, newValue;
                                     
        if (textIdx !== -1) {
            text = text.substr(0, textIdx);            
        }
        label = " "+$.getText("items");
        newValue = this.count($scroller);
        
        if (newValue > 1) { label += "s"; }
        label = "("+newValue+label+")";
                    
        text = text+" <span>"+label+"</span>";

        $title.html(text);
        /*global Cufon */
        if (typeof(Cufon) === "function") {
            Cufon.replace($title);
        }
    },
	showMode: function(mode, $cToggle, $content, $tglBtn, widgetClassName, settings) {
		if (mode === "grid") {
			var $this;
			$cToggle.each(function(){
				$this = $(this); 
				$this.removeClass(widgetClassName).addClass(settings.gridViewModeClassName);
				
				$.each(settings.itemsContainer, function(idx, value) {
					$content = $this.find("."+value+":visible");
					if ($content.length) { return false; }
				});
				                       
				$content.removeAttr("style").show();
				$this.find(".scroller").remove();

				//Trigger hasLayout for IE6
				if ($.isFunction($.hasLayout)) {
					$.hasLayout($content);
				}
				
				$.scroller.generateNavigationPager($cToggle, settings);
				
				// track with omniture
				$.scroller.tracker($tglBtn, "button","matrix");
		
				return false;                       
			});   
		} else { // Scroller view
			$cToggle.addClass(widgetClassName).removeClass(settings.gridViewModeClassName);
			
			$cToggle.scroller({
				fillSpace: settings.fillSpace,
				fillSpacePaddingRight: settings.fillSpacePaddingRight,
				showNavigation: settings.showNavigation,
				speed: settings.speed,
				toggle: settings.toggle,
				toggleTitle: settings.toggleTitle,
				maskContainer: settings.maskContainer,
				itemsContainer: settings.itemsContainer,
				scrollerContainer: settings.scrollerContainer,
				view: settings.view
			});
			
			//Trigger hasLayout for IE6
			if ($.isFunction($.hasLayout)) {
				$.hasLayout($content);
			}

			// scroll animation
			if ($.isFunction(jQuery.scrollToElement)) {
				$.scrollToElement($cToggle);    
			}
			
			// track with omniture
			$.scroller.tracker($tglBtn, "button", "row");
		}
		// equalize units
		if ($.isFunction(jQuery.fn.equalize)) {
			// TODO: find a way to not hardcode value here
			$cToggle.equalize({similarItem:"unit", siblings: false});
		}
	},
    generateNavigationPager: function($widget, settings) {
        var col = 3, row = 3,
            totalItems, itemsPerPage, nbPages,
            html = "", page,
            active = " class='active'",
            first = " class='first'",
            last = " class='last'",
            $items, $page, $footer, $content;

		$.each(settings.scrollerContainer, function(idx, value) {
			$footer = $widget.find("."+value+":first");
			if ($footer.length) { return false; }		
		});
        
        $footer.find("."+settings.pagerNavigationClassName).remove();

        $content = $(".scrollerContentJs", $widget);
        if ($content.length) {      
            $items = $content.children(":visible:not(.hide)");
            totalItems = $items.length;
            
            $items.each(function(idx) {
                if ($(this).hasClass(settings.nthClassName)) {
                    col = idx+1;
                    return false;   
                }
            });
            
            itemsPerPage = col*row;
            
            if (totalItems > itemsPerPage) {            
                nbPages = Math.ceil(totalItems/itemsPerPage);
    
                if (nbPages > 1) {
                    html = "<div class='"+settings.pagerNavigationClassName+"'>";
                    html += "<ul>\n";
                    
                    for (page=0;page<nbPages;page++) {
                        if (page>0) { 
                            active = "";
                            first = "";                     
                        }
                        if (page === nbPages-1) {
                            first = last;   
                        }
                        html += "<li"+active+"><a"+first+" href='#'>";
                        html += page+1;                 
                        html += "<span></span></a></li>\n";
                    }
                    html += "</ul>\n";
                    html += "</div>";
                    
                    $page = $(html);
                    $footer.append($page);
    
                    // initial show
                    $.scroller.showPage($content, $items, $footer, itemsPerPage, 1, settings);
                    
                    $widget.find("."+settings.pagerNavigationClassName+" a").each(function(idx) {
                        $(this).click(function() {
                            $widget.find("."+settings.pagerNavigationClassName+" a").each(function(curIdx) {
                                if (curIdx === idx) {
                                    $(this).parent().addClass("active");
                                } else {
                                    $(this).parent().removeClass("active");
                                }
                            });
                            $.scroller.showPage($content, $items, $footer, itemsPerPage, idx+1, settings);
                            return false;                    
                        });
                    });
                }
            }
        }
    },
    showPage: function($content, $items, $footer, itemsPerPage, page, settings) {
        var startIdx = (page-1)*itemsPerPage,
            endIdx = page*itemsPerPage-1,
            $emptyItem, $item, nbVisible = 0,
            hasColClassName = false,
            i, col;

        // clean empty items
        $content.children(".emptyJs").remove();

        $items.each(function(idx) {
            $item = $(this);
            if (idx >= startIdx && idx <= endIdx) {
                $item.addClass("scrollerGridViewShowJs").show();
                nbVisible++;
            } else {
                $item.addClass("scrollerGridViewHideJs").hide();                
            }
            if ($item.get(0).className.indexOf("col") !== -1) {
                hasColClassName = true; 
            }
        });
        

        if (hasColClassName) {
            $emptyItem = $($items[0]).clone();
                
            if (nbVisible < itemsPerPage) {
                $emptyItem.removeAttr("style").removeClass("scrollerGridViewShowJs").removeClass("scrollerGridViewHideJs").addClass("emptyJs").find(".unit:first").empty().append('<div class="unitExtra"></div>');
            
                for (i=1;i<(itemsPerPage-nbVisible);i++) {
                    $content.append($emptyItem.clone());    
                }
            }

            col = parseInt($emptyItem.get(0).className.split("col")[1].split(" ")[0],10)-1;

            if ($.isFunction($.setClassToNthPosition)) {
                $.setClassToNthPosition($content.children(":visible:not(.hide)"), col, settings.nthClassName);
            }
        }
    },
	tracker: function($element, control, value) {
		if (typeof $.bell === "object") {
			if ($.bell.external) {
				if ($.isFunction($.bell.external.tracker)) {
					var params = {};
					if (control === "slide") {
						params.s_oPGS = "037";
					} else {
						params.s_oPGS = "038";				
					}
					params.s_oPRM = value;
					
					$.bell.external.tracker({
						appName: "omniture",
						actionName: "slider",
						data: params
					});
				}
			}
		}
	}
};
/***************************************************/
// plugin: equalize
//
// Developped by: Son Pham
//
// version: 1.6 (may 2011: support of builtIn CSS className "eqRootResetJs" to skip an element from the process)
// version: 1.5 (december 2010: similar items are only siblings())
// version: 1.0 (octobre 2010)
//
// description: equalize the height a list of elements having the same rootElement
// 
// note: this equalize function has been customized and optimized for BELL.ca 
//       HTML markeup structure.  It should also work if you attempt to equalize 
//       other regular HTML element not following BELL.ca HTML structure
//
// requirement: 1) jQuery 1.3.2
//              2) $.isIE();
//				3) $.removeInlineCSSProp()
//
// usage:   1) $(".selector").equalize({params})
//          2) $(".cBoxThemeA").equalize({insideItem: ["bStick","pricingInfo"]})
//          3) $(".cBoxThemeA").equalize({similarItem: "unit", insideItem: ["bStick","pricingInfo"]})
//			4) $(".eqRootJs").equilize({similarItem:"eqJs"});
//
// builtIn CSS className: when using CSS className "eqRootResetJs" this will skip this element from equalize process
//
// params : 
//  @similarItem: (string) className or element tag representing similar items to compare againts  default: "unit"
//  @insideItems: (array) specify extra element to add in the height calculation default: ["bStick","stickyBottom"]
//	@anchorItems: (array) specify elements immediate child to be considered as anchor.  Instead of applying the min-height on the similar items it will be applied on the anchor default: ["stickyFigure"]
//	@siblings: (boolean) indicates if similarItem should be siblings default: true
/**********************************************************/
jQuery.fn.equalize = function(settings) {
   var defaults, validateParams, getExtraHeights, loadMedias;
    
    defaults = {
        similarItem: "eqJs",
        insideItems: ["bStick","stickyBottom"],
        anchorItems: ["stickyFigure"],
		siblings: true
    };
    settings = $.extend(defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.similarItem) !== "string") {
            settings.similarItem = "unit";
        }
        if (typeof(settings.insideItems) !== "object") {
            settings.insideItems = ["bStick","stickyBottom"];
        }
        if (typeof(settings.anchorItems) !== "object") {
            settings.anchorItems = ["stickyFigure"];
        }		
        if (typeof(settings.siblings) !== "boolean") {
            settings.siblings = true;
        }		
    };

    getExtraHeights = function($item) {
        var extraHeights = 0,
            arrExtras = $.makeArray(settings.insideItems);
        
        $.each(arrExtras, function(idx, value) {
			$item.find("."+value).each(function() {
                return (function($extraElement) {
                    extraHeights += $extraElement.outerHeight(true);
				}($(this)));
            });         
        });
        return parseInt(extraHeights,10);
    };
    
    loadMedias = function(itemImages) {
        if ($.isFunction($.loadImages)) {
            return (function(images) {
                $.loadImages(images);
            }(itemImages));
        } 
    };

    return this.each(function(idx){
        //validateParams
        if (idx ===0) { validateParams(); }
                              
        var currentTallest = 0,
            $this = $(this), $items,
            itemH = 0, $content,
            largerImageFound = false,
            $item, $img, isElement = false,
            imgH, contentH = 0, arrExtras,
            currentFontSize, cssProp,
            $tmpElement, newHeight,
			$anchor, toApplyOnAnchor,
            isIE = $.isIE(), isIE6 = $.isIE(6), isIEGreaterThan7 = $.isIE(">7");          
        
		if (!$this.hasClass("eqRootResetJs")) {		
			$item = $this.find("."+settings.similarItem+":first");
	
			if ($item.length === 0) {
				$item = $this.find(settings.similarItem+":first");
				if ($item.length) { isElement = true; }
			}
			
			if ($item.length) {
				if (settings.siblings) {     
					$items = $item.siblings();
					$items.push($item);
				} else {
					if (!isElement) {
						$items = $this.find("."+settings.similarItem);
					} else {
						$items = $this.find(settings.similarItem);
					}
				}
	
				loadMedias($("img",$items));
			
				$items.each(function(){
					$item = $(this);
					// remove any height styling
					$.removeInlineCSSProp($item,"height");
					$.removeInlineCSSProp($item,"min-height");
					$item.removeClass("eqImgSmallerJs").removeClass("eqImgLargerJs");
					
					itemH = $item.height()+getExtraHeights($item);
	
					$item.find("img").each(function() {
						$img = $(this);
						imgH = $img.outerHeight();
		
						// Most of the structure contains sectionContent/itemInfo otherwise
						// function will simply ignore sectionContent/itemInfo
						$content = $item.find(".itemInfo:first"); 
						if ($content.length) {
							$content.each(function() {
								contentH = $(this).outerHeight(true);                                 
							});
						} else {
							$content = $item.find(".sectionContent:first");
							if ($content.length) {
								$content.each(function() {
									contentH = $(this).outerHeight(true);                              
								});				
							}
						}
							
						if ($img.css("float") !== "none") {
							if (imgH > contentH) {
								//To avoid any extra spacing, we take the diffence space
								//between larger image and content
								itemH -= (imgH-contentH);
								largerImageFound = true;
								$item.addClass("eqImgLargerJs");    
							} else {
								//Do nothing to unit because image is smaller than content.
								//So content will automatically flow in it's original flow stack
								$item.addClass("eqImgSmallerJs");
							}
						} else if ($img.css("position").toLowerCase() === "absolute") {
							if (imgH > contentH) {
								itemH = imgH;
								itemH -= parseInt($item.css("paddingBottom"),10);
							} else {
								itemH = $item.outerHeight(true)+getExtraHeights($item);
								
								arrExtras = $.makeArray(settings.insideItems);
								$.each(arrExtras, function(idx, value) {
									// Each extra element we remove the extra height + the bottom value
									$item.find("."+value+":first").each(function() {
										return (function($extraElement) {
											itemH -= parseInt($extraElement.css("bottom"),10)*2;
										}($(this)));
									});
													   
								});
							}
						}
					});
					
					if (itemH > currentTallest) { 
						currentTallest = itemH;
					}
				});
				
				if (isIE) {
					if (isIEGreaterThan7) {
						if (!$.data(document.body,"fontSize")) {
							$tmpElement = $("<span id='fontSizeChecker'>fontSize</span>");
							$tmpElement.css("fontSize", "1em");
							$("body").append($tmpElement);
							currentFontSize = $.getPixelValue($("#fontSizeChecker"),$("#fontSizeChecker").css("fontSize"));
							$tmpElement.remove();
							$.data(document.body,"fontSize",currentFontSize);
						} else {
							currentFontSize = $.data(document.body,"fontSize");	
						}
					}
				} else {
					currentFontSize = parseInt($("body").css("fontSize"),10);
				}
	
				if (!isIE || isIEGreaterThan7) { 
					newHeight = (currentTallest/currentFontSize) + "em";
				} else {
					newHeight = currentTallest + "px";
				}
	
				if (parseInt(newHeight,10) > 0)  {       
					cssProp = isIE6?'height':'min-height';
					$items.each(function() {
						toApplyOnAnchor = false;
						$item = $(this);					
						$.each(settings.anchorItems, function(idx, value) {
							if ($item.attr("class").indexOf(value) !== -1) {
								toApplyOnAnchor = true;
								$anchor = $item.children(":first");							
								return false;	
							}
						});
						if (!toApplyOnAnchor) {
							$item.css(cssProp,newHeight);
						} else {
							$anchor.css(cssProp,newHeight);	
						}
					});
			
					if (largerImageFound) {
						currentTallest = 0;
						$items.each(function() {
							itemH = $(this).height();
							if (itemH > currentTallest) {
								currentTallest = itemH;
							}
						});
						if (!isIE || isIEGreaterThan7) {
							newHeight = (currentTallest / currentFontSize) + ("em");
						} else {
							newHeight = currentTallest + "px";
						}
						cssProp = isIE6?'height':'min-height';
						$items.each(function() {
							toApplyOnAnchor = false;
							$item = $(this);					
							$.each(settings.anchorItems, function(idx, value) {
								if ($item.attr("class").indexOf(value) !== -1) {
									toApplyOnAnchor = true;
									$anchor = $item.children(":first");
									return false;	
								}
							});
							if (!toApplyOnAnchor) {
								$item.css(cssProp,newHeight);
							} else {
								$anchor.css(cssProp,newHeight);	
							}
						});
					}
				}
			}
		}
	});
};
/***************************************************/
// plugin: toggleShowHide
//
// Developped by: Son Pham
//
// version 1.0 (oct. 2010)
// version 2.0 (mar 25, 2011 support displayType, Themes, custom show and hide className, + page Render)
//
// description: Toggles the Show / Hide the anchor link 
//
//              Note: if you do not want the toggle behavior, please see toRemove() and toShow()
// 
// requirement: 1) jQuery 1.3.2+
//              2) $.isIE()
//				3) $.hasLayout()
//				4) $.getJsClassName()
//				5) $.getTheme()
//
// usage:   1) $(".selector").toggleShowHide()
//
// Note: if you want to toggle the text use the following rule:
//       rel value must match the toggle text you want in the anchor link text
//       <a href="#content" rel="show/hide">show/hide options</a>
//
// params : 
//  @slide: (boolean) indicate if slide effect is applied  default: true (note: slide is not supported on IE)
//  @display: (boolean) indicates whenever visibility is on display or visibility default: display        
//	@showClassName: (string): css ClassName for Open state default: ""
//	@hideClassName: (string): css ClassName for Hide state default: ""
/**********************************************************/
jQuery.fn.toggleShowHide = function(settings) {
    var validateParams, bindClickEvent, runExternalProcess, elements = this,
	selector = this.selector, theme;
    settings = $.extend(false, $.toggleShowHide.defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.slide) !== "boolean") {
            settings.slide = false;
        }
        if (typeof(settings.display) !== "boolean") {
            settings.display = true;
        }		
        if (typeof(settings.showClassName) !== "string") {
            settings.showClassName = "";
        }
        if (typeof(settings.hideClassName) !== "string") {
            settings.hideClassName = "";
        }
    };

    bindClickEvent = function() {
		elements.unbind("click").bind("click", function() {
            var $element = $(this),
                $content = [], contentId,
                href = $element.attr("href"),
                rev = $element.attr("rev"),
                isInPage = true;
				
            if (href) {
                if (href.substr(0,1) !== "#") { 
                    if (rev) {
                        isInPage = false;
                        contentId = rev;
                    } else if (href.indexOf("#") !== -1) {
                        contentId = href.split("#")[1];
                    } 
                } else {
                    contentId = href.split("#")[1];
                }
                if (contentId && contentId !== "") {
                    $content = $("#"+contentId);
                }
                
                if ($content.length) {
                    if (!isInPage && !$.data($element.get(0),"loaded")) {
                        $.ajaxLoader.show();
                        $.ajax({
                            url: href,
							dataType: "html",
                            success: function(data) {
                                $.ajaxLoader.hide();                                    
                                $content.html(data);
								$(selector,$content).toggleShowHide();
                                $.toggleShowHide.animateText($element, $content);
                                $.data($element.get(0),"loaded",settings);
								if (typeof $.bell === "object") {
									if (typeof $.bell.page === "object") {
										if ($.isFunction($.bell.page.render)) {
											$.bell.page.render($content);
										}
									}
								}
                            },
                            error: function() {
                                $.ajaxLoader.hide();
                                var defErrorText = "Error";
                                if ($.isFunction($.getText)) {
                                    $content.html($.getText("error"));
                                } else {
                                    $content.html(defErrorText);
                                }
                                $.data($element.get(0),"loaded",true);                                  
                            }
                        });
                    } else {
                        $.toggleShowHide.animateText($element, $content);
                    }
                    runExternalProcess($content);
                }
            }
            
            return false;
        });
        
        // Third-Party optional process
        runExternalProcess = function($content) {
            if (typeof $.bell === "object") {
				if ($.bell.external) {
					if ($.isFunction($.bell.external.tracker)) {
						if ($content.parents(".detailPanel:first").length) {
							$.bell.external.tracker({
								appName: "lp",
								data: {
									componentName: "PromotionDetails"
								}
							});
						}
					}
				}
			}
		};
    };

    return this.each(function(idx){
        var $element = $(this),
            $content, widgetClassName, customCSS,
            isInPage = true, elementSettings = {},
            href = $element.attr("href");


        // validateParams
        if (idx ===0) { validateParams(); }
		
		// custom CSS?
		customCSS = $.trim(settings.showClassName) === ""?false:true;

        if (href) {
            if (href.substr(0,1) !== "#") { isInPage = false; }

            $content = $.toggleShowHide.getContent($element);

            if ($content.length) {
                widgetClassName = "";
                if ($.isFunction($.getJsClassName)) {
                    widgetClassName = $.getJsClassName($element);
                    $element.addClass(widgetClassName).addClass(settings.hideClassName);
                    
					theme = $.getTheme(widgetClassName, $element.attr("class"));

                    // default state opened?closed
                    if (theme !== "") {
						if (customCSS) {
							if (!$element.hasClass(settings.showClassName)) {
								$.toggleShowHide.toggleDisplay($content,settings.display);
							}
						} else if (!$element.hasClass(theme+"Open")) {
							$.toggleShowHide.toggleDisplay($content,settings.display);
						}
					} else if (!$element.hasClass(widgetClassName+"Open")) {
						$.toggleShowHide.toggleDisplay($content,settings.display);
                    } else if (!isInPage) {
                        $.ajaxLoader.show();
                        $.ajax({
                            url: href,
							dataType: "html",
                            success: function(data) {
                                $.ajaxLoader.hide();                                    
                                $content.html(data);
                                $(selector, $content).toggleShowHide();
                                $.data($element.get(0),"loaded",true);
								if (typeof $.bell === "object") {
									if (typeof $.bell.page === "object") {
										if ($.isFunction($.bell.page.render)) {
											$.bell.page.render($content);
										}
									}
								}								
                            },
                            error: function() {
                                $.ajaxLoader.hide();
                                var defErrorText = "Error";
                                if ($.isFunction($.getText)) {
                                    $content.html($.getText("error"));
                                } else {
                                    $content.html(defErrorText);
                                }
                                $.data($element.get(0),"loaded",true);                                  
                            }
                        });
                    }
				}
				                
				elementSettings = $.extend(false, elementSettings, settings);				
                elementSettings.widgetClassName = widgetClassName;
				elementSettings.customCSS = customCSS;
				elementSettings.theme = theme;
				
                // Toggle text handling
                if (!$.data($element.get(0),"settings")) {
                    $element.attr("title", $element.text());
                    if ($.toggleShowHide.toToggleText($element)) {
                        $.toggleShowHide.toggleText(-1,$element);
						if (theme !== "") {
							if ($element.hasClass(theme+"Open") || $element.hasClass(settings.showClassName)) {
								$.toggleShowHide.toggleText(1,$element);	
							}
						}if ($element.hasClass(widgetClassName+"Open") || $element.hasClass(settings.showClassName)){
                            $.toggleShowHide.toggleText(1,$element); 
                        }
                    }
                    $.data($element.get(0),"settings",elementSettings);
                }

                if (idx===0) { bindClickEvent(); }
            }
        }
    });
};
jQuery.toggleShowHide = {
    defaults : {
        slide: true
    },
    update: function(params) {
        var $link, settings, $content, defaults,
            goodIE = $.isIE(">8");
        
        if (typeof(params) === "object") {
            // defaults are there for security only
            defaults = {
                linkElement: [],
                ajax: false,
                inPage: true,
                text: false,                
                url: "",
                targetId: "",
                content: ""
            };
            
            params = $.extend(false,defaults,params);
            
            $link = $(params.linkElement);
            
            if ($link.length) {
                settings = $.data($link.get(0),"settings");             
                if (settings) {
                    settings = $.extend(false,params,settings);
                    $content = this.getContent($link);
                    
                    $.removeData($link.get(0),"loaded");
                    
                    if (settings.ajax) {
                        $link.attr("rev", $content.attr("id"));
                        $link.attr("href",settings.url);
                    }else if (settings.inPage) {
                        $link.attr("href","#"+settings.targetId);
                    }

                    if ($content.length) {
                        if (settings.display) {
							if ((settings.slide && !$.isIE()) || (settings.slide && goodIE)) {
								$content.animate({opacity:0},100).slideUp(function() {
									$content.empty();                                                  
								});
							} else {
								$content.hide().empty();
							}
						} else {
							$content.css("visibility","hidden");
						}
                        if ($link.hasClass("tglActiveJs")) {
                            $link.removeClass("tglActiveJs");
                            if (typeof settings.theme === "string" && settings.theme.length) {
								$link.removeClass(settings.theme+"Open").removeClass(settings.showClassName).addClass(settings.hideClassName);
							} else if (settings.widgetClassName !== "") {
                                $link.removeClass(settings.widgetClassName+"Open").removeClass(settings.showClassName).addClass(settings.hideClassName);
                            }
                        }
                        this.toggleText(0,$link);                       
                        
                        if (settings.text) {
                            $content.html(settings.content);    
                        }
                    }
                }
            }
        }
    },
    getContent: function(linkElement) {
        var $link = $(linkElement),
            href = $link.attr("href"),
            rev =  $link.attr("rev"), contentId,
            $content = [];
            
        if ($link.length) {
            if (href) {
                if (href.substr(0,1) !== "#") { 
                    if (rev) {
                        contentId = rev;
                    } else if (href.indexOf("#") !== -1) {
                        contentId = href.split("#")[1];
                    } 
                } else {
                    contentId = href.split("#")[1];
                }
                if (contentId && contentId !== "") {
                    $content = $("#"+contentId);
                }
            }
        }
        return $content;
    },
    toToggleText: function(element) { // find toggle text
        var $element = $(element),
            str = $element.attr("title"),
            rel = $element.attr("rel"),
            toggleTextFounded = false;
            
        if (str.indexOf(rel) !== -1) {
            toggleTextFounded = true;
        }
        return toggleTextFounded;
    },
    replaceText: function(searchText, newText, element) {
        var $element = $(element);
        $element.html($element.html().replace(searchText, newText));
    },
	toggleDisplay: function($content, display) {
		if (display) {
			$content.hide();
		} else {
			$content.css("visibility","hidden");
		}
	},
    toggleText: function(showState,element) {
        var $element = $(element),
            rel, originaltext,
            arrRel, text;
        
        if (this.toToggleText($element)) {
            rel = $element.attr("rel");
            originaltext = $element.attr("title");

            if (rel !== "") {
                if (rel.indexOf("/") !== 0) {
                    arrRel = rel.split("/");
                    
                    if (arrRel.length) {
                        switch(showState) {
                            case -1: // initial state
                                text = originaltext.replace(arrRel[1], arrRel[0]);
                                text = text.replace(arrRel[0]+"/","");
                                this.replaceText(originaltext, text, $element);
                                break;
                            case 0: // Show state
                                
                                text = originaltext.replace(arrRel[showState+1], arrRel[showState]);    
                                text = text.replace(arrRel[showState]+"/","");
                                this.replaceText($element.text(), text,  $element);
                                $element.removeClass("tglActiveJs");
                                break;
                            case 1: // Hide state
                                text = originaltext.replace(arrRel[showState-1], arrRel[showState]);    
                                text = text.replace("/"+arrRel[showState],"");
                                this.replaceText($element.text(), text,  $element);                         
                                $element.addClass("tglActiveJs");
                                break;
                        }
                    }
                }
            }
        }
    },
    animateText: function($element, $content) {
        var widgetClassName = "",
            settings = $.data($element.get(0),"settings"),
            isIE = $.isIE(), goodIE = $.isIE(">8"),
			customCSS = settings.customCSS;

        if (!settings) { 
            settings = this.defaults;
            $.data($element.get(0),"settings", settings);
        }
        
        if ($.isFunction($.getJsClassName)) {
            widgetClassName = $.getJsClassName($element);
            $element.addClass(widgetClassName).addClass(settings.hideClassName);

            // default state opened?closed
            if (typeof settings.theme === "string" && settings.theme.length) {
				if (customCSS) {
					if (!$element.hasClass(settings.showClassName)) {
						$.toggleShowHide.toggleDisplay($content,settings.display);	
					}
				} else if (!$element.hasClass(settings.theme+"Open")) {
					$.toggleShowHide.toggleDisplay($content,settings.display);
				}
				$element.toggleClass(settings.theme+"Open");
				if ($element.hasClass(settings.showClassName)) {
					$element.removeClass(settings.showClassName).addClass(settings.hideClassName);
				} else {
					$element.removeClass(settings.hideClassName).addClass(settings.showClassName);					
				}
				    
			} else if (widgetClassName !== "") {
				if (customCSS) {
					if (!$element.hasClass(settings.showClassName)) {
						$.toggleShowHide.toggleDisplay($content,settings.display);					
					}
				} else if (!$element.hasClass(widgetClassName+"Open")) {
					$.toggleShowHide.toggleDisplay($content,settings.display);
				}
				$element.toggleClass(widgetClassName+"Open");
				if ($element.hasClass(settings.showClassName)) {
					$element.removeClass(settings.showClassName).addClass(settings.hideClassName);
				} else {
					$element.removeClass(settings.hideClassName).addClass(settings.showClassName);					
				}
			}           
        }

        if (!$content.is(":visible") || $content.css("visibility") === "hidden") {
			if (settings.display) {
				if ((settings.slide && !$.isIE()) || (settings.slide && goodIE)) {
					$content.css("opacity",0).slideDown(function() {
						$content.animate({opacity:1},"fast");
					});
				} else {
					$content.css("opacity",1).show();
					if (isIE) { 
						$.removeInlineCSSProp($content, "filter");
						$.hasLayout($content);                  
					}
				}
			} else {
				$content.css("visibility","visible");
			}
        } else {
            if (settings.display) {
				if ((settings.slide && !$.isIE()) || (settings.slide && goodIE)) {
					$content.animate({opacity:0},100).slideUp();
				} else {            
					$content.hide();
					if (isIE) { 
						$.removeInlineCSSProp($content, "filter");                  
						$.hasLayout($content);
					}
				}
			} else {
				$content.css("visibility","hidden");		
			}
        }
        $.hasLayout($content);

        this.toggleText($element.hasClass("tglActiveJs")?0:1,$element);
    }
};
/***************************************************/
// plugin: formatPrice
//
// Developped by: Son Pham
//
// description: Takes a given price value e.g $14.95 and
//              sets the appropriate HTML markup and class
//              to it
// 
// requirement: jQuery 1.3.2 
//              original price format MUST BE: $12.95/12,95 $/40/40 
//
// usage:   1) $(".selector").formatPrice({params})
//
// params : 
//  @htmlTag: (string) html tag wrapping the pricing format  default: span
//  @className: (string) css className that will be placed in the html tag default: superscript
/**********************************************************/
jQuery.fn.formatPrice = function(settings) {
    var defaults, validateParams;
    
    defaults = {
        htmlTag: "span",
        className: "superscript"
    };
    settings = $.extend(defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.htmlTag) !== "string") {
            settings.htmlTag = "span";
        }
        if (typeof(settings.className) !== "string") {
            settings.className = "superscript";
        }
    };

    return this.each(function(idx){
        var $element = $(this),
            str, dollarPosition,
            cents, centsPosition, i,
            dollarHasBeenFormatted;
        
        //validateParams
        if (idx ===0) { validateParams(); }
        
        str = $.trim($element.text());
        
        dollarPosition = str.indexOf("$");
        if (dollarPosition !== -1) {
            // Detect FR/EN format
            if (dollarPosition === 0) {
                // EN format e.g $23.95
                for (i=0;i<str.length;i++) {
                    if (str.substr(dollarPosition+1, i).indexOf(".") !== -1) {
                        cents = $.trim(str.substr(dollarPosition+1+i,2));
                        if (!isNaN(cents) && (cents.length>0)) {
                            cents = str.substr(dollarPosition+i,3);
                            // Replace cents with HTML markup
                            centsPosition = $element.html().indexOf(cents);
                            if (!isNaN($element.html().substr(centsPosition-1, 1))) {
                                $element.html($element.html().replace(cents,"<"+settings.htmlTag+" class='"+settings.className+"'>"+cents+"</"+settings.htmlTag+">"));
                            }
                        }
                        break;
                    }
                }
            } else {
                // FR 
                // format 1) 23,95 $  (with space between cents and $)              
                // format 2) 23.95$ / 23,95$
                
                // Format 1)
                cents = str.substr(dollarPosition-4, 3);
                if (cents.indexOf(",") === 0) {
                    // Replace cents with HTML markup
                    centsPosition = $element.html().indexOf(cents);
                    if (!isNaN($element.html().substr(centsPosition-1, 1))) {
                        $element.html($element.html().replace(cents,"<"+settings.htmlTag+" class='"+settings.className+"'>"+cents+"</"+settings.htmlTag+">"));
                    }
                } else {
                    // Format 2)
                    cents = str.substr(dollarPosition-3, 3);
                    if (cents.indexOf(".") !== -1 || cents.indexOf(",") !== -1) {
                        // Replace cents with HTML markup
                        centsPosition = $element.html().indexOf(cents);
                        if (!isNaN($element.html().substr(centsPosition-1, 1))) {
                            $element.html($element.html().replace(cents,"<"+settings.htmlTag+" class='"+settings.className+"'>"+cents+"</"+settings.htmlTag+">"));
                        }
                    }
                }
            }
            // Replace $ sign with HTML markup
            dollarHasBeenFormatted = false;
            $element.find("."+settings.className).each(function() {
                if ($(this).text()==="$") {
                    dollarHasBeenFormatted = true;
                    return false;
                }
            });
            
            if (!dollarHasBeenFormatted) {
                $element.html($element.html().replace("$","<"+settings.htmlTag+" class='"+settings.className+"'>$</"+settings.htmlTag+">"));
            }
        } else {
            centsPosition = str.search(new RegExp("\u00A2"));
            if (centsPosition !== -1) {
                cents = str.substr(centsPosition-1, 1);

                // Replace  sign with HTML markup
                dollarHasBeenFormatted = false;
                $element.find("."+settings.className).each(function() {
                    if ($.trim($(this).html())==="\u00A2") {
                        dollarHasBeenFormatted = true;
                        return false;
                    }
                });
                
                if (!dollarHasBeenFormatted) {                  
                    $element.html($element.html().replace("\u00A2","<"+settings.htmlTag+" class='"+settings.className+"'>&#162;</"+settings.htmlTag+">"));
                }
            }
        }
    });
};
/***************************************************/
// plugin: toRemove TODO: add cookie capabilities
//
// Developped by: Son Pham
//
// description: similar to toggleShowHide but this fn hides the element
//              in addition, this plugin adds the cookie capability (not yet implemented)
// 
//              see: toShow()
//
// requirement: 1) jQuery 1.3.2+
//              2) $.isIE()
//
// usage:   1) $(".selector").toRemove({params})
//          exemple <a href="#id_of_content_to_remove" class="removeJs">Remove</a>
//
// params : 
//  @fade: (boolean) enables fade out effect default: true
//  @speed: (integer) slideUp speed default: 500
//  @cookie: (boolean) enabled the cookie support  default: false
//  @cookieName: (string) if cookie option is enabled set the cookie Name default: [name_of_element]
//  @cookieExpire: (int) cookie's life cycle in number of days default: 30
/**********************************************************/
jQuery.fn.toRemove = function(settings) {
    settings = $.extend(false, $.toRemove.defaults, settings);

    // Validate Params
    var validateParams = function() {
        if (typeof(settings.fade) !== "boolean") {
            settings.fade = false;
        }
        if (isNaN(settings.speed)) {
            settings.speed = 500;
        }           
        if (typeof(settings.cookie) !== "boolean") {
            settings.cookie = false;
        }
        if (typeof(settings.cookieName) !== "string") {
            settings.cookieName = "random_unique_QWERTY";
        }
        if (isNaN(settings.cookieExpire)) {
            settings.cookieExpire = 30;
        }

    };

    return this.each(function(idx){
        //validateParams
        if (idx ===0) { 
            validateParams(); 

            this.live("click", function() {
                $.toRemove.remove($(this), settings);
                return false;
            });
        }
    });
};
jQuery.toRemove = {
    defaults: {
        fade: true,
        speed: 500,
        cookie: false,
        cookieName: "random_unique_QWERTY",
        cookieExpire: 30
    },
    remove: function(element, settings) {
        if (typeof(settings) === "undefined") {
            settings = this.defaults;   
        }
        
        var $element = $(element),
            linkUrl, contentId,
            $content, isIE = false;         
            
        if ($element.attr("href")) {
            linkUrl = $element.attr("href");
            if (linkUrl.length > 1 && linkUrl.indexOf("#") !== -1) {
                contentId = linkUrl.split("#")[1];
    
                $content = $("#"+contentId);
                if (settings.fade) {
                    if ($.isFunction($.isIE)) {
                        isIE = $.isIE("<9");
                    }
                    if (!isIE) {
                        $content.animate({opacity:0},function() { 
                            $(this).slideUp(settings.speed, function() {
                                $(this).hide();                      
                            }); 
                        });
                    } else {
                        // opacity problem with IE < 9
                        $content.fadeOut(settings.speed);
                    }
                } else {
                    $content.hide();
                }
            }
        }   
    }
};
/***************************************************/
// plugin: toShow
//
// Developped by: Son Pham
//
// description: Applies to link <a href='#myId'>.  When clicking on
//              the link, the link will search for the anchor specify by the
//              attribute href.  If founded it will show
//
//              see: toRemove()
// 
// requirement: jQuery 1.3.2 
//
// usage:   1) $(".selector").toShow({params})
//          exemple <a href="#id_of_content_to_show" class="showJs">Show</a>
//
// params : 
//  @fade: (boolean) enables fade in effect default: true
//  @speed: (integer) slideDown speed default: 500
/**********************************************************/
jQuery.fn.toShow = function(settings) {
    var defaults, validateParams;
    
    defaults = {
        fade: true,
        speed: 500
    };
    settings = $.extend(defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.fade) !== "boolean") {
            settings.fade = false;
        }
        if (isNaN(settings.speed)) {
            settings.speed = 500;
        }           
    };

    return this.each(function(idx){
        var $element = $(this),
            linkUrl, contentId;
        
        if ($element.attr("href")) {
            linkUrl = $(this).attr("href");
            if (linkUrl.length > 1 && linkUrl.indexOf("#") !== -1) {
                contentId = linkUrl.split("#")[1];

                //validateParams
                if (idx ===0) { validateParams(); }
    
                $element.unbind("click").click(function() {
                    var $content = $("#"+contentId);
                    if (settings.fade) {
                        $content.fadeIn();
                    } else {
                        $content.show();
                    }
                    return false;                       
                });
            }
        }
    });
};
/***************************************************/
// plugin: toolTip
//
// Developped by: Son Pham
//
// version: 1.0 (nov 2009)
// version: 1.1 (oct 15, 2010) touch support
// version: 1.5 (dec 22, 2010) theme support
//
// description: similar to toggleShowHide but this function
//              adds the toolTip logic that will insert the
//              tip arrow according to the user window dimension
// 
// requirement: 1) jQuery 1.3.2+
//				2) $.detect()
//
// usage:   1) $(".selector").toolTip({params})
//
// params : 
//  @fade: (boolean) enables fade out effect default: true
//  @follow: (boolean) enables toolTip to follow mouse default: true
//  @enableClick: (boolean) enables the click event default: true
//  @unToolTip: (boolean) will remove the toolTip functionality default: false
//  @offsetX: (integer) sets the offset X of the toolTip default: 0 (note in use for now)
//  @offsetY: (integer) sets the offset Y of the toolTip default: 15
//  @minWidth: (integer) sets the minimum widht in px of the toolTip default: 
//  @maxWidth: (integer) sets the maximum widht in px of the toolTip default: 300
//  @containerId: (string) html element Id containing the toolTip content default: "toolTip"
//  @arrowId: (string) html element Id of the toolTip arrow default: "toolTipArrow"
/**********************************************************/
jQuery.fn.toolTip = function(settings) {
    var defaults, isHTML, validateParams, setPosition, hide,
		extractTheme;
    
    defaults = {
        fade: true,
        follow: true,
        enableClick: true,
        unToolTip: false,
        offSetX: 0,
        offSetY: 15,
        minWidth: 200,  
        maxWidth: 300,
        containerId: "bell-toolTip",
        arrowId: "toolTipArrow"
    };
    settings = $.extend(defaults, settings);

    isHTML = false;

    // Validate Params
    validateParams = function() {
        if (typeof(settings.fade) !== "boolean") {
            settings.fade = true;
        }
        if (typeof(settings.follow) !== "boolean") {
            settings.follow = true;
        }
        if (typeof(settings.enableClick) !== "boolean") {
            settings.enableClick = true;
        }
        if (typeof(settings.unToolTip) !== "boolean") {
            settings.unToolTip = false;
        }
        if (isNaN(settings.offSetX)) {
            settings.offSetX = 0;
        }
        if (isNaN(settings.offSetY)) {
            settings.offSetY = 15;
        }
        if (isNaN(settings.minWidth)) {
            settings.minWidth = 200;
        }
        if (isNaN(settings.maxWidth)) {
            settings.maxWidth = 300;
        }
        if (typeof(settings.containerId) !== "string") {
            settings.containerId = "toolTip";
        }
        if (typeof(settings.arrowId) !== "string") {
            settings.arrowId = "toolTipArrow";
        }           
    };

    // Position the toolTip
    setPosition = function(e) {
        var top, left, arrowLeft,
            $toolTip = $("#"+settings.containerId),
            $arrow = $("#"+settings.arrowId),
            toolTipH = $toolTip.outerHeight(),
            toolTipW = $toolTip.outerWidth(),
            arrowH = parseInt($arrow.css("height"),10),
            arrowW = parseInt($arrow.css("width"),10),
            arrowPositionRatio = toolTipW/4,
            winW = $(window).width(),
            toolTipPosition, reverseLeft;
        
        if ($toolTip.length) {
            top = e.pageY-settings.offSetY-toolTipH-arrowH;
            left = e.pageX - arrowPositionRatio;
            arrowLeft = arrowPositionRatio-(arrowW/2);

            // Pre-compute ToolTip position including width etc...
            toolTipPosition = left + toolTipW;

			if (top < 0) {
				top = arrowH+toolTipH+settings.offSetY;	
			}

            if (toolTipPosition > winW) {
                // We know the toolTip will bust the window
                // now we will prevent it
                    
                // reverse left position of toolTip to the right
                reverseLeft = left-toolTipW*0.75+arrowPositionRatio-(arrowW/2)-8;
                $toolTip.css("top",top+"px").css("left",reverseLeft+"px");
                
                if ($arrow.length) {
                    $arrow.css("left",arrowPositionRatio*3+10+"px");
                }
            } else {
                $toolTip.css("top",top+"px").css("left",left+"px");
                
                if ($arrow.length) {
                    $arrow.css("left",arrowLeft+"px");                                                  
                }
            }
        }
    };
	
	hide = function($element) {
		var element = $element.get(0), $toolTip,
			toolTipTitle = $.data(element,"bellToolTip");
		
		if (toolTipTitle) {
			element.title = toolTipTitle;
		}
		$toolTip = $("#"+settings.containerId);

		if (settings.fade) {
			$toolTip.stop().fadeOut("fast", function() {
				$(this).remove();                                 
			});
		} else {
			$toolTip.remove();
		}	
	};

	extractTheme = function(arrClass) {
		var theme = "Theme", arrTheme;
			
		$.each(arrClass, function(idx, value) {
			if (value.indexOf("Theme") !== -1) {
				arrTheme = arrClass[idx].split("Theme");
				if (arrTheme.length > 1) {
					theme += arrTheme[1];
				}
			}
		});			
		return "toolTip"+theme;
	};

    return this.each(function(idx){
        var $element = $(this),
            txt, contentId, $content,
            $toolTip, html, $arrow, theme;
            
        // validateParams
        if (idx ===0) { validateParams(); }
        
		// themes support
		theme = extractTheme($element.attr("class").split(" "));
		
        if (!settings.unToolTip) {
            if (!$.data($element.get(0),"initialized")) {
                if (!settings.enableClick) {
                    // preventDefault action
                    $element.click(function() {
                        return false;
                    });
                }
                
                // Set hover action
                $element.mouseover(function(e){
					var closeHTML = "", isTouchDevice = $.detect.touch();
					
                    // Get Text
                    $.data($element.get(0),"bellToolTip", this.title);
        
                    // Trying to detect if toolTip content's from title or HTML
                    contentId = "";
                    try {
                        contentId = $(this).attr("href").split("#")[1];
                    } catch(ex) {}
                    
                    if (contentId !== "") {
                        isHTML = true;
                        $content = $("#"+contentId);
                        if ($content.length) {
                            txt = $content.html();
                        }
                    }
                    if (!txt || txt === "" || typeof(txt) == "undefined") {
                        txt = this.title;
                        isHTML = false;
                    }
                    
                    // Create ToolTip if only text exists
                    if (txt !== "" && txt) {
                        txt = $.trim(txt);
                        if (txt !== "") { 
                            // Temporary remove title because we don't want to show the browser's
                            // native toolTip behavior
                            this.title = "";
                        
                            // hide previous tooltip
                            $("#"+settings.containerId).remove();
                            
							// Touch devices
							if (isTouchDevice) {
								closeHTML = "<a href='#"+settings.containerId+"' class='bt_remove'>"+$.getText("actionClose")+"</a>";
							}
							
                            $toolTip = $("<div id='"+settings.containerId+"' class='toolTip "+theme+"'></div>");
                            
                            html = "";
                            html += "   <div class='toolTipBordRight'>\n";
                            html += "       <div class='toolTipBordLeft'>\n";
                            html += "           <div class='lining'>\n";
                            html += closeHTML;
							html += txt;
                            html += "           <\/div>\n";
                            html += "       <\/div>\n";
                            html += "   <\/div>\n";
                            html += "   <div class='toolTipTopRight'><div class='toolTipTopLeft'><\/div><\/div>\n";
                            html += "   <div class='toolTipBottomRight'>\n";
                            html += "       <div class='toolTipBottomLeft'>\n";
                            html += "       <\/div>\n";
                            html += "   <\/div>\n";
                            html += "   <div id='"+settings.arrowId+"' class='toolTipArrow'><\/div>\n";

                            $toolTip.append(html);
                            $toolTip.appendTo("body");
                            
                            $arrow = $("#"+settings.arrowId);
                
                            // set minWidth/maxWidth if applicable
                            if ($toolTip.width() > settings.maxWidth) {
                                $toolTip.css("width",settings.maxWidth + "px");
                            } else if ($toolTip.width() < settings.minWidth) {
                                $toolTip.css("width",settings.minWidth + "px");                         
                            }
        
                            // IE PNG check
                            if ($.isIE("<9")) {
                                if ($toolTip.css("backgroundImage").indexOf(".png") !== -1 || $arrow.css("backgroundImage").indexOf(".png") !== -1) {
                                    settings.fade = false;
                                }
                            }
							
							// Touch device
							if (isTouchDevice) {
								$toolTip.find(".bt_remove:first").click(function() {
									hide($toolTip);
									return false;
								});
							}
							
                            // Position toolTip
                            setPosition(e);
                            
                            // Show toolTip
                            if (settings.fade) {
                                $toolTip.stop().fadeIn("fast");
                            } else {
                                $toolTip.show();
                            }
                        }
                    }
                }).mouseout(function(){
					hide($element);
                });
                if (settings.follow) {
                    $element.mousemove(function(e){
                        // Position toolTip
                        setPosition(e);
                    });
                }
                $.data($element.get(0),"initialized", true);
            }
        } else {
            // UnToolTip
            $element.unbind("mouseover").unbind("mouseout");
            $.removeData($element.get(0),"toolTipInitialized");
        }
    });
};
/***************************************************/
// plugin: Carousel
//
// Developped by: Son Pham
//
// version 1.0 (novembre 2009)
// version 1.5 (february 2011: support for non images only for BCE)
//
// description: Carousel based on links vs images
// 
// requirement: jQuery 1.3.2+ 
//
// usage:   1) $(".selector").carousel({params})
//
// params : 
//  @autoPlay: (boolean) enables the caroursel to start automatically default: false
//  @timer: (integer) sets the interval in seconds between each media (autoPlay must be set to True)  default: 5
//  @slide: (boolean) enables the caroursel to slide between the media changes default: true
//  @speed: (integer) the animation speed default: 300
//  @navInside: (boolean) set if the navigation should be outside the carousel or part of the media zone default: true
//  @navCenter: (boolean) set if the navigation should be centered to the carousel default: true
//  @navShow: (boolean) set if the navigation should be displayed default: true
//  @mediaContainer: (string) className of the element containing the media files  default: "mediaContainer"
//  @navContainer: (string) className of the element containing the carousel navigation  default: "carouselNav"
//  @activeClassName: (string) className that will be use on the navigation when its active  default: "active"
/**********************************************************/
jQuery.fn.carousel = function(settings) {
    var defaults, timerId, validateParams, loadMedias, 
        setDimension, setMediaDimension, show, playShow, play;
    
    defaults = {
        autoPlay: false,
        timer: 5, // in seconds
        slide: false,
        speed: 300,
        navInside: false,
        navCenter: true,
        navShow: true,
        navContainer: "carouselNav",
        mediaContainer: "carouselMedia",
        activeClassName: "active"
    };
    settings = $.extend(defaults, settings);

    timerId = 0;

    // Validate Params
    validateParams = function() {
        if (typeof(settings.autoPlay) !== "boolean") {
            settings.autoPlay = false;
        }
        if (isNaN(settings.timer)) {
            settings.timer = 5;
        }
        if (typeof(settings.slide) !== "boolean") {
            settings.slide = false;
        }
        if (isNaN(settings.speed)) {
            settings.speed = 300;
        }
        if (typeof(settings.navInside) !== "boolean") {
            settings.navInside = false;
        }
        if (typeof(settings.navCenter) !== "boolean") {
            settings.navCenter = true;
        }
        if (typeof(settings.navShow) !== "boolean") {
            settings.navShow = true;
        }
        if (typeof(settings.navContainer) !== "string") {
            settings.navContainer = "carouselNav";
        }
        if (typeof(settings.mediaContainer) !== "string") {
            settings.mediaContainer = "carouselMedia";
        }
        if (typeof(settings.activeClassName) !== "string") {
            settings.activeClassName = "active";
        }
    };

    // set images width/height by loading the images
    loadMedias = function($carouselImages) {
        if ($.isFunction($.loadImages)) { 
            $carouselImages.each(function() {
                var $image = $(this),
                    $link, toHide;

                if ($image.attr("id") === "") {
					if ($image.parent().attr("id")) {
						if (document.getElementById($image.parent().attr("id")).nodeName === "A") {
							$link = $($image.parent());
							toHide = false;
							
							if (!$link.is(":visible")) {
								toHide = true;
								$link.show();
							}
							return function() {
								$.loadImages($("img", $link));
								if (toHide) { $link.hide(); }
							};
						}
                    }
                } else {
                    return function() { $.loadImages($image); };
                }           
            });
        }
    };

	// set carousel media dimension when it's a complex structure other than only images
	// this is very specific to BCE therfore may not work for other situation
	setMediaDimension = function($element) {
		var $links = $element.find("."+settings.navContainer+" a"),
			$media, $mediaImage, mediaH, $mask,
			tallestH = 0, $content;

		// set mask	
		$mask = $element.find("."+settings.mediaContainer+":first");
		$mask.width($element.width());

		$links.each(function(idx) {
			$media = $("#"+$(this).attr("href").split("#")[1]);
			$mediaImage = $media.find("img:first"); 
			mediaH = $mediaImage.height()+parseInt($mediaImage.parent().css("marginTop"),10);
			if (mediaH> tallestH) {
				tallestH = mediaH;
			}
		});
		
		// set component height
		$element.height(tallestH);

		// alignCenter
		$mask.find(".sectionContent").each(function() {
			$content = $(this);
			$content.css("paddingTop",((tallestH-$content.height())/2)+"px");
		});

		$links.each(function(idx) {
			if (idx > 0) {
				$("#"+$(this).attr("href").split("#")[1]).hide();	
			}
		});		
	};

    // set carousel dimension by tallest and widest image
    setDimension = function($element) {
        var tallestH = 0,
            tallestW = 0,
            totalImgW = 0,
            dimension = {
                height: 0,
                width: 0
            }, 
            validData = false,      
            $carouselImages = $element.find("."+settings.mediaContainer+" img"),
            zIndex, $img, imgH, imgW, killOutLine,
            $nav, abortOperation = false;

        // load images
        loadMedias($carouselImages);
        
        zIndex = 0;
        
        $carouselImages.each(function(i) {
            $img = $(this);
            imgH = $img.outerHeight();
            imgW = $img.outerWidth();           
            
            // functionality check
            if (imgH === 0) {
                // somethings wrong !!!
                return false;
            } else {
                validData = true;   
            }
            
            if (imgH > tallestH) {
                tallestH = imgH;
            }
            
            if (imgW > tallestW) {
                tallestW = imgW;
            }
            dimension.height = tallestH;
            dimension.width = tallestW;
            
            totalImgW += imgW;

            if (!$img.attr("id")) {
				if ($img.parent().attr("id")) {
					if (document.getElementById($img.parent().attr("id")).nodeName === "A") {
						$img = $($img.parent());
					}
				} else {
					// more complexe structure we gonna assume it's a non full image scenario with dynamic text
					setMediaDimension($element);
					abortOperation = true;
					return false;
				}
            }

            // always show first
            if (i === 0) { $img.show(); }
            
            if (i === 0 || !settings.slide) {
                $img.css("left", 0);
                if (i > 0 && !settings.slide) {
                    $img.hide();    
                } 
                if (!settings.slide) {
                    $img.css("position","absolute");
                }
            } else {
                $img.css("left", totalImgW-imgW+"px").css("float", "left");
            }
        });

		if (!abortOperation) {
			// functionality check
			if (!validData) {
				// Somethings wrong exit function
				return false;   
			} else {
				// Everything seems to be OK! Now set Mask width
				if (dimension.width) {
					$element.width(dimension.width);    
				}
				
				// Set the media container width
				$element.find("."+settings.mediaContainer).each(function() {
					if (settings.slide) {
						$(this).width(totalImgW);
					} else {
						$(this).width(dimension.width);
					}
				});
				
				killOutLine = false;
				if ($.isFunction($().outLineKiller)) {
					killOutLine = true;
				}
				
				// position navigation
				$element.find("."+settings.navContainer).each(function() {
					$nav = $(this);
					if (settings.navShow) {
						if (settings.navCenter) {
							$nav.css("left", (dimension.width-$nav.width())/2+"px");
						}
						if (killOutLine) {
							$("a",$nav).outLineKiller();
						}
						
						if (dimension.height) {
							if (settings.navInside) {
								$element.height(dimension.height);
								$nav.css("zIndex", zIndex++);   
							} else {
								$element.height(dimension.height+$nav.outerHeight(true));
							}
						}
					} else {
						$nav.hide();
						if (dimension.height) {
							$element.height(dimension.height);
						}
					}
				});
			}
        }
		return true;		
    };

    // Show media
    show = function(element, lnk, arrMedia) {
        var $element = $(element),
            $link = $(lnk),
            imageId,
            $img, $media;
        
        $element.find("."+settings.navContainer+" a").each(function() {
            $(this).removeClass(settings.activeClassName);
        });
        $link.addClass(settings.activeClassName);
                    
        imageId = $link.attr("href").split("#")[1];
        $img = $("#"+imageId);

        if (settings.slide) {
            $element.find("."+settings.mediaContainer).each(function() {
                if ($img.length) {
                    $(this).stop().animate({left: "-"+$img.css("left") }, settings.speed);
                }
            });
        } else {
            $.each(arrMedia, function(idx, value) {
                $media = $(value);
                if ($media.is(":visible") && ($img.attr("id")!==$media.attr("id"))) {
                    if (settings.navInside) {
                        $media.css("bottom",0);
                    }
                    $media.fadeOut(settings.speed, function() {
                        $img.fadeIn(settings.speed);
                    });
                    return false;
                }                                 
            });
        }
    };

    // AutoPlay Show
    playShow = function(element, content, arrMedia, index) {
        var $element = $(element),
            $content = $(content),
            zIndex  = 0, //$.getHighestZIndex(),
            $nav = $element.find("."+settings.navContainer);
        
        $content.css("zIndex", zIndex);
        $content.fadeIn(settings.speed);
        
        if ($nav.length) {
            $nav.css("zIndex", zIndex++);   
        }

        timerId = setTimeout(function() {
            var nextIdx = index+1>arrMedia.length-1? 0 : index+1;
            play($element, arrMedia, nextIdx, false);
        }, settings.timer*1000);
        
    };  

    // on autoPlay mode
    play = function(element, arrMedia, index, isFirstTimeLoad) {
        if (arrMedia.length) {
            var $element = $(element),
                $img = $(arrMedia[index]),
                $media,
                nextIdx, href;
            
            // get media link
            $element.find("a").each(function() {
                href = $(this).attr("href").split("#")[1];
                if (href === $img.attr("id")) {
                    $(this).removeClass(settings.activeClassName).addClass(settings.activeClassName);
                } else {
                    $(this).removeClass(settings.activeClassName);
                }
            });

            if (settings.slide) {
                $element.find("."+settings.mediaContainer).each(function() {
                    $(this).stop().animate({left: "-"+$img.css("left") }, settings.speed,  function() {
                        //interval validation
                        if (isNaN(settings.timer)) {
                            settings.timer = defaults.timer;
                        }
                        timerId = setTimeout(function() {
                            nextIdx = index+1>arrMedia.length-1? 0 : index+1;
                            play($element, arrMedia, nextIdx, false);
                        }, settings.timer*1000);
                    });
                });
            } else {
                $.each(arrMedia, function(idx, value) {
                    $media = $(value);

                    if ($media.is(":visible")) {
                        if (!isFirstTimeLoad) {
                            $media.fadeOut(settings.speed, function() {
                                playShow($element, $img, arrMedia, index);
                            });
                        } else {
                            playShow($element, $img, arrMedia, index);
                        }
                        return false;
                    }                     
                });
            }
        }
    };
    
    return this.each(function(idx){
        var $element = $(this),
            $links, media, $link,
            $content, contentId;

        //validateParams
        if (idx ===0) { validateParams(); }

        // Set Carousel dimension
        if (!$.data($element.get(0),"initialized")) {
            if (setDimension($element)) {           
                // error functionality check
                if (window.carouselTimerId) {
                    clearTimeout(window.carouselTimerId);   
                }
                if (!settings.slide) {
                    $element.css("overflow","visible");
                } 
        
                // find links and initialize it
                $links = $element.find("."+settings.navContainer+" a");
                
                if ($links.length > 1) {
                    // Get media array
                    media = [];
    
                    $links.each(function(i) {
                        $link = $(this);
                        contentId = $link.attr("href").split("#")[1];
                        if (i===0) {
                            $link.addClass(settings.activeClassName);
                        } else {
                            $link.removeClass(settings.activeClassName);                
                        }
                        try {
                            $content = $("#"+contentId);
                            
                            if ($content.length) {
                                if (settings.navInside) {
                                    $content.css("bottom",0);
                                }                       
                                media.push($content);
                            }
                        } catch(e) {}
                        
                        $link.unbind("click").click(function() {
                            show($element, $(this), media);
                            clearTimeout(timerId);
                            return false;
                        });
                    });
                    
                    // autoPlay mode
                    if (settings.autoPlay) {
                        play($element, media, 0, true);
                    }
                } else if ($links.length === 1) {
                    // We only show navigation for at least 2 items
                    $links.hide();
                }
                $.data($element.get(0),"initialized",true);
            } else {
				// re-run carousel call
                window.carouselTimerId = setTimeout(function() {
                    $element.carousel(settings);
                }, 100);
            }
        }
    });
};
/***************************************************/
// plugin: flyOut
//
// Developped by: Son Pham
//
// description: similar to toggleShowHide but this function has two types of Flyout
//              1) with Inputs: after selecting an input, the label of this input will replace
//                 the text of element responsible to trigger the flyOut
//              
//              2) links: after clicking on a link, the link will do its native function wich is
//                 to go to the resource indicated in the attribute href
//
// requirement: jQuery 1.3.2+ 
//
// usage:   1) $(".selector").flyout({params})
//
// params : 
//  @ajax: (boolean) determine if content if from ajax default: false
//  @fade: (boolean) enables fade out effect default: true
//  @inputs: (boolean) indicates that flyout is composed of form inputs default: false
//  @hide: (boolean) indicates that flyout must be hidden default: false
//          normaly used to force the flyout content to be hidden after an external javascript call
//  @generateHtml: (boolean) indicates if the function will generate the flyOut HTML markup default: true
//  @speed: (integer) sets the fading speed (fade must be true) default: 250
//  @className: (string) sets the flyOut ClassName default: "";
//  @itemActiveClassName: (string) used to specify the className of the parent of the element when clicked default "active"
//  @closeTimer: (integer) specifies the timer clock to close the flyout on mouseLeave default: 250
/**********************************************************/
jQuery.fn.flyOut = function(settings) {
    var defaults, mouseOn, validateParams,
        show, hide, startTimer, resetActive,
        setActiveInput, setAlwaysOnTop, generateHTML;
    
    defaults = {
        ajax: false,
        fade: true,
        inputs: false,
        hide: false,
        generateHtml: true, 
        speed: 250,
        className: "",
        itemActiveClassName: "active",
        itemHoverClassName: "hover",
        closeTimer: 250
    };
    settings = $.extend(defaults, settings);

    mouseOn = false;

    // Validate Params
    validateParams = function() {
        if (typeof(settings.ajax) !== "boolean") {
            settings.ajax = false;
        }
        if (typeof(settings.fade) !== "boolean") {
            settings.fade = true;
        }
        if (typeof(settings.inputs) !== "boolean") {
            settings.inputs = true;
        }
        if (typeof(settings.hide) !== "boolean") {
            settings.hide = false;
        }
        if (typeof(settings.generateHtml) !== "boolean") {
            settings.generateHtml = true;
        }
        if (isNaN(settings.speed)) {
            settings.speed = 250;
        }       
        if (typeof(settings.className) !== "string") {
            settings.className = "";
        }               
        if (typeof(settings.contentClassName) !== "string") {
            settings.contentClassName = "flyOut";
        }       
        if (typeof(settings.itemActiveClassName) !== "string") {
            settings.itemActiveClassName = "active";
        }       
        if (isNaN(settings.closeTimer)) {
            settings.closeTimer = 250;
        }       
    };
    
    // show flyOut
    show = function(element) {
        var $element = $(element),
            fromAjax = arguments[1];

        // make sure content will be showned
        $($(".flyOutContJs", $element).children()[0]).show();

        // animate effect       
        if (settings.fade) {
            $element.stop();
            if (fromAjax || $.isIE("<9")) {
                $element.show();
            } else {
                $element.fadeIn(settings.speed);                
            }
        } else {
            $element.show();
        }

        // handling mouse out/leave on element
        $element.mouseover(function() {
            mouseOn = true;
            $element.show();
        }).mouseleave(function() {
            mouseOn = false;
            startTimer($element);
        });
        
        // $.getHighestZIndex()
        $element.css("zIndex", 999999);
    };
    
    // hide flyOut
    hide = function(element) {
        var $element = $(element);
        mouseOn = false;        
        
        if (settings.fade && $.isIE(">8")) {
            $element.fadeOut(settings.speed);
        } else {
            $element.hide();
        }
        
        // IE select always on top fix
        if ($.isIE()) { 
            // remove IE bug overlay links
            $("#"+$element.attr("id")+"-img").remove();
        }       
    };

    // start timer before closing flyOut
    startTimer = function(element) {
        var $element = $(element);      
        window.bellFlyOutTimer = setTimeout(function() {
            clearTimeout(window.bellFlyOutTimer);
            if (!mouseOn) {
                hide($element);
            }
        }, settings.closeTimer);
    };

    resetActive = function(elements) {
        var $elements = $(elements);
        $elements.each(function() {
            $(this).parent().removeClass(settings.itemActiveClassName);                     
        });
    };

    setActiveInput = function(content, text) {
        if (settings.inputs) {
            var $inputs = $(content).find(":input"),
                $parent;
                
            resetActive($inputs);
            $inputs.each(function() {
                $parent = $(this).parent();
                if ($.trim($parent.text())===text) {
                    $parent.addClass(settings.itemActiveClassName); 
                }
            });
        }
    };

    setAlwaysOnTop = function(content) {
        var $content = $(content),
            $img, src;
        
        // IE PNG check (because IE does not like fade effect when PNG is involve)
        if ($.browser.msie) {
            if ($content.css("backgroundImage").indexOf(".png") !== -1) {
                settings.fade = false;
            } else {
                $content.children().each(function() {
                    if ($(this).css("backgroundImage").indexOf(".png") !== -1) {
                        settings.fade = false;
                        return false;
                    }
                });
            }
            
            // IE flyout mouseleave bug fix
            if ($("#"+$content.attr("id")+"-img").length === 0) {
                $img =  $("<img id='"+$content.attr("id")+"-img'></img>");
                $img.addClass("transparent");
                $content.prepend($img);
                
                src = $img.css("backgroundImage").replace("url(","").replace(".png)",".png");
                src = src.substr(0,src.length-1);
                src = src.substr(1,src.length-2);
                $img.attr("src",src);
                $img.css("position", $content.css("position"));
                
                if ($content.css("left") === "auto") {
                    if ($content.css("right") !== "auto") {
                        $img.css("right", $content.css("right"));                               
                    }
                } else {
                    $img.css("left", $content.css("left"));
                }
                $img.css("top", $content.css("top"));
                $img.width($content.width());
                $img.height($content.height());
                
                $img.mouseenter(function() { mouseOn = true; });
            }
        }       
    };

    generateHTML = function(flyOutId) {
        var rand, html;
        
        if (!flyOutId || flyOutId === "" || flyOutId.indexOf("#")!== -1) {
            rand = Math.floor(Math.random()*1000);
            if ($.isFunction($.getRandomNumber)) {
                rand = $.getRandomNumber();
            }
            flyOutId = "bell-flyOut-"+rand;
        } else {
            flyOutId += "-flyOut"; 
        }
        
        html = "";
        html += "<div id='"+flyOutId+"' class='flyOut "+settings.className+"'>\n";
        html += "   <div class='flyOutBordRight'>\n";
        html += "       <div class='flyOutBordLeft'>\n";
        html += "           <div class='lining flyOutContJs'><\/div>\n";
        html += "       </div>\n";
        html += "   <\/div>\n";
        html += "   <div class='flyOutTopRight'><div class='flyOutTopLeft'><\/div><\/div>\n";
        html += "   <div class='flyOutBottomRight'><div class='flyOutBottomLeft'><\/div><\/div>\n";
        html += "<\/div>\n";
        return html;
    };
    
    return this.each(function(idx){
        var $element = $(this),
            contentId = $element.attr("href").split("#")[1],
            $content = $("#"+contentId);

        //validateParams
        if (idx ===0) { 
            validateParams();
            $("body").click(function() {
                hide($content);
            });
        }
        
        if (settings.hide) {
            hide($content);
        } else {
            if ($content.length) { $content.hide(); }
            
            $element.unbind("click").click(function(idx) {
                var $link = $(this),
                    flyOutId, $flyOut, $placeHolder,
                    url, rand, loaderEnabled, toBindEventHandling,
                    $parent, $inputs, strFor, label, $links, currentText;
                
                // indicate that mouse is on
                mouseOn = true;

                // hide previous flyOut
                $("body").find(".flyOut").each(function() {
                    if (!settings.ajax) {
                        flyOutId = $(this).attr("id");
                        if (flyOutId) {
                            if (flyOutId !== contentId+"-flyOut") {
                                $(this).hide(); 
                            }
                        }
                    }
                });
            
                // Set default selected input based on the link text (if applicable)
                setActiveInput($content, $link.text());

                // Content
                if (settings.ajax) { // Ajax
                    url = $link.attr('href');
                    
                    rand = 0;
                    if ($.getRandomNumber) { rand = $.getRandomNumber(); }
                    
                    if (url.indexOf("&") !== -1) {
                        url += "&refreshxyz="+rand;
                    } else if (url.indexOf("?") === -1) { 
                        url += "?refreshxyz="+rand; 
                    }
                    
                    $flyOut = $.data($link.get(0),"flyOut");
                    if (!$flyOut) {
                        $flyOut = $(generateHTML());
                        $link.after($flyOut);
                        $placeHolder = $(".flyOutContJs", $flyOut);
                        
                        loaderEnabled = false;
                        if ($.isFunction($.ajaxLoader.show)) {
                            loaderEnabled = true;
                            $flyOut.show();
                            $placeHolder.addClass("loading");
                            $.ajaxLoader.show({targetId:$placeHolder});
                        }

                        // Loads data synchronously. 
                        // Blocks the browser while the requests is active. 
                        // It is better to block user interaction by other means when synchronization is necessary.
                        $.ajax({
                            url: url,
                            async: false,
                            dataType: "html",
                            success: function(data) {
                                // place new content
                                var $data = $(data);
                                $flyOut.addClass($data.attr("class"));
                                $data.removeClass("class");
                                $placeHolder.prepend(data).removeClass("loading");

                                if (loaderEnabled) {
                                    $.ajaxLoader.hide({targetId:$placeHolder});
                                }
                                
                                show($flyOut, true);

                                // handling mouse out/leave on the link
                                $link.mouseover(function() {
                                    mouseOn = true;
                                }).mouseleave(function() {
                                    mouseOn = false;
                                    startTimer($flyOut);
                                });
                                    
                                // save state
                                $.data($link.get(0),"flyOut", $flyOut);
                            },
                            error: function() {
                                var defErrorText = "Error";
                                if ($.isFunction($.getText)) {
                                    defErrorText = $.getText("error");
                                }
                                /*global alert */
                                alert(defErrorText);
                            }                           
                        });

                    } else {
                        if (!$flyOut.is(":visible")) {
                            show($flyOut);  
                            // handling mouse out/leave on the link
                            $link.mouseover(function() {
                                mouseOn = true;
                            }).mouseleave(function() {
                                mouseOn = false;
                                startTimer($flyOut);
                            });                     
                        } else {
                            hide($flyOut);
                        }
                    }
                } else {  // In Page
                
                    // create new flyOut?
                    toBindEventHandling = false;
                    if (settings.generateHtml) {
                        flyOutId = contentId+"-flyOut";
                        $flyOut = $("#"+flyOutId);
                    } else if ($content.length) {
                        toBindEventHandling = true;
                        $flyOut = $content;
                    }

                    if ($flyOut.length === 0 || toBindEventHandling) {
                        // content handling
                        if ($content.length) {
                        
                            // main element mouseout handling
                            $link.unbind("mouseleave").mouseleave(function() {
                                mouseOn = false;
                                startTimer($flyOut);                                          
                            });
                        
                            if (settings.generateHtml) {
                                $flyOut = $(generateHTML(contentId));
                                $flyOut.addClass($content.attr("class"));
                                $content.removeAttr("class");
                                
                                // move content in flyOut
                                $content.after($flyOut);
                                $content.show();
                                $placeHolder = $(".flyOutContJs", $flyOut);
                                $placeHolder.append($content);
                            } 
                            
                            // transparent layer workaround
                            setAlwaysOnTop($flyOut);

                            if (!$flyOut.is(":visible")) {
                                // Handling flyOut types
                                if (settings.inputs) {
                                    $inputs = $content.find(":input");
                                    $inputs.each(function() {
                                        // Click
                                        $(this).unbind("click").click(function() {
                                            strFor = $(this).attr("id");
                                            resetActive($inputs);
                                            $parent = $(this).parent(); 
                                            $parent.addClass(settings.itemActiveClassName);
                                            label = $parent.find("label[for='"+strFor+"']").text();
                                            $element.text(label);
                                            $flyOut.hide();                             
                                        });
                                        // Mouse hover
                                        $(this).parent().find("label:first").hover(function() {
                                            $(this).addClass(settings.itemHoverClassName);                                     
                                        }, function() {
                                            $(this).removeClass(settings.itemHoverClassName);                                   
                                        });
                                        
                                        if($.browser.msie) {
                                            $(this).parent().find("label:first").unbind("click").click(function() {
                                                resetActive($inputs);
                                                $(this).parent().addClass(settings.itemActiveClassName);
                                                $element.text($(this).text());
                                                $flyOut.hide();
                                            });
                                        }
                                    });
                                } else {
                                    $links = $flyOut.find("a");
                                    $links.each(function() {
                                        $(this).unbind("click").click(function() {
                                            currentText = $element.text();
                                            $element.html($element.html().replace(currentText,$(this).text()));
                                            resetActive($links);
                                            $(this).parent().addClass(settings.itemActiveClassName);                                    
                                            window.location.href = $(this).attr("href");                                    
                                        });
                                    });
                                }
                                show($flyOut);                      
                            } 
                        }
                    } else { // flyOut already generated
                        if (!$flyOut.is(":visible")) {
                            show($flyOut); 
                        } else {
                            hide($flyOut);
                        }
                    }
                }
                return false;                       
            });
        }
    });
};
/***************************************************/
// plugin: tabbing (TODO: rework history manager form IE)
//          (used this name to avoid conflict with jQuery ui $().tabs)
//
// Developped by: Son Pham
//
// version: 1.1 (oct. 15, 2010)
//
// description: handles the tabbing functionalities including
//              ajax (if content is loaded, no call ajax will be used)
//
// requirement: 1) jQuery 1.3.2+
//              2) The following HTML structure must be respected for functionality
//              
//              2.1) Must have a tab links wrapper "linksContainerClassName"
//              2.2) Tabs links must be an <a> element and the href should point to:
//              2.2.1) id of the tab content + "slugContent"
//              2.2.2) url containing the HTML of the tab content
//              2.3) Must have a tab content wrapper containing all the tab contents "contentContainerClassName"
//              2.4) Each tab content MUST have a className "contentClassName"
//
// Note: In order to set the default selected tab please follow these instructions
//       1) put the className "linkActiveClassName" on the the tab link <a> ex: <a class="tabTrigActive"></a>
//       2) put an id on the link e.g <a id="#myTabContent" class="tabTrigActive"></a> the id can be anything
//       3) for the content: set the attribute id equal to the id of the link + slugContent
//          ex: <div id="myTabContent-content" class="tabCont"></div>
//
// usage:   1) $(".selector").tabs({params})
//
// params : 
//  @slugHash: (string) word used for history/bookmarking management  default: "-tabs"
//                  also the the slug is used to extract the ID of the tab content when detected
//  @slugContent: (string) word that will be appended to the element ID of the tab content ID  default: "-content"
//                  also the the slug is used to extract the ID of the tab content when detected
//  @linksContainerClassName: (string) className of the element wrapping the tab links  default: "tabTrigSet"
//  @linkActiveClassName: (string) className of the tab links when it is active default: "tabTrigActive"
//  @contentContainerClassName: (string) className of the wrapper containing the tab contents default: "tabContSet"
//  @contentClassName: (string) className of the tab wrapping the individual content default: "tabCont"
//  @opacity: (integer) the opacity pourcentage default 50
/**********************************************************/
jQuery.fn.tabbing = function(settings) {
    var defaults, validateParams,
        historyManager, show, historyLookUp;
    
    defaults = {
        slugHash: "-tabs",
        slugContent: "-content",
        linksContainerClassName : "tabTrigSet",
        linkActiveClassName : "tabTrigActive",
        contentContainerClassName: "tabContSet",
        contentClassName: "tabCont",
        contentActiveClassName: "tabContActive",
        opacity: 50
    };
    settings = $.extend(defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.slugHash) !== "string") {
            settings.slugHash = "-tabs";
        }
        if (typeof(settings.slugContent) !== "string") {
            settings.slugContent = "-content";
        }
        if (typeof(settings.linksContainerClassName) !== "string") {
            settings.linksContainerClassName = "tabTrigSet";
        }
        if (typeof(settings.linkActiveClassName) !== "string") {
            settings.linkActiveClassName = "tabTrigActive";
        }
        if (typeof(settings.contentContainerClassName) !== "string") {
            settings.contentContainerClassName = "tabContSet";
        }
        if (typeof(settings.contentClassName) !== "string") {
            settings.contentClassName = "tabCont";
        }
        if (typeof(settings.contentActiveClassName) !== "string") {
            settings.contentActiveClassName = "tabContActive";
        }
        if (isNaN(settings.opacity)) {
            settings.opacity = 50;
        }
    };

    // IE history Manager
    historyManager = {
        init: function(element) {
            if($.isIE("<9")) {
                var $iframe = $("#history_manager"),
                    $element, $myGroup, $myTabs, $activeTab, iframe;
                
                if ($iframe.length === 0) {
                    $iframe = $("<iframe id='history_manager' style='display: none;'><\/iframe>");
                    $("body").prepend($iframe);
                    if (window.location.hash.indexOf(settings.slugHash) === -1) {
                        // When no hash in url we have to set initial hash in iframe
                        $element = $(element);
                        $myGroup = $element.find("."+settings.linksContainerClassName);             
                        $myTabs = $myGroup.find('a');
                
                        $activeTab = $myGroup.find("."+settings.linkActiveClassName+":first");
                        iframe = $iframe[0].contentDocument || $iframe[0].contentWindow.document;
                        iframe.open();
                        iframe.close();
                        iframe.location.hash = $activeTab.length > 0? "#"+$($activeTab[0]).attr("id") : "#"+$($myTabs[0]).attr("id");
                    }
                } 
            }
        },
        add : function() {
            var $iframe = $("#history_manager"), iframe;
            
            if ($iframe.length) {
                iframe = $iframe[0].contentDocument || $iframe[0].contentWindow.document;
                iframe.open();
                iframe.close();
                iframe.location.hash = window.location.hash.replace(settings.slugHash,'');
            }
        },
        goTo : function(selector, idLink) {
            var $iframe = $("#history_manager"), iframe;
            
            if ($iframe.length) {
                iframe = $iframe[0].contentDocument || $iframe[0].contentWindow.document;
                
                // We need to avoid multiple call to the show function
                if (window.location.hash.replace(settings.slugHash,'') !== iframe.location.hash && iframe.location.hash !== "") {
                    show($(selector), $(iframe.location.hash));
                    // reset the hash onced showned
                    window.location.hash = iframe.location.hash;
                } else {
                    if (!$("#"+idLink.attr("id")+settings.slugContent).hasClass(settings.contentActiveClassName)) {
                        show($(selector), idLink);  
                    }
                }
            }
        }
    };

    show = function(selector, element, fromHistoryLookUp) {
        var $selector = $(selector),
            $element = $(element),
            $myGroup = $selector.find("."+settings.linksContainerClassName),
            $myCont = $selector.find("."+settings.contentClassName),
            url, $container, strDiv, $tab, $tabContent,
            rand, isIELowerThan9 = $.isIE("<9"), rel;

        // Get url to send to AJAX
		// DIRTY: specific to Bell.ca, dev has used rev attribute to store URL/ support still use href
        if ($element.attr('rev')) {
			url = $element.attr('rev');
		} else {
			url = $element.attr('href');
		}

        strDiv = $element.attr("id")+settings.slugContent;
        $tab = $("."+settings.contentContainerClassName);
        $tabContent = $("#"+strDiv);
        
        if ($tabContent.length === 0 && typeof($element.attr("id"))!=="undefined") {
            $container = $("<div class='"+settings.contentClassName+"' id='"+strDiv+"'></div>");
            $tab.css("opacity", settings.opacity/100);
            $tab.append($container);
            $.ajaxLoader.show();
            
            // Loads data synchronously. 
            // Blocks the browser while the requests is active. 
            // It is better to block user interaction by other means when synchronization is necessary.
            rand = Math.floor(Math.random()*100);
            if (url.indexOf("&") !== -1) {
                url += "&refreshxyz="+rand;
            } else if (url.indexOf("?") === -1) {
                url += "?refreshxyz="+rand;
            }
            $.ajax({
                url: url,
                async: false,
				dataType: "html",
                success: function(data) {
                    $.ajaxLoader.hide();
                    $container.html(data);
                    
                    $tab.css("opacity", 1);
                    
                    // Finally apply hasLayout
                    if (isIELowerThan9) {
                        $tab.removeAttr("style");
                        window.bellTabsTimer = setTimeout(function() {
                            clearTimeout(window.bellTabsTimer);
                            $.hasLayout($selector);
                            window.bellTabsTimer = setTimeout(function() { 
                                clearTimeout(window.bellTabsTimer);
                                $.hasLayout($container); 
                            }, 100);
                        }, 100);
                    }

                    $myGroup.find("."+settings.linkActiveClassName).removeClass(settings.linkActiveClassName);
                    $myCont.parent().find("."+settings.contentActiveClassName).removeClass(settings.contentActiveClassName);
                    $element.addClass(settings.linkActiveClassName);
                    
                    $container.addClass(settings.contentActiveClassName);
            
                    // Specific to BELL.ca otherwise we can remove this part
                    if (typeof $.tabbing === "object") {
						$.tabbing.render($container, "tabs");
                    }
                },
                error: function() {
                    var defErrorText = "Error";
                    if ($.isFunction($.getText)) {
                        $container.html($.getText("error"));
                    } else {
                        $container.html(defErrorText);
                    }                                   
                }
            });
        } else {
            $myGroup.find("."+settings.linkActiveClassName).removeClass(settings.linkActiveClassName);
            $myCont.parent().find("."+settings.contentActiveClassName).removeClass(settings.contentActiveClassName);
            $element.addClass(settings.linkActiveClassName);
            
            $container = $("#"+strDiv);
            $container.addClass(settings.contentActiveClassName);
            
            // Specific to BELL.ca otherwise we can remove this part
            if (!$.data($container.get(0),"renderInitialized")) {
				if (typeof $.tabbing === "object") {
					$.tabbing.render($container, "tabs");
				}				
                $.data($container.get(0),"renderInitialized", true);
            }               
        }

        if (!fromHistoryLookUp) {
            // Omniture
            // TODO: refactor this code to use $.bell.external
            rel = $element.attr("rel");
            /*global manageTabTracking */
            if (typeof(manageTabTracking) !== "undefined" && window.bellToTrackTab) {
                if (rel) {
                    window.bellToTrackTab = false;              
                    manageTabTracking(rel);
                }
            }
            
            // LivePerson
            if (typeof $.bell === "object") {
				if ($.bell.external) {
					if (!rel) { rel = $element.text(); }
					if ($.isFunction($.bell.external.tracker)) {
						$.bell.external.tracker({
							appName: "lp",
							actionName: "tabs",
							data: {
								tabLabel: rel.indexOf("/")===-1?rel:rel.split("/")[1]   
							}
						});
					}
				}
			}
		}

        // Finally apply hasLayout for IE < IE9
        if (isIELowerThan9) {
            window.bellHasLayoutTimer = setTimeout(function() {
                clearTimeout(window.bellHasLayoutTimer);
                $.hasLayout($selector);
                window.bellHasLayoutTimer = setTimeout(function() { 
                    clearTimeout(window.bellHasLayoutTimer);    
                    $.hasLayout($container); 
                }, 100);
            }, 100);
        }
    };

    historyLookUp = function(selector) {
        var hash = window.location.hash,
            idLink = hash;
            
        if (hash!=="") {
            if (hash.indexOf(settings.slugHash) !== -1) {
                idLink = hash.split(settings.slugHash)[0];
            } 
            if (!$.isIE("<9")) {
                show($(selector), $(idLink), true); // add true flag indicating the show is coming from historyLookUp
            } else {
                historyManager.goTo($(selector), $(idLink));
            }
        }
    };  

    return this.each(function(idx){
        var $element = $(this),
            $myGroup = $element.find("."+settings.linksContainerClassName),
            $myTabs = $myGroup.find('a'),
            $activeTab, $myCont;

        //validateParams
        if (idx ===0) {
            window.bellToTrackTab = true;           
            
            // Load initial active tab Data
            $activeTab = $myGroup.find("."+settings.linkActiveClassName+":first");
            if ($activeTab.length) {
                $myCont = $element.find("."+settings.contentClassName);
                if ($myCont.length) {
                    $myCont.addClass(settings.contentActiveClassName);
                }
            } else {
                show($element, $activeTab.length > 0? $activeTab[0] : $myTabs[0]);
            }
            historyManager.init($element);          
            
            if (!$.isIE() || !$.isIE("<9")) {
                /*global setInterval */
                setInterval(historyLookUp, 100, $element);
            }
        }

        // Click behavior of the links
        if (!$.data($myTabs.get(0),"tabsInitialized")) {
            $myTabs.each(function() {
                $(this).click(function(){
                    var $link = $(this);
                    
                    window.bellToTrackTab = true;
                    window.location.hash = $link.attr("id")+settings.slugHash;
                    
                    // history handling not handled for now on IE                   
                    /*
                    if ($.isIE("<9")) {
                        historyManager.add();
                    }
                    */
                    show($element, $link);
                    return false;
                });
            });
            $.data($myTabs.get(0),"tabsInitialized", true);
        }
    });
};
jQuery.tabbing = {
	render: function(context, useCase) {
		if ($.isFunction($.pageRender)) {
			$.pageRender(context, useCase);	
		}
	}
}
/***************************************************/
// jQuery function: pageRender()
//
// Developped by: Son Pham
//
// description: use when content/page needs to be re-rendered using
//              BELL specifics DOM ready functions (usually used for Ajax call)
//
// requirement: 1) jQuery 1.3.2
//              2) BELL object in bell_master.js
//
// Specific to BELL.ca otherwise we can remove this part
//
// usage:   1) $.pageRender(context, useCase, callBack);
//          context: (string) Must set a className/#id/""
//          when you set to "" or $.pageRender() the whole page will be re-rendered
/**********************************************************/
jQuery.pageRender = function(context, useCase) {
    if (typeof($.bell) === "object") {
        if (typeof($.bell.page) === "object") {
            if ($.isFunction($.bell.page.render)) {
                var fn = $.getCallBack(arguments);
                $.bell.page.render(context, useCase, fn);
            }
        }
    }
};
/***************************************************/
// jQuery function: setDropDownVisibility() *** NOT COMPLETED ***
//
// Developped by: Son Pham
//
// description: will hidden/visible all select element
//              this is usually used in IE6 when you have overlays
//              on top of select elements which are always on top
//              typical scenarios involves lightBox, flyouts, etc...
//
// requirement: jQuery 1.3.2
//
// usage:   1) $.setDropDownVisibility(true, params); // will show all selects in the page
//          2) $.setDropDownVisibility(false, params); // will hidden all selects in the page
//
// params:
//  @1 state (boolean): sets the visibility state
//  @2 context (string): context selector of the select tags
//  @3 exclude (string/array): exlcude from the context selector select tags
/**********************************************************/
jQuery.setDropDownVisibility = function(state, context) {
    var $element;
    
    if (typeof context === "undefined") { context = "body"; }
    
    $("select", context).each(function() {
        $element = $(this);
        if ($element[0].nodeName === "SELECT") {
            if (state) {
                $element.css("visibility","visible");
            } else {
                $element.css("visibility","hidden");            
            }
        }
    });
};

/***************************************************/
// jQuery function: hasLayout() TODO: rework this function
//
// Developped by: Son Pham
//
// description: gives the element a css property of zoom = 1
//              use this for IE6 only
//
// requirement: jQuery 1.3.2
//              $.removeInlineCssProp()
//
// usage:   1) $.hasLayout("#myDiv");
//          2) $.hasLayout(".cBox, .cFoot");
/**********************************************************/
jQuery.hasLayout = function(selector) {
    if (selector && $.isIE("<9")) {
        var $selector = $(selector),
            $element, $elementParent,
            $elementParentCbox = [],
            hasLayoutTimerId; 

        if ($selector.length === 0) { selector = "body"; }

        $selector.each(function() {
            $element = $(this);
            $elementParent = $element.parent();
            
            // specific for BELL ** you can safely removed this code **
            var lookUpCBox = true;
            if ($element.hasClass("cBox")) {
                lookUpCBox = false;
            } else {
                $elementParentCbox = $element.parents(".cBox:first");
                if ($elementParentCbox.length) {
                    $.removeInlineCSSProp($elementParentCbox,"zoom");   
                }
            }
            
            if ($element.attr("style")) {
                $.removeInlineCSSProp($element,"zoom");
            }

            if ($elementParent.length && $elementParent.get(0).nodeName !== "HTML") {
                if ($elementParent.attr('style')) {
                    $.removeInlineCSSProp($elementParent,"zoom");
                }
            } else {
                $elementParent = [];    
            }
            
            hasLayoutTimerId = setTimeout(function() {
                $element.css("zoom", 1);
                if ($elementParent.length) {
                    $elementParent.css("zoom", 1);
                }

                if (lookUpCBox) {
                    if ($elementParentCbox.length) {
                        $elementParentCbox.css("zoom", 1);  
                    }
                }
                clearTimeout(hasLayoutTimerId);
            }, 200);
        });
    }
};  
/**************************************************************/
// jQuery function: getJsClassName()
//
// Developped by: Son Pham
//
// Description: Extract className use for JS trigger to the CSS
//              ClassName
//
// Exemple: hScrollBarJs -> will become hScrollBar
//
// requirement: 1) jQuery 1.3.2
//              2) selector (can be a string or object)
//
// Note: 1) if you have multiple instance of className with Js
//          example: <div class='hScrollBarJs toolTip'></div>
//          the first occurence of Js will be returned e.g hScrollBar
//
//       2) specific for Bell.ca
//
// usage:   1) $.getJsClassName(".hScrollBarJs");
//          2) $.getJsClassName("hScrollBarJs");
//          3) $.getJsClassName($(".cBox"));
/**************************************************************/    
jQuery.getJsClassName =  function(selector) {
    var strSelector = selector,
        objClass, hasJs, i;
    
    if (typeof(selector) === "object") {
        objClass = $(selector).attr("class").split(" ");
        hasJs = false;
        for (i=0;i<objClass.length;i++) {
            if (objClass[i].indexOf("Js") !== -1) {
                strSelector = objClass[i];
                hasJs = true;
                break;
            }
        }
        if (!hasJs) {
            strSelector = "";   
        }
    } 
    if (strSelector.indexOf(".") !== -1) {
        strSelector = strSelector.substr(1,strSelector.length-3);
    } else {
        strSelector = strSelector.substr(0,strSelector.length-2);
    }
    return strSelector;
};
/***************************************************/
// jQuery function: getHighestZIndex()
//
// Developped by: Son Pham
//
// description: Returns the highest z-index in the page + 1
//              so the return value will be the hightest
// 
// Warning: Very slow!!! use this function if really you need to get the top zIndex
// 
// requirement: jQuery 1.3.2
//
// usage:   1) $.getHighestZIndex();
//
/**********************************************************/
jQuery.getHighestZIndex = function() {
    var allElems = document.getElementsByTagName? document.getElementsByTagName("*"): document.all,
        maxZIndex = 0,
        i, elem, cStyle, sNum;

    for(i=0;i<allElems.length;i++) {
        elem = allElems[i];
        cStyle = null;

        if (elem.currentStyle) {
            cStyle = elem.currentStyle;
        } else if (document.defaultView && document.defaultView.getComputedStyle) {
            cStyle = document.defaultView.getComputedStyle(elem,"");
        }
        if (cStyle) {
            sNum = Number(cStyle.zIndex);
        } else {
            sNum = Number(elem.style.zIndex);
        }
        if (!isNaN(sNum)) {
            maxZIndex = Math.max(maxZIndex,sNum);
        }
    }
    return maxZIndex + 1;
};
/**************************************************************/
// jQuery function: getPixelValue()
//
// Developped by: Son Pham
//
// Description: Gets the pixel value of em element
//
// note: 1) this function will only accepts objects or element string ID
//       2) if you are passing an object, only the first item will be considered
//
// requirement: jQuery 1.3.2
//
// usage: 1) $.getPixelValue($("#myDiv"), $("#myDiv").css("fontSize"));
//        2) $.getPixelValue("myDiv", document.getElementById("myDiv").style.fontSize);
/**************************************************************/    
jQuery.getPixelValue = function(element, value) {
    var PIXEL = /^\d+(px)?$/i,
        style, runtimeStyle;

    if (PIXEL.test(value)) {return parseInt(value,10);}
    
    if (typeof(element) === "object") {
        if (element.length) {
            element = element[0];
        }
    } else if (typeof(element) === "string") {
        element = document.getElementById(element);
    }

    if (element) {
        style = element.style.left;
        runtimeStyle = element.runtimeStyle.left;
        element.runtimeStyle.left = element.currentStyle.left;
        element.style.left = value || 0;
        value = element.style.pixelLeft;
        element.style.left = style;
        element.runtimeStyle.left = runtimeStyle;
    }
    
    return value;
};
/***************************************************/
// jQuery plugin: $.getBrowserStyle() ** BETA state **
//
// Developped by: Son Pham
//
// Description: Returns the computed style of a single element
//
// Requirement: jQuery 1.3.2
//
// usage 1) $.getBrowserStyle(el, "width")
//       2) $.getBrowserStyle(el, "margin-top")
//
// params
// @el (jQuery Object): must be an element array usually a jQuery object
// @styleProp (string): CSS property
/***************************************************/
jQuery.getBrowserStyle = function(el, styleProp) {
    var $element, value = null;
    if (el && el.length) {
        $element = $(el);
        if ($element.length) {
            el = $element.get(0);
            if (el.currentStyle) {
                value = el.currentStyle[styleProp];
            } else if (window.getComputedStyle) {
                value = document.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp);
            }
        }
    } 
    return value;   
};
/**************************************************************/
// jQuery function : textBreaker()
//
// Developped by: Son Pham
//
// Version 2.1 (april 2011 -> setVerticalAlign is different when it's a Tab)
// Version 2.0 (november 2010 -> introduce the squeezeIt function)
// Version 1.0 (2009)
//
// Description: Breaks the text to a giving Max width.  If ajustment
//              is applied ... then the padding top and bottom of the
//              other text will be ajusted (visually the text will be
//              aligned vertical to the middle (DESCRIPTION TO BE REVIEWED)
//
// How the "Break" system works :
//  - to be written
//
//  hTabs support notes :
//  - Should have no problem with 6 tabs. (any amount of text)
//  - Maximumof 8 tabs is supported 
//  - IE6 min-width does not work correctly (no fix yet)
//
// requirement: jQuery 1.3.2
//
// usage: $(".nav a").textBreaker({params});
//
// @similarItem (string): defines an HTML element to textBreak againts default: "ul:first li a"
// @maxElementWidth (integer): TODO: revalidate this parameter default :160
// @breakPourcent (integer): TODO: revalidate this parameter default: 60 (%)
// @maxWidth (integer) defines the maximum width of the element default: 112
// @breakRatio (float) determines the ratio of the total width of the elements with the total width allowed. Changing the default CSS min-width affects this ratio.
//                     default: 1.1 (means the total width of the elements would be .1 times bigger than the width allowed)
// @minusBreakPourcent REEVALUATE (integer) defines the value to substract the breakPourcent if the breakRatio is higher than its default default: 5 (%)
// @widthDiffIE (integer) IE is calculating the width of elements differently, this is a simple workaround to fix the issue. We're adding a fixed value to the final width to
//                        "simulate" the correct calculations made by other browsers (firefox, chrome, safari and opera) default: 20 (pixel)
/**************************************************************/    
jQuery.fn.textBreaker = function(settings) {
    var defaults, pageFontSize, $tmpElement, beenVerticalAlign = false,
        $elementsWrapper, setVerticalAlign, squeezeIt, getWidth, autoExit = 0,
        isIELowerThan9 = $.isIE("<9"), isTabs, seekAndReduceLargest;

    defaults = {
        similarItem: "ul:first li a",
        breakPourcent: 65, // 65% do not go under 65%
        widthDiffIE: 22,
        widthDiffIETabs: 45,
		minPaddingTop: 7,
		minPaddingBottom: 3
    };  
    
    settings = $.extend(defaults, settings);
    
    if (isIELowerThan9) {
        $tmpElement = $("<span id='fontSizeChecker'>fontSize</span>");
        $tmpElement.css("fontSize", "1em");
        $("body").append($tmpElement);
        pageFontSize = $.getPixelValue($("#fontSizeChecker"),$("#fontSizeChecker").css("fontSize"));
        $tmpElement.remove();
    } else {
        pageFontSize = parseInt($("body").css("fontSize"),10);
    }
    
    $elementsWrapper = $(this);
    
    setVerticalAlign = function(elements) {
        // get tallest 
        var currentTallest = 0,
            eleH, diff, idxActive = -1,
            $item, $itemParent, beenSqueezed = false,
            paddings = 0, paddingTop, paddingBottom;
        
        elements.each(function(idx){
			
            $item = $(this);
			if (!isTabs) {
				if ($.data(this,"squeezed")) {
					beenSqueezed = true;
					if (beenVerticalAlign) {
						eleH = $item.outerHeight(true);
					} else {
						eleH = $item.height();
					}
				} else {
					eleH = $item.outerHeight(true);
				}
			} else {
				eleH = $item.outerHeight(true);				
			}
			if (eleH > currentTallest) {
                currentTallest = eleH;
            }
            if ($item.parent().hasClass("active")) {
				idxActive = idx;    
            }
        });

        // Adjust element's height (always the tallest)
        elements.each(function(){
            $item = $(this);
			diff = (currentTallest - $item.outerHeight(true))/2;
			
			paddingTop = parseInt($item.css("paddingTop"),10);
			paddingBottom = parseInt($item.css("paddingBottom"),10);
			
			if (!isTabs) {
				paddingTop += diff;
				paddingBottom += diff;
				
				if (paddingTop < settings.minPaddingTop) {
					paddingTop = settings.minPaddingTop;
				}
				
				if (paddingBottom < settings.minPaddingBottom) {
					paddingBottom = settings.minPaddingBottom;
				}				
				
				$item.css({
					paddingTop : paddingTop+"px",
					paddingBottom : paddingBottom+"px"
				});	
			} else {
				if ($item.hasClass("tabTrigActive")) {
					paddingBottom = paddingBottom/3;
				}
				$item.css("paddingTop",paddingTop+diff+"px").height(currentTallest-(paddingTop+diff)-paddingBottom);    
			}
			if (isIELowerThan9) {
				$itemParent = $item.parent();               
				if (($itemParent.width()-$item.width()) !== paddings) {
					$itemParent.width($item.outerWidth());
				}
			}
        });

        if (!isTabs && idxActive !== -1) {
            $item = elements.eq(idxActive);
            $item.css({
                paddingBottom : parseInt($item.css("paddingBottom"),10)+1+"px"
            });
        } else if (isTabs) {
            $elementsWrapper.css("paddingTop",(parseInt($elementsWrapper.css("paddingTop"),10)+currentTallest/2)+"px");
        }
		
		if (!isTabs) {
			if (beenSqueezed && !beenVerticalAlign) {
				beenVerticalAlign = true;
				setVerticalAlign(elements);
			}	
		}
    };
    
	squeezeIt = function(contentWidth, $elements) {
		autoExit++;
		if (autoExit < 100) {
			if (getWidth($elements) > contentWidth) {
				$elements = seekAndReduceLargest($elements);
				return squeezeIt(contentWidth, $elements);	
			} else {
				return true;	
			}
		} else {
			return false;	
		}
	};
	
	seekAndReduceLargest = function($elements) {
		var $element, elementW,
			largestIdx = -1, largestW = 0, newW, 
			$largest;

		$elements.each(function(idx) {
			$element = $(this);
			elementW = $element.outerWidth(true); 
			if (elementW > largestW) {
				largestIdx = idx;
				largestW = elementW;
			}
		});
		if (largestIdx !== -1) {
			$largest = $elements.eq(largestIdx);
			newW = (largestW)-Math.ceil(largestW*((100-settings.breakPourcent)/100));
			$largest.width(newW);
			$.data($largest.get(0),"squeezed",true);
		}
		return $elements;
	};
	
	getWidth = function($elements) {
		var totalElementsWidth = 0, $element ;
		$elements.each(function() {
			$element = $(this);
			totalElementsWidth += $element.outerWidth(true);
			if (isTabs) {
				totalElementsWidth += parseInt($element.parent().css("marginRight"),10);
			}
		});
		
		//DIRTY: IE seems to not be able to properly calculate the witdh in this situation
		if (isIELowerThan9){
			if (!isTabs) {
				totalElementsWidth += settings.widthDiffIE;
			} else {
				totalElementsWidth += settings.widthDiffIETabs;
			}
		}

		return totalElementsWidth;
	};
	
    return this.each(function(idx) {
		var $container = $(this), $elements, contentWidth;

		if ($container.is(":visible")) {
			$elements = $container.find(settings.similarItem);
			contentWidth = $container.outerWidth();

			if ($elements.length) {
				if ($container.hasClass("hTabs") || $container.hasClass("vTabs")) {
					isTabs = true;	
				}
				if (getWidth($elements) > contentWidth) {
					if (squeezeIt(contentWidth, $elements)) {
						// only run once
						setVerticalAlign($elements);
					}
				}
			}
		}
    });
};
/***************************************************/
// plugin: quickView 
//
// description: gets an external content into a lightBox
//              with an illusion of the content coming
//              from the link source and being morph to its
//              final display.  Reverse effect to apply when
//              the user closes the quickView window
// 
// requirement: 1) jQuery 1.4.2 because of the use of .delay()
//              2) $.isIE()
//
// usage:   1) (".selector").quickView({params});
/**********************************************************/        
jQuery.fn.quickView = function(settings) {
    var defaults, arrayQuickView,
        show, hide, animate, bindWindowResize, setPosition,
        links = this;
    
    defaults = {
        slug: "bell-quickView-"
    };
    settings = $.extend(defaults, settings);
    
    // global variables
    arrayQuickView = {};
    
    // display quickView main process
    show = function(element) {
        // element is the HTML element source responsible of trigerring the quickView
        var $element = $(element), 
            sourceId, firstLoad, qvId, $sourceContainer,
            $qView, textActionClose, textResource,
            $qvContent, $qvContentWrapper, $spinner, url, rand;
        
        // gather trigger source infos and prepare quickview ID
        firstLoad = false;
        
        qvId = $.data($element.get(0),"quickViewId");
        if (!qvId) {
            firstLoad = true;       
            if ($.isFunction($.getRandomNumber)) {
                sourceId = $.getRandomNumber(5);    
            } else {
                $sourceContainer = $element.parents(".unit:first");
                if ($sourceContainer.length) {
                    sourceId = $sourceContainer.attr("id");         
                } else {
                    sourceId = Math.floor(Math.random()*5); 
                }
            }
            qvId = settings.slug+sourceId;
            $.data($element.get(0),"quickViewId",qvId);
        } 
    
        // remove previous quickView only one quickView can be showned at a time
        $(".qvOpened").each(function() {
            hide($(this));                       
        });
    
        // load external content if not already loaded
        $qView = $("#"+qvId);

        if ($qView.length === 0) {
            // defaults texts
            textActionClose = "Close";
            if ($.isFunction($.getText)) {
                textResource = $.getText("actionClose");
                if (textResource!=="") {
                    textActionClose = textResource; 
                }
            }
            
            // build new quickview HTML
            $qView = $("<div id='"+qvId+"' class='qvFrame'><div class='qvBordRight'><div class='qvBordLeft'><div class='qvBoxLining'><div class='qvContentWrapper'><\/div><span class='bt_qvClose'>"+textActionClose+"<\/span><\/div><\/div><\/div><\/div>");
            $qvContent = $("<div id='"+qvId+"-content"+"' class='qvContent'><\/div>");

            // We append the quickView at the end of the body
            $('body').append($qView);
            
            $qView.append("<div class='qvTopRight'><div class='qvTopLeft'><\/div><\/div><div class='qvBottomRight'><div class='qvBottomLeft'><\/div><\/div>");
            $qvContentWrapper = $qView.find(".qvContentWrapper:first");
            $qvContentWrapper.append($qvContent);
            
            // Create instance of spinner
            $spinner = $.ajaxLoader.show({targetId:$qvContentWrapper});
            
            // Get url to send to AJAX
            url = $element.attr('href');

            // Loads data synchronously. 
            // Blocks the browser while the requests is active. 
            // It is better to block user interaction by other means when synchronization is necessary.
            rand = Math.floor(Math.random()*100);
            if (url.indexOf("&") !== -1) {
                url += "&refreshxyz="+rand;
            } else if (url.indexOf("?") === -1) {
                url += "?refreshxyz="+rand;
            }

            $.ajax({
                url: url,
                async: false,
				dataType: "html",
                success: function(data, textStatus) {
                    $qvContent.append(data).delay(100);

                    // Set quickView dimensions
                    var zIndex = 99999,
                        $externalContent = $qvContentWrapper.find("#quickViewHolder:first"),
                        contentH = $externalContent.outerHeight(true),
                        contentW = $externalContent.outerWidth(true),
                        contentHTML, propertiesQuickView,
                        bellQuickViewTimer;
                    
                    $qView.width(contentW);
                    $qView.height(contentH);
                    $qView.css("zIndex", zIndex);
                    
                    // Remove external class since we already have the width instance
                    // note: here we assume the external content has a css width
                    $externalContent.removeAttr("id").removeAttr("class").addClass("qvExternalJs");
                    $externalContent.find(".cBox").removeClass("cBox");
                    contentHTML = $externalContent.html();
                    $qvContent.empty().append(contentHTML);
                    
                    propertiesQuickView = {};
                    propertiesQuickView.width = contentW;
                    propertiesQuickView.height = contentH;
                    propertiesQuickView.zIndex = zIndex;
                    arrayQuickView[qvId] = propertiesQuickView;

                    // Esthetic structure for padding the quickView
                    $qvContent.wrapInner('<div class="qvLining"></div>');

                    // Animate new quickView
                    animate($element, $qView, true);
                    
                    // Finally Fix IE6 if required
                    if ($.isIE(6)) {
                        bellQuickViewTimer = setTimeout(function() {
                            $.hasLayout($qView);
                            clearTimeout(bellQuickViewTimer);
                            bellQuickViewTimer = setTimeout(function() { 
                                clearTimeout(bellQuickViewTimer);
                                $.hasLayout($qvContentWrapper); 
                            }, 100);
                        }, 100);
                    }
                },
                error: function() {
                    var defErrorText = "Error";
                    if ($.isFunction($.getText)) {
                        defErrorText = $.getText("error");
                    } 
                    alert(defErrorText);
                    $qView.remove();
                }               
            });
        } else {
            // Content is already loaded so byPass Ajax and reuse loaded content
            animate($element, $qView, false);
        }
    };

    // Hides the current QuickView
    hide = function(qv) {
        $(qv).hide();
        // IE6 select hidding bug
        if ($.isIE(6)) {
            if ($.isFunction($.setDropDownVisibility)) {
                $.setDropDownVisibility(true);
            }
        }
    };

    // Animates the quickView and handles the close quickView
    animate = function(element, qView, isNewContent) {
        var $element = $(element),
            $qView = $(qView),
            $btnClose = $qView.find(".bt_qvClose:first"),
            $spinner = $qView.find(".cLoader:first"),
            $content, propertiesQuickView, $window, $document,
            windowH, windowW, docH, left, top, topIE6, originalTop, originalLeft,
            isIE6 = $.isIE(6), isIELowerThan9 = $.isIE("<9"), 
            setVisibilityEnabled = false;

        // IE6 select hidding bug
        if (isIE6) {
            if ($.isFunction($.setDropDownVisibility)) {
                setVisibilityEnabled = true;
                $.setDropDownVisibility(false);
            }
        }

        // hide quickView content
        $content = $qView.find(".qvContent:first");
        $content.css("visibility", "hidden");

        // Get the quickView properties to get information on its final dimensions
        propertiesQuickView = arrayQuickView[$qView.attr("id")];

        // Center frame
        $window = $(window);
        $document = $(document);
        
        windowH = $window.height();
        windowW = $window.width();
        docH = $document.height();
        left = (windowW - propertiesQuickView.width)/2;
        top = (windowH - propertiesQuickView.height)/2;     
        originalTop = $element.offset().top-$document.scrollTop();
        originalLeft = $element.offset().left;
        
        if (isIE6) {
            top = $document.scrollTop();
            windowH = windowH/2;
            if (top === 0) { 
                top = windowH; 
            } else {
                top = (windowH+top);
            }
            top = top-propertiesQuickView.height/2;
            topIE6 = top;
        }

        // height check
        if (propertiesQuickView.height < $content.outerHeight()) {
            propertiesQuickView.height = $content.outerHeight();
        }

        // Reset quickView visual apparence to zero
        $qView.addClass("qvOpened").css({
            visibility: "visible",
            width: 0,
            height: 0,
            top: originalTop,
            left: originalLeft
        });

        $qView.unbind("animate").stop().animate({
            width: propertiesQuickView.width,
            height: propertiesQuickView.height,
            top: top+"px",
            left: left+"px"
        }, 125, function() {
            $btnClose.show();   
            
            top = (windowH-$content.outerHeight())/2;
            if (isIE6) {
                top = topIE6;
            }

            // height check
            if (propertiesQuickView.height < $content.outerHeight()) {
                propertiesQuickView.height = $content.outerHeight();
            }

            $(this).removeAttr("style").css({
                visibility: "visible",
                width: propertiesQuickView.width,               
                height: propertiesQuickView.height,
                top: top+"px",
                left: left+"px",
                zIndex: propertiesQuickView.zIndex
            });

            // By setting height here, we ensure that the quickView has the real content height
            $qView.height($content.outerHeight());  

            if (isNewContent) {
                // DIRTY: QuickFix IE 7+
                if (isIELowerThan9) {
                    var $bottom = $qView.find(".qvBottomRight:first"),
                        bottom = parseInt($bottom.css("bottom"),10),
                        newHeight = $qView.height()+bottom+8;
                        
                    if ($.isIE(8)) { newHeight += 5; }
                    $qView.height(newHeight);
                }

                $.pageRender($content, "quickview", function() {
                    var qvH, qvTimer;

                    qvH = $.getBrowserStyle($content, "height");
                    if (qvH !== null && qvH !== "auto") {
                        qvH = parseInt(qvH, 10);
                    } else {
                        qvH = $content.outerHeight();
                    }
                    $qView.height(qvH);
                    setPosition($qView);

                    // Re-apply height after PageRender because PageRender may change some layout
                    qvTimer = setTimeout(function() {
                        clearTimeout(qvTimer);
                        qvH = $.getBrowserStyle($content, "height");
                        if (qvH !== null && qvH !== "auto") {
                            qvH = parseInt(qvH, 10);
                        } else {
                            qvH = $content.outerHeight();
                        }
                        $qView.height(qvH);
                        setPosition($qView);
                    }, 250);
                });
            }
            $spinner.remove();
            $content.hide().removeAttr("style").hide().fadeIn("slow");

            bindWindowResize($qView);
            
            // IE6 select hidding bug
            if (isIE6) {
                if (setVisibilityEnabled) {
                    $.setDropDownVisibility(true, $content);
                }
            }

			// Touch devices
			if ($.detect.touch()) {
				$($qView).stickyElement({position:"center"});	
			}

            // Set Close Action
            $btnClose.unbind("click").click(function() {
                $btnClose.hide();
                    
                $qView.removeClass("qvOpened").unbind("animate").animate({
                    width: "0px",
                    height: "0px",
                    top: $element.offset().top-$(document).scrollTop(),
                    left: $element.offset().left+"px"
                }, 175, function() {
                    // put back in the item original place
                    hide($qView);
                });
                return false;
            });

        });
    };

    bindWindowResize = function($qView) {
        if ($qView && $qView.length) {
            var qViewH = $qView.height(),
                $window = $(window), windowW, windowH,
                $updatedWindow, updatedWindowW, updatedWindowH,
                resizeTimeout;
    
            //  window dimension
            windowW = $window.width();
            windowH = $window.height(); 
            
            // Resize window handling
            $window.unbind("resize").resize(function() {
                var top = (($(window).height()-qViewH)/2),
                    onResize;
                
                if ($.isIE(6)) {
                    top = $(document).scrollTop();
                    windowH = windowH/2;
                    if (top === 0) { 
                        top = windowH; 
                    } else {
                        top = (windowH+top);
                    }
                    top = top-qViewH/2;             
                }
                
                onResize = function() {
                    $qView.css({
                        top: top+"px",
                        left: (windowW-$qView.width())/2+"px"
                    });
                };
    
                $updatedWindow = $(window);
                updatedWindowW = $updatedWindow.width();
                updatedWindowH = $updatedWindow.height();
                
                // compare the new height and width with old one
                if(windowW!==updatedWindowW || windowH!==updatedWindowH)
                {
                    window.clearTimeout(resizeTimeout);
                    resizeTimeout = setTimeout(onResize, 10);
                }
                //Update the width and height
                windowW = updatedWindowW;
                windowH = updatedWindowH;
            });
        }
    };

    setPosition = function($qView) {
        if ($qView && $qView.length) {
            var $window = $(window),
                windowH = $window.height(),
                windowW = $window.width(),
                qViewH = $qView.height(),
                top = (($window.height()-qViewH)/2);
            
            if ($.isIE(6)) {
                top = $(document).scrollTop();
                windowH = windowH/2;
                if (top === 0) { 
                    top = windowH; 
                } else {
                    top = (windowH+top);
                }
                top = top-qViewH/2;             
            }
            
            $qView.css({
                top: top+"px",
                left: (windowW-$qView.width())/2+"px"
            });
        }
    };

    return this.each(function(idx) {
        if (idx === 0) {
            var $link = $(this);
            
            if (!$.data($link.get(0), "quickViewInitialized")) {
                links.live("click", function() {
                    show($(this));

                    // Third-party extra process
                    if (typeof $.bell === "object") {
						if ($.bell.external) {
							if ($.isFunction($.bell.external.tracker)) {
								$.bell.external.tracker({
									appName: "lp",
									data: {
										componentName: "QuickView"
									}
								});
							}
						}
					}
					return false;
                });
                $.data($link.get(0), "quickViewInitialized", true);             
            }
        }
    });
};
/***************************************************/
// function: compareTool *
//
// Developped by: Son Pham
//
// version 1.1 (oct. 15, 2010) touch support
// version 1.0 (nov 2009)
//
// description: 1) Initialize the add/remove compare buttons
//              2) shows the compare board
//              3) Initialize the remove button in th compare board
// 
// requirement: 1) jQuery 1.3.2+
//              2) $.lightBox()
//				3) $.detect
//
// usage: $(".selector").compareTool({params})
//
// params :
// @boardClassName (string): className of the compareTool board default: "compareWidget"
//                           if the board is not found, the function will exit
// @activeClassName (string) className of the active state on the board items default: "active"
// @removeClassName (string) className of the trigger link (not on the board link) default: "bt_removeCompare"
// @initialClassName (string) className of the trigger link on its initial state (not on the board link) default:"bt_addCompare",
// @compareRemoveClassName (string) className of the remove button (on the board link) default: "bt_rmCompare"
// @disableClassName (string) className: "bt_disableCompare"
// @splitter (string) " -- " representing the separator string in the trigger Title attribute
// @speed: 500 (integer) speed of the animation when the board is showned/hidden
// @maxChar (integer): maximum number of character before word truncate ....default 25
//  * = Bell.ca specific
/**********************************************************/
jQuery.fn.compareTool = function(settings) {
    var defaults, enableCompare;
    
    defaults = {
        boardClassName : "compareWidget",
        slotActiveClassName: "active",
        defaultClassName: "bt_addCompare",
        disableClassName: "bt_disableCompare",
        removeClassName: "bt_removeCompare", /* Not in use */
        resetClassName: "compareReset",
        toolTipId: "compareToolTip",        
        speed: 500,
        maxChar: 20
    };
    settings = $.extend(defaults, settings);
    
    enableCompare = false;

    return this.each(function(i, objElement) {
        var $element = $(this), $board;
        
        // Share settings
        if (i===0) { 
            window.compareSettings = settings;
            $board = $.compareTool.getObject();
            if ($board) {
                enableCompare = true;
                if (objElement.className !== "") {
                    settings.defaultClassName = objElement.className.split(" ")[0];
                }               
                window.compareSettings = settings;
            } else if ($element.get(0).nodeName === "A"){
                $element.attr("href","#error_no_compareBoard");
            }
        }

        if (enableCompare) {
            // IE6 always stay in bottom
            if ($.isIE(6) && $board) {
                $("body").append($board);
                
                $(window).scroll(function() {
                    $board.css("bottom",0);
                });
            }
            
            // Toggle text handling
            if (!$element.hasClass("compareLinkInitializedJs")) {
                $.data($element.get(0),"originaltext", $element.text());
                $element.addClass("compareLinkInitializedJs");              
            }
            if ($.compareTool.toToggleText($element)) { 
                $.compareTool.toggleText(-1,$element);
            }
            if ($board) {
                $board.find("."+settings.resetClassName).each(function() {
                    $(this).unbind("click").click(function() {
                        $.compareTool.reset();
                        return false;
                    });
                });
            } 
        }
    });
};
jQuery.compareTool = {
    boardObj: null,
    
    // check category compatibility (categories are stored in the "rev" attribute of the link
    isCategoryCompatible: function(categoryId){
        var $board = this.getObject(),
            currentCat = $.data($board.get(0),"categoryId");
            
        if(!currentCat){
            // Current categoryId is stored
            $.data($board.get(0),"categoryId", categoryId);
            return true;
        }else{
            if(currentCat === categoryId) { return true; }
        }
        return false;
    },
    show: function(element) {
        var settings = window.compareSettings,
            bellCompareTimer, $board;
        
        $("body").addClass("compareToolOn");

        $board = this.getObject();
        // IE6 problem with animation fix
        if ($.isIE(6)) {
            $board.show(10,function() {
                $.compareTool.toggleItem(element);                                      
                $board.animate({ bottom: 0 }, settings.speed);
            });
            $(window).scroll(function() {
                bellCompareTimer = setTimeout(function() {
                    if (!$board.hasClass("compareNoItemsJs")) {
                        $board.css("bottom",0).hide().show();
                    }
                    clearTimeout(bellCompareTimer);
                },0);
            });
        } else {
            $.compareTool.toggleItem(element);
			if (!$.detect.touch()) {
				$board.animate({ bottom: 0 }, settings.speed);
			} else {
				$board.show();	
			}
		}
        $board.removeClass("compareNoItemsJs");

        // Third-party extra process
        if (typeof $.bell === "object") {
			if ($.bell.external) {
				if ($.isFunction($.bell.external.tracker)) {
					$.bell.external.tracker({
						appName: "lp",
						data: {
							componentName: "Compare"
						}
					});
				}
			}
		}
	},
    hide: function() {
        var settings = window.compareSettings, $board;
        
        $("body").removeClass("compareToolOn");
        $board = this.getObject();
        if (!$.detect.touch()) {
			$board.animate({ bottom: -($board.outerHeight())+"px"}, settings.speed, function() {
				// IE6 problem with animation fix
				if ($.browser.msie && $.browser.version < 7) {                                                                                   
					$board.hide();
				}
			});
		} else {
			$board.hide();	
		}
	},
    getObject: function() {
        if (this.boardObj === null) {
            var settings = window.compareSettings,
                $board = $("."+settings.boardClassName+":first");
                
            if ($board.length) {
                this.boardObj = $board; 
            }
        }
        return this.boardObj;
    },
    remove: function(comparedItem, text, sourceTrigger, board) {
        var $element = $(sourceTrigger),
            $comparedItem = $(comparedItem),
            $board = $(board),
            settings = window.compareSettings,
            isActive;

        // Remove Item
        if ($.browser.msie) {
            text = text.replace(/sup>/gi,"SUP>");   
        }
        $comparedItem.html($comparedItem.html().replace(text,"&nbsp;")).removeClass(settings.slotActiveClassName).removeAttr("id");
        
        // Enable all disabled links
        $.compareTool.toggleEnable(true);

        // If no active item then hide compare board
        isActive = false;
        $board.find("ul li").each(function() {

            if ($(this).hasClass(settings.slotActiveClassName)) {
                isActive = true;
                return false;
            }
        });
        if (!isActive) {
            $.compareTool.hide();
            $.removeData($board.get(0),"categoryId");
            $board.addClass("compareNoItemsJs");
        } 
        
        $.compareTool.toggleText($element.hasClass("tglActiveJs")?0:1,$element);
    },
    hasAvailableSlot: function() {
        var settings = window.compareSettings,
            $board = this.getObject(),
            availableSlots = false,
            $placeHolder;

            $placeHolder = $board.find("ul li");
        
        $placeHolder.each(function() {
            if (!$(this).hasClass(settings.slotActiveClassName)) {
                availableSlots = true;
                return false;
            }
        });
        return availableSlots;
    },  
    toggleEnable: function(status) {
        var settings = window.compareSettings, $element;

        if (!status) {
            // to disable
            $("."+settings.defaultClassName+":not(.tglActiveJs)").each(function() {
                $element = $(this);
                $element.addClass("deactivateCompareJs").attr("href","#"+settings.toolTipId);
                if ($.isFunction(jQuery.fn.toolTip)) {
                    $element.toolTip({unToolTip: false});
                }
            });
        } else {
            // to enable            
            $(".deactivateCompareJs").each(function() {
                $element = $(this);
                $element.removeClass("deactivateCompareJs").addClass(settings.defaultClassName).attr("href","#");
                if ($.isFunction(jQuery.fn.toolTip)) {
                    $element.toolTip({unToolTip: true});                    
                }
            });
        }
    },
    // toggle a lightBox. This lightbox is hidden in the compareWidget.jsp.
    toggleConfirmationBox: function(element) {
        var $element = $(element);
        $.lightBox.showInPage("#confirmBox", {modal:true, minHeight: 100}, function(boxObject) {
            if (boxObject.length) {
                boxObject.find(".btnDftAct").unbind("click").click(function() {
                    $.compareTool.reset();
                    $.compareTool.show($element);
                    $.lightBox.hide();
                    return false;
                });
            }
        });
    },
    toggleItem: function(element) {
        var settings = window.compareSettings,
            $board = this.getObject(),
            $placeHolder, availableSlots, categoryId, text,
            elementId, $element, elementIdCompared, elementTitle,
            $comparedItem, $holder, $highlight, extraHTML, timerId,
            $temp;
                
        // Check to see if all placeHolder items are filled
        $placeHolder = $board.find("ul li");
        availableSlots = this.hasAvailableSlot();

        $element = $(element);
        elementId = $element.attr("id");
        categoryId = $element.attr("rev");
        // check for categories before adding it. If selected item is not comparable with the previously added one, toggle the confirmation box and break current function.
        if(!this.isCategoryCompatible(categoryId)){
            this.toggleConfirmationBox($element);       
            return false;
        }

        if (!$element.hasClass("tglActiveJs")) {
            if (elementId !== "") {
                elementTitle = $element.attr("title");

                $temp = $("<div class='accessAlt'>"+elementTitle+"</div>");
                $("body").append($temp);
                text = $temp.text();

                if(text && text.length > settings.maxChar){
                    text = text.substring(0,settings.maxChar)+"...";
                }
                elementIdCompared = elementId+"-cpt";
                $comparedItem = $("#"+elementIdCompared);
                
                if ($comparedItem.length === 0) {
                    if (availableSlots) {
                        $.compareTool.toggleText($element.hasClass("tglActiveJs")?0:1,$element);
                        $placeHolder.each(function() {
                            $holder = $(this);

                            if (!$holder.hasClass(settings.slotActiveClassName)) {
                                $holder.attr("id", elementIdCompared);
                                // This title should be i18n.                               
                                // Add html markup
                                extraHTML = "<span> <a href='#"+elementId+"' title='"+$.getText("compareRemoveItemToolTip")+"'><span>"+$.getText("actionRemove")+"</span></a></span>";
                                $holder.html(text+extraHTML);
                                
                                // highlight effect
                                $highlight = $("<span class='highlight'><span><!-- --></span></span>");                             
                                $holder.append($highlight);
                                
                                $holder.addClass(settings.slotActiveClassName).show();
                                
                                timerId = setTimeout(function() {
                                    $highlight.fadeOut(function() {
                                        $(this).remove();

                                        // bind click "remove" event
                                        $holder.find("a").unbind("click").click(function() {
                                            $.compareTool.remove($holder, text, $element, $board);
                                            return false;
                                        });
                                        
                                        // Disable all the links if no more slots are availble
                                        availableSlots = $.compareTool.hasAvailableSlot();
                                        if (!availableSlots) {
                                            $.compareTool.toggleEnable(false);  
                                        }
                                        
                                        // remove Timer
                                        clearTimeout(timerId);
                                    });
                                }, 250);
                                return false;
                            }
                        });
                    } 
                }
            } 
        } 
    },
    toggleText: function(showState,element) {
        var $element = $(element),
            settings = window.compareSettings,
            rel, originaltext, arrRel, text;

        if (this.toToggleText($element)) {
            rel = $element.attr("rel");
            originaltext = $.data($element.get(0),"originaltext");
            if (rel !== "") {
                if (rel.indexOf("/") !== 0) {
                    arrRel = rel.split("/");
                    if (arrRel.length) {
                        switch(showState) {
                            case -1: // initial state
                                text = originaltext.replace(arrRel[1], arrRel[0]);
                                text = text.replace(arrRel[0]+"/","");
                                this.replaceText(originaltext, text, $element);
                                break;
                            case 0: // added -> add state
                                text = originaltext.replace(arrRel[showState+1], arrRel[showState]);    
                                text = text.replace(arrRel[showState]+"/","");
                                this.replaceText($element.text(), text,  $element);
                                $element.removeClass("tglActiveJs");
                                $element.removeClass(settings.disableClassName);
                                break;
                            case 1: // add -> added state
                                text = originaltext.replace(arrRel[showState-1], arrRel[showState]);    
                                text = text.replace("/"+arrRel[showState],"");
                                this.replaceText($element.text(), text,  $element);                         
                                $element.addClass("tglActiveJs");
                                $element.addClass(settings.disableClassName);
                                break;
                        }
                    }
                }
            }
        }
    },
    // find toggle text
    toToggleText: function(element) {
        var $element = $(element),
            str = $.data($element.get(0),"originaltext"),
            rel = $element.attr("rel"),
            toggleTextFounded = false;
            
        if (str.indexOf(rel) !== -1) {
            toggleTextFounded = true;
        }
        return toggleTextFounded;
    },
    // replace text
    replaceText: function(searchText, newText, element) {
        var $element = $(element);
        $element.html($element.html().replace(searchText, newText));
    },
    reset: function() {
        var settings,
            $board = this.getObject(),
            $placeHolder, $holder,
            $linkTrigger, text;

        settings = window.compareSettings;

        // Check to see if all placeHolder items are filled
        $placeHolder = $board.find("ul li");
        $placeHolder.each(function() {
            $holder = $(this);
            if ($holder.attr("id")) {
                $linkTrigger = $("#"+$holder.attr("id").replace("-cpt",""));
                text = $.trim($holder.text().replace($holder.find("span:last").text(),""));
                $.compareTool.remove($holder, text, $linkTrigger, $board);
            }
        });
    }
};
/***************************************************/
// plugin: outLineKiller 
//
// description: Removes the outline on element
// 
// requirement: jQuery 1.3.2
//
// usage:   1) $(".selector").outLineKiller();
//          2) $("#myElement").outLineKiller();
//
/**********************************************************/        
jQuery.fn.outLineKiller = function() {
    return this.each(function() {
        $(this).mousedown(function(){
            $(this).css("outline","none");
        }).mouseup(function() {
            $(this).css("outline","invert none medium");
        });
    });
};
/***************************************************/
//  plugin: fullScrollDetector 
//
//  Developped by: Son Pham
//
//  description: This function will enable a element when
//              its detect that a user has fully scrolled a content
// 
//  requirement: jQuery 1.3.2
//
//  usage:  1) $(".myDiv").fullScrollDetector({params});
//
//  params :
//  @contentClassName (string) : content to be scrolled default: txtWindow
//  @targets (array): array of elements to be enabled when full scroll is detected default: [".scrollDetectionJs"]
/**********************************************************/        
jQuery.fn.fullScrollDetector = function(settings) {
    var defaults, validateParams, enableControl;
    
    defaults = {
        contentClassName: "txtWindow",
        targets : [".fTerms"]
    };
    settings = $.extend(defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.contentClassName) !== "string") {
            settings.contentClassName = "txtWindow";
        }
        if (typeof(settings.targets) !== "array") {
            settings.targets = [".fTerms"];
        }
    };
    
    enableControl = function() {
        // if targets a specified
        $.each(settings.targets, function(idx, value) {
            $(value).find("input:checkbox").each(function() {
                $(this).removeAttr("disabled");                                          
            });                           
        });
    };
    
    return this.each(function(idx) {
        if (idx === 0) { validateParams(); }
                              
        var $element = $(this),
            $content, scrollHeight, clientHeight;
        
        if (!$.data($element.get(0),"initialized")) {
            $content = $element.find("."+settings.contentClassName+":first");

            if ($content.length) {
                scrollHeight = $content.get(0).scrollHeight;
                clientHeight = $content.get(0).clientHeight;
    
                if ((scrollHeight-clientHeight) === 0) {
                    enableControl();
                }
                
                $content.scroll(function() {
                    if (this.scrollHeight-this.clientHeight == this.scrollTop) {
                        $(this).unbind("scroll");
                        // default behaviour is to find first checkBox
                        var $checkbox = $element.find("input:checkbox:first");
                        if ($checkbox.length) {
                            $checkbox.removeAttr("disabled");   
                        }
                        
                        // if targets a specified
                        enableControl();
                    }
                    return false;
                });
            }
            $.data($element.get(0),"initialized",true);
        }
    });
};
/************************************************************************************/
//  plugin: $().maxChar() 
//
//  Developed by: Son Pham / Miguel Matos
//
//  description: This function will count down the remaining 
//               characters left in a textarea or text field.
//
//              !important: 
//              1) max character is set by the value found in the maxClassName element
//                  e.g <span class="maxClassName">200</span> characters left 
//              2) the source input is on textarea by default or overwritted by sourceClassName
//
//  requirement: jQuery 1.3.2
//              
//  usage:  1) $(".selector").maxChar({params});
//
//  params:
//  @maxLength (integer): max characters default : 500
//  @maxClassName (string): className of html element containing the max Length value default: "charCountDownMaxJs"
//  @sourceClassName (string): className of html element containing the source input default: textarea
//                              Note: specify this when to want to use a input text field for example
/************************************************************************************/
jQuery.fn.maxChar = function (settings) {
    var defaults, validateParams, count;
    
    defaults = {
        maxLength: 500,
        maxClassName: "charCountDownMaxJs",
        sourceClassName: ""
    };
    settings = $.extend(defaults, settings);

    // Validate Params
    validateParams = function() {
        if (isNaN(settings.maxLength)) {
            settings.maxLength = 500;
        }
        if (typeof(settings.maxClassName) !== "string") {
            settings.maxClassName = "charCountDownMaxJs";
        }
        if (typeof(settings.sourceClassName) !== "") {
            settings.sourceClassName = "";
        }
    };

    count = function(maxValue, source, textElement, evt) {
        var $source = $(source),
            sourceLen = $source.val().length,
            currentCount = maxValue-sourceLen;
            
        if (evt && (evt.which === 8 || evt.which === 120)) { // backspace / cut
            $(textElement).text(currentCount);
            return true;
        } else {
            if (sourceLen > maxValue) {
                if (evt.which === 17 || evt.which === 1) { // paste / drop
                    if (sourceLen) {
                        $source.val($source.val().substr(0,maxValue));
                        $(textElement).text(0);
                    }
                }
                return false;
            } else {
                $(textElement).text(currentCount);
            }
            return currentCount>0?true:false;
        }
    };
    
    return this.each(function (idx) {
        var $element = $(this),
            $source, maxLength, $textElement, maxValue;

        // validate params
        if (idx===0) { validateParams(); }

        if (!$.data($element.get(0),"initialized")) {
            // get source of input
            if (settings.sourceClassName !== "") {
                $source = $element.find("."+settings.sourceClassName+":first");
            } else {
                $source = $element.find("textarea:first");
            }
            if ($source.length) {
                // Max length character
                maxLength = settings.maxLength;
                $textElement = $element.find("."+settings.maxClassName+":first");
                if ($textElement.length) {
                    // get user max value
                    maxValue = parseInt($textElement.text(),10);
                    if (!isNaN(maxValue)) {
                        if (maxValue > 0) {
                            maxLength = maxValue;   
                        }
                    } 
                    
                    // display initial count
                    count(maxLength, $source, $textElement);
                    
                    $source.keypress(function(evt) {
                        return count(maxLength, $source, $textElement, evt);
                    }).keydown(function(evt) {
                        return count(maxLength, $source, $textElement, evt);
                    }).keyup(function(evt) {
                        return count(maxLength, $source, $textElement, evt);
                    }).bind("paste", function(evt) {
                        return count(maxLength, $source, $textElement, evt);                    
                    }).bind("drop",function(evt) {
                        return count(maxLength, $source, $textElement, evt);
                    });
                }
            }
            $.data($element.get(0),"initialized",true);
        }
    });
};
/***************************************************/
//  plugin: tableColumnRemover()
//
//  Developped by: Son Pham / Miguel Matos
//
//  description: Remove Table column on click
// 
//  requirement: jQuery 1.3.2
//
//  usage: $(selector).tableColumnRemover({params})
//
//  params:
//  @fade: (boolean): enables fade out effect default: true
//  @tableClassName (string): className of the table with the column to be removed default: "tableGroupJs"
//  @speed: (integer): fade speed default: 500
/**********************************************************/
jQuery.fn.tableColumnRemover = function(settings) {
    var defaults, validateParams;
    
    defaults = {
        fade: true,
        tableClassName : "tableGroupJs",
        speed: 500
    };
    settings = $.extend(defaults, settings); 

    // Validate Params
    validateParams = function() {
        if (typeof(settings.fade) !== "boolean") {
            settings.fade = true;
        }
        if (typeof(settings.tableClassName) !== "string") {
            settings.tableClassName = "tableGroupJs";
        }
        if (isNaN(settings.speed)) {
            settings.speed = 500;
        }
    };
    
    return this.each(function(idx) {
        var $element = $(this);

        // validate params
        if (idx===0) { validateParams(); }

        if (!$.data($element.get(0),"initialized")) {
            $element.click(function() {
                var $col = $element.parents("th:first"),
                    colIndex, $table, $tr, $th, $td;
                
                if ($col.length === 0) {
                    $col = $element.parents("td:first");
                }           
                if ($col.length) {
                    colIndex = $col[0].cellIndex;
                    if (colIndex >= 0) {
                        $("."+settings.tableClassName).each(function () {
                            $table = $(this);
                            $("tr", $table).each(function () {
                                $tr = $(this);
                                $th = $("th:eq("+colIndex+")", $tr);
                                $th.animate({opacity:0},settings.speed, function() {$(this).html("&nbsp;").css("opacity",1);});
    
                                $td = $("td:eq("+colIndex+")", $tr);
                                $td.html("&nbsp;");                         
                            });
                        });
                    }
                }
                return false;
            });
            $.data($element.get(0),"initialized",true);
        }
    });
};
/***************************************************/
// plugin: collapser
//
// Developped by: Son Pham / Miguel Matos
//
// description: Show / Hide a group of html element
// 
// requirement: jQuery 1.3.2
//
/**********************************************************/
jQuery.fn.collapser = function(settings) {
    var defaults, resetActive, toggleCollaspe;
    
    defaults = {
        collapseActionClassName : "collapseJs",
        unCollapseActionClassName : "unCollapseJs",
        targetContainerClassName: "collapseGroupJs",
        targetActionClassName: "h3 .tglJs",
        openedClassName: "tglOpen"
    };
    settings = $.extend(defaults, settings);
    
    resetActive = function(element) {
        var $element = $(element);
        $element.find(".active").each(function() {
            $(this).removeClass("active");                                     
        });
    };
    
    toggleCollaspe = function(toCollapse, element) {
        var $element = $(element),
            $parent = $element.parent(),
            $target, $targetAction;
            
        resetActive($parent.parent());
        $parent.addClass("active");

        $("."+settings.targetContainerClassName).each(function () {
            $target = $(this);
            $targetAction = settings.targetActionClassName.substr(0,1)!=="."?$(settings.targetActionClassName):$target.find("."+settings.targetActionClassName);
            if (toCollapse) {
                $target.removeClass(settings.openedClassName).hide();
                $targetAction.each(function() {
                    $(this).removeClass(settings.openedClassName);                          
                });
            } else {
                $target.addClass(settings.openedClassName).show().css("opacity",1).removeAttr("filter");
                $targetAction.each(function() {
                    $(this).addClass(settings.openedClassName);                         
                });
            }
        });
    };
    
    return this.each(function() {
        var $element = $(this),
            $collaspeAction, $unCollaspeAction;

        if (!$.data($element.get(0),"initializedCollapser")) {
            // collaspe
            $collaspeAction = $element.find("."+settings.collapseActionClassName+":first");
            $collaspeAction.click(function() {
                toggleCollaspe(true, $(this));
                return false;
            });
    
            // unCollaspe
            $unCollaspeAction = $element.find("."+settings.unCollapseActionClassName+":first");
            $unCollaspeAction.click(function() {
                toggleCollaspe(false, $(this));
                return false;
            });
            $.data($element.get(0),"initializedCollapser",true);
        }
    });
};
/***************************************************/
//  function: $.ajaxLoader.show(), $.ajaxLoader.hide()
//
//  Developped by: Son Pham
//
//  description: Add/Removes a loader in the page 
//               only one instance of loader will be in the page
// 
//  requirement: jQuery 1.3.2
//
//  usage:  1) $.ajaxLoader.show() // will show a loader
//          2) $.ajaxLoader.show({modal:true})
//          3) $.ajaxLoader.show({targetId:"#myContent"})
//          4) $.ajaxLoader.hide()
//          5) $.ajaxLoader.hide({targetId:"#myContent"})
//          6) $.ajaxLoader.isVisible() // returns true/false
//          7) $.ajaxLoader.preLoad() // will preLoad the loader images
//
//  params:
//  @modal (boolean): the loader will go in a modal mode
//  @targetId (string): loader will go in a content mode e.g it will show the loader content version within the specified content.
//  @text (string): text that will appear in the loader
/**********************************************************/
jQuery.ajaxLoader = {
    defaults: {
        modal: false,
        targetId: null,
        text: null,
        overlayId: "ajaxLoaderOverlay"
    },
    state: false,   
    show : function(settings) {
        // default text
        var text = "Loading data. Please wait...",
            textResource, $loader, html, content, $body,
            $overlay = [], $window = $(window), loaderTimer, args;

        if (!settings || typeof(settings) !== "object") {
            settings = {};
        }
        settings = $.extend(false,this.defaults, settings);

        if (settings.text !== null) { 
            text = settings.text;
        } else if ($.isFunction($.getText)) {
            textResource = $.getText("ajaxLoader");
            if (textResource!=="") {
                text = textResource;    
            }
        }
        
        content = settings.targetId;
        if (content !== null) {
            $loader = $(".cLoader:first");
            if ($loader.length === 0) {
                $loader = $("<div class='cLoader'></div>");
            }
            $(content).append($loader); 
        } else {
            $loader = $(".pgLoader:first");
            $body = $("body");

            if ($loader.length === 0) {
                html = "";
                html += "<div class='pgLoader'>\n";
                html += "<div class='pgLoaderDesc'>"+text+"<\/div>\n";
                html += "<span class='pgLoaderExtra1'><!-- --><\/span>\n";
                html += "<\/div>\n";
                $body.append(html);
                this.setPosition();
            }

            if (settings.modal) {
                $overlay = $("#"+settings.overlayId);
                if ($overlay.length===0) { 
                    $overlay = $('<div id="'+settings.overlayId+'" class="ajaxLoaderOverlay"></div>'); 

                    $overlay.css({
                        width: $(window).width(),
                        height: $(document).height()
                    });
                    
                    $window.resize(function() {
                        $overlay.width($(window).width());                      
                    });
                    $body.append($overlay);
                } else {
                    $overlay.show();
                }
            }

            this.setPosition();         
            $loader.show();
        }
        this.state = true;
        args = arguments;
        if ($.isFunction($.runCallBack)) {
            loaderTimer = setTimeout(function() {
                clearTimeout(loaderTimer);
                $.runCallBack(args);
            }, 250);
        }
        
        return $loader;     
    },
    hide: function(settings) {
        var args = arguments,
            $loader, isValidSelector,
            $overlay = [],
            content, $content;

        if (!settings || typeof(settings) !== "object") {
            settings = {};
        }
        settings = $.extend(false, this.defaults, settings);
        content = settings.targetId;
        
        if (content !== null) {
            isValidSelector = false;            
            
            switch (typeof(content)) {
                case "string":
                    content = $.trim(content);
                    if (content !== "") {
                        isValidSelector = true;                     
                    }
                    break;
                case "object":
                    isValidSelector = true;                                         
                    break;
            }
            
            if (isValidSelector){
                $content = $(content);
                if ($content.length) {
                    if (!$.isIE() || !$.isIE("<9")) {
                        $content.find(".cLoader").fadeOut("fast",function() {
                            if ($.isFunction($.runCallBack)) {
                                $.runCallBack(args);
                            }
                            $(this).remove();                                                    
                        });             
                    } else {
                        $content.find(".cLoader").remove();
                        if ($.isFunction($.runCallBack)) {
                            $.runCallBack(args);
                        }
                    }
                }
            }               
                
        } else {
            $loader = $(".pgLoader");
            if ($loader.length) {
                if (!$.isIE() || !$.isIE("<9")) {
                    $loader.fadeOut("fast", function() {
                        if ($.isFunction($.runCallBack)) {
                            $.runCallBack(args);
                        }
                    });
                } else {
                    $loader.hide();
                    if ($.isFunction($.runCallBack)) {
                        $.runCallBack(args);
                    }
                }
            }
            $overlay = $("#"+settings.overlayId);
            if ($overlay.length) {
                $overlay.hide();
            }
        }
        this.state = false;         
    },
    isVisible: function() {
        if (!this.state) {
            return false;
        } else {
            return true;    
        }
    },
    preLoad: function() {
        var text = "Loading data. Please wait...",
            html = "";
        html += "<div id='ajaxLoaderPreloader' class='pgLoader'>\n";
        html += "<div class='pgLoaderDesc'>"+text+"<\/div>\n";
        html += "<span class='pgLoaderExtra1'><!-- --><\/span>\n";
        html += "<\/div>\n";
        $("body").append(html);
        $("#ajaxLoaderPreloader").remove();
    },
    // only applies for IE6
    setPosition: function() {
        if ($.isIE(6)) {
            var $loader = $(".pgLoader:first"),
                top, winH;
            
            if ($loader.length) {
                top = $(document).scrollTop();
                winH = $(window).height()/2;
                if (top === 0) { 
                    top = winH; 
                } else {
                    top = (winH+top);
                }
                $loader.css("top",top-$loader.height()/2+"px");
            }
        }
    }
};
/***************************************************/
//  function: $.getPageLang()
//
//  Developped by: Son Pham
//
//  description: Gets the HTML lang value
// 
//  requirement: jQuery 1.3.2
//
//  usage:  1) $.getPageLang()
/**********************************************************/
jQuery.getPageLang = function(){
    var $html = $("html"),
        lang = "en", attr;
    
    if ($html.length) {
        attr = $html.attr("lang");
        if (attr) {
            attr = $.trim(attr);
            if (attr !== "") {
                lang = attr;
            }
        }
    }
    return lang;
};
/***************************************************/
//  function: $.cookies.set(), $.cookies.get(), $.cookies.remove()
//
//  Developped by: Son Pham
//
//	version 1.0 (oct 2010)
//	version 1.5 (feb 2011: default to 365 days if no days are specified in $.cookies.set('myName','myValue');)
//
//  description: Cookie capabilities (set, get, remove)
// 
//  requirement: jQuery 1.3.2
//
//  usage:  1) $.cookies.set('myName','myValue',365);
//          2) $.cookies.get('myName');
//          3) $.cookies.remove('myName');
/**********************************************************/
jQuery.cookies = {
    set : function(name,value,days) {
        var expires = "", date;
		date = new Date();
        if (!days || isNaN(days)) {
			days = 365;
		}
		date.setTime(date.getTime()+(days*24*60*60*1000));
		expires = "; expires="+date.toGMTString();

        document.cookie = name+"="+value+expires+"; path=/";
    },
    get : function(name) {
        var nameEQ = name + "=",
            ca = document.cookie.split(';'),
            i, c;
            
        for(i=0;i < ca.length;i++) {
            c = ca[i];
            while (c.charAt(0) === ' ') {
                c = c.substring(1,c.length);
            }
            if (c.indexOf(nameEQ) === 0) {
                return c.substring(nameEQ.length,c.length);
            }
        }
        return null;
    },
    remove : function(name) {
        $.cookies.set(name,"",-10);
    }       
};
/**************************************************************/
//  jQuery function : $.getCallBack.() *** Internal use DO NOT USE ***
//
//  Developped by: Son Pham 
//  Description: returns the first function found in the args parameters
//               We use this function for callBack parameters
//
//  requirement: jQuery 1.3.2
//
//  usage: $.getCallBack(arguments);
/**************************************************************/
jQuery.getCallBack = function(args) {
    var fn = null, i;
    for (i=0;i<args.length;i++) {
        if ($.isFunction(args[i])) {
            return args[i]; 
        }
    }
    return fn;
};
jQuery.runCallBack = function(args) {
    var fn = $.getCallBack(args);
    if (fn !== null) {
        fn.call();
    }       
};
/**************************************************************/
//  jQuery plugin : $.lightBox.[methods]  TODO: validate params
//
//	version: 1.5 (march 2011 -> bug fixes + fully plugin standalone)
//  version: 1.0 (january 2010)
//
//  Developped by: Son Pham 
//
//  requirement:    1) jQuery 1.3.2+
//                  2) $.hasLayout
//                  3) $.getRandomNumber
//
//  TODO: add more information
/**************************************************************/
jQuery.lightBox = {
    defaults : {
        ajax: false,
        autoScroll: true, //height control
        colClassName: "", // Grid base [col1,col2,...]
        frameSpeed: 200,        
        image: false,
        modal: false,
        maxWidth: 935,
        minWidth: 619,
        minHeight: 400,
        overlay: true,
        overlaySpeed: 200,
        overlayOpacity: 60,
        overlayColor: '#000000',
        hideCallBack: null
    },  
    animateBox : function(lightBox, args) {
        var $lightBox = $(lightBox),
            $overlay = this.generateOverlay($lightBox),
            config = window.lightBoxSettings[$lightBox.attr("id")],
            isIE = $.isIE(), isIE6 = $.isIE(6), isIELowerThan9 = $.isIE("<9"),
            setVisibilityEnabled = false;


        // IE6 select always on top fix
        if (isIE6) {
            if ($.isFunction($.setDropDownVisibility)) {
                setVisibilityEnabled = true;
                $.setDropDownVisibility(false);
            }
        }   

        // Animate background
        if (config.overlay) {
            $overlay.stop().show().animate({opacity: config.overlayOpacity/100},config.overlaySpeed, function() {
                // Animate lightBox
                if (!isIE || !isIELowerThan9) {
                    $lightBox.fadeIn(config.frameSpeed, function() {
                        $.lightBox.runCallBack(args,$lightBox);
                    });
                } else {
                    // IE: jQuery 1.3.2 will fade will black stoke  -> we dont want that it's ugly
                    $lightBox.show();
                    $.lightBox.runCallBack(args,$lightBox);
                        
                    // IE6 select always on top fix
                    if (isIE6) {
                        if (setVisibilityEnabled) {
                            $.setDropDownVisibility(true, $lightBox);
                        }
                        $lightBox.find(".lbContent:first").css("zoom", 1);                      
                    }
                }
                
                // NOTE: Specific to BELL.ca.  otherwise you can safely remove this part                
                $.lightBox.render($lightBox);

                /* run scripts and set the position */
                $.lightBox.setPosition($lightBox);
            });
        } else {
            if (!isIE || !isIELowerThan9) {
                $lightBox.fadeIn(config.frameSpeed, function() {
                    $.lightBox.runCallBack(args,$lightBox);                     
                });
            } else {
                // IE: jQuery 1.3.2 will fade will black stoke  -> we dont want that it's ugly
                $lightBox.show();
                $.lightBox.runCallBack(args,$lightBox);                 
            }           
        }

        this.bindWindowResize($lightBox);
        
        // Specific to bell.ca otherwise you can
        // safely remove the code below
        this.enableLivePerson(false);
        
        return $lightBox;
    },
    bindWindowResize: function($lightBox) {
        if ($lightBox && $lightBox.length) {
            var config = window.lightBoxSettings[$lightBox.attr("id")],
                $window = $(window), windowW, windowH,
                $updatedWindow, updatedWindowW, updatedWindowH,
                resizeTimeout;
    
            //  window dimension
            windowW = $window.width();
            windowH = $window.height(); 
            
            // Resize window handling
            $window.unbind("resize").resize(function() {
                var onResize = function() {
                    if ($lightBox.is(":visible")) {
                        var $overlay = $.lightBox.generateOverlay($lightBox);
                        $overlay.css({
                            opacity: config.overlayOpacity/100,
                            "-ms-filter": "progid:DXImageTransform.Microsoft.Alpha(Opacity="+config.overlayOpacity+")",
                            filter: "alpha(opacity="+config.overlayOpacity+")",
                            display: "block"         
                        });
                        $.lightBox.resize($lightBox);
                        $.lightBox.setPosition($lightBox);
                    }
                };
    
                $updatedWindow = $(window);
                updatedWindowW = $updatedWindow.width();
                updatedWindowH = $updatedWindow.height();
                
                // compare the new height and width with old one
                if(windowW!==updatedWindowW || windowH!==updatedWindowH)
                {
                    window.clearTimeout(resizeTimeout);
                    resizeTimeout = setTimeout(onResize, 10);
                }
                //Update the width and height
                windowW = updatedWindowW;
                windowH = updatedWindowH;
            });
        }
    },
    enableLivePerson: function(state) {
		if (typeof $.bell  === "object") {
			if (typeof $.bell.external === "object") {
				if ($.isFunction($.bell.external.tracker)) {
					$.bell.external.tracker({
						appName: "lp",
						actionName: "lightBox",
						data: {
							state: state?'true':'false'
						}
					});
				}
			}
		}
    },
    hide: function(lightBox) {
        var $lightBox, config, fn,
            isIE = $.isIE(), isIE6 = $.isIE(6), isIELowerThan9 = $.isIE("<9");
        
        if (typeof(lightBox) === "undefined") {
            $lightBox = this.getObject();
        } else if (typeof(lightBox) === "object") {
            $lightBox = $(lightBox);
        }
        
        // Specific to bell.ca otherwise you can
        // safely remove the code below
        this.enableLivePerson(true);
		
		// Track with omniture: You can safely remove this code / bell.ca sepecific
		this.trackIt($lightBox,"","close");

        if ($lightBox && $lightBox.length) {
            config = window.lightBoxSettings[$lightBox.attr("id")];

            if (!isIE || !isIELowerThan9) {
                $lightBox.fadeOut(config.frameSpeed, function() {
                    $("#lbOverlay").fadeOut(config.overlaySpeed, function() {
                        if (typeof (config.showInPage) === "undefined") {
                            $(this).remove();
                        }

                        if ($.isFunction(config.hideCallBack)) {
                            config.hideCallBack.apply(this, [$lightBox]);           
                        }
                    });
                });
            } else {
                // IE: jQuery 1.3.2 will fade will black stoke  -> we dont want that it's ugly          
                $lightBox.hide();
                $("#lbOverlay").fadeOut(config.overlaySpeed, function() {
                    $(this).remove();

                    if ($.isFunction(config.hideCallBack)) {
                        config.hideCallBack.apply(this, [$lightBox]);           
                    }
                });
            }
            // IE6 select always on top fix
            if (isIE6) {
                if ($.isFunction($.setDropDownVisibility)) {
                    $.setDropDownVisibility(true);
                }
            }

            fn = $.getCallBack(arguments);
            if (fn !== null) {
                window.lightBoxSettings[$lightBox.attr("id")].hideCallBack = fn;
            }
			
            return $lightBox;
        } else {
            $lightBox = this.getObject();

            fn = $.getCallBack(arguments);
            if (fn !== null) {
                window.lightBoxSettings[$lightBox.attr("id")].hideCallBack = fn;
            }
            this.hide($lightBox);
        }
    },
    fadeEnable : function() {
        if ($.isIE("<9")) {
            return false;   
        } else {
            return true;    
        }
    },
    getInnerWidth: function($lightBox) {
        var width = 0, $lining;
        
        if (typeof($lightBox) === "undefined") {
            $lightBox = this.getObject();       
        } 

        if ($lightBox.length) {
            $lining = $lightBox.find(".lbBoxLining:first");         
            if ($lining.length) {
                width += parseInt($lining.css("paddingLeft"),10)+parseInt($lining.css("paddingRight"),10);
                width = $lightBox.width() - width - 1;
            }
        }
        
        return width;
    },
    getObject: function() {
        var $lightBox = null;
        $(".lbFrame").each(function() {
            if ($(this).is(":visible")) {
                $lightBox = $(this);
                return false;   
            }
        });
        return $lightBox;
    },
    getOverlay: function() {
        return $("#lbOverlay");
    },
    generateBoxHTML: function(lightBoxId) {
        var $lightBox = $("<div id='"+lightBoxId+"' class='lbFrame'><div class='lbBordRight'><div class='lbBordLeft'><div class='lbBoxLining'><div class='lbTitle'><div class='lining'><h2 class='txtRep'>loading ...</h2></div></div><div class='lbContent lbInnerWrap'></div></div></div></div><div class='lbTopRight'><div class='lbTopLeft'><!-- --></div></div><div class='lbBottomRight'><div class='lbBottomLeft'><!-- --></div></div></div>");

        $lightBox.css({
            zIndex: 999999,//$.getHighestZIndex(),
            display: "none"
        });
            
        $("body").append($lightBox);
        
        return $lightBox;   
    },
    generateOverlay: function(lightBox) {
        // remove previous overlay
        $("#lbOverlay").remove();
        
        // Define background html markup
        // width 100% looks to work well in all browser (old : $(window).width()+"px")
        var $overlay = $("<div id='lbOverlay' class='lbOverlay'></div>"),
            $lightBox, config;
        
        $overlay.css({
            height: $(document).height()+"px",
            width: "100%",
            opacity: 0,
            backgroundColor: "#000",
            display: "none"
        });
        $('body').append($overlay);

        if (lightBox) {
            $lightBox = $(lightBox);
            config = window.lightBoxSettings[$lightBox.attr("id")]; 
            
            $overlay.css({
                zIndex: $lightBox.css("zIndex")-1,
                backgroundColor: config.overlayColor,
                filter: "alpha(opacity="+config.overlayOpacity+")"
            });
            
            // Close actions
            if (!config.modal) {
                $overlay.unbind("click").click(function() {
                    $.lightBox.hide($(lightBox));
                    return false;
                });
            }
        } 
        return $overlay;
    },
    getCallBack : function(args) {
        var fn = null, i;
        for (i=0;i<args.length;i++) {
            if ($.isFunction(args[i])) {
                return args[i]; 
            }
        }
        return fn;
    },
    preRender: function(lightBoxId) {
        // lightbox html markup
        var $lightBox = $.lightBox.generateBoxHTML(lightBoxId),
            $overlay, config, $content;
        
        // Adds and bind close action
        this.setCloseAction($lightBox);

        $overlay = this.generateOverlay($lightBox);
        config = window.lightBoxSettings[$lightBox.attr("id")];

        // set initial dimension
        $content = $lightBox.find(".lbContent:first");
        $content.height(config.minHeight);

        // loader animation
        if (typeof($.ajaxLoader) === "object") { 
            $.ajaxLoader.show({targetId:$content});
        }
        $lightBox.width(config.minWidth);
        $.lightBox.render($lightBox);

        // Animate background
        if (config.overlay) {
            $overlay.stop().show().animate({opacity: config.overlayOpacity/100},config.overlaySpeed, function() {
                if ($.lightBox.fadeEnable()) {
                    $.lightBox.setPosition($lightBox).fadeIn();                 
                } else {
                    $.lightBox.setPosition($lightBox).show();
                }
            });
        } else {
            if ($.lightBox.fadeEnable()) {
                $.lightBox.setPosition($lightBox).fadeIn();                 
            } else {
                $.lightBox.setPosition($lightBox).show();
            }
        }
        return $lightBox;
    },
    render: function(selector) {
        // NOTE: Specific to BELL.ca.  otherwise you can safely remove this part
        if (typeof($.pageRender) === "function") {
            $.pageRender(selector, "lightBox");
        }
    },
    resize : function(lightBox) {
        var $lightBox, $window, windowW, windowH,
            newWidth, gridBased, $col, elementWidth,
            $content, top, config, resizedH, resizedW,
            extraHeights, $lbTopRight, $lbBottomRight, lightBoxH, heightDiff,
            isIFrame, $iFrame, iFrame, $iFrameInnerWrap,
            isIE6 = $.isIE(6);
        
        if (!lightBox) {
            $lightBox = this.getObject();
        } else {
            $lightBox = $(lightBox);
        }
        if ($lightBox.length) {
            config = window.lightBoxSettings[$lightBox.attr("id")]; 
    
            $iFrame = $lightBox.find("iframe:first");
            isIFrame = $iFrame.length?true:false;
            
            //  window dimension
            $window = $(window);
            windowW = $window.width();
            windowH = $window.height();     
    
            // Content ajustment depending on the height
            $content = $lightBox.find(".lbContent:first");
            $content.removeAttr("style"); // reset content styles
    
            //  width validation
            newWidth = config.minWidth;
    
            //  Grid base seetings?
            gridBased = false;
            if (config.colClassName !== "") {
                $col = $("<div id='temp-will-be-destroyed-anyways' class='"+config.colClassName+" lbBoxLining'></div>");
                $("body").append($col);
                if ($col.width()) {
                    gridBased = true;
                    newWidth = $col.width()+parseInt($col.css("paddingLeft"),10)+parseInt($col.css("paddingRight"),10);             
                }
                $col.remove();
            }
            
            elementWidth = $lightBox.outerWidth();
            
            if (isIFrame) { 
                if ($content.length) {
                    $content.removeClass("lbInnerWrap");
                }
                // try to access iframe content
                try {
                    iFrame = $iFrame[0].contentDocument || $iFrame[0].contentWindow.document;           
                } catch(e) {}
                
                if (iFrame) {
                    $iFrameInnerWrap = $(iFrame).find(".lbInnerWrap:first");
                    if ($iFrameInnerWrap.length) {
                        $iFrameInnerWrap.width($iFrame.width());    
                    }
                } else {
                    elementWidth += 20; // 20 is the approximative browser scroller width
                }
            }
    
            if (gridBased) { elementWidth = newWidth; }
            
            // Width check
            if (elementWidth < config.minWidth) {
				$lightBox.width(config.minWidth); 
            } else if (elementWidth > windowW) {
				resizedW = windowW-(elementWidth-windowW)*2;
				if (resizedW <config.minWidth) {
					resizedW = config.minWidth;	
				}
				$lightBox.width(resizedW);
            } else if (elementWidth > config.maxWidth) {
				$lightBox.width(config.maxWidth);
            } else {
				$lightBox.width(elementWidth);
            }
            
            // Height check
            if (config.autoScroll) {
                extraHeights = 0;
                $lbTopRight = $lightBox.find(".lbTopRight:first");
                if ($lbTopRight.length) {
                    extraHeights += parseInt($lbTopRight.css("height"),10); 
                }
                $lbBottomRight = $lightBox.find(".lbBottomRight:first");
                if ($lbBottomRight.length) {
                    extraHeights += parseInt($lbBottomRight.css("height"),10);
                }
                
                lightBoxH = ($lightBox.height()+extraHeights+extraHeights/2);
                if(lightBoxH>windowH) {
                    heightDiff = lightBoxH - windowH;
					resizedH = $lightBox.height()-heightDiff*2;
					if (resizedH < config.minHeight) {
						resizedH = config.minHeight;
					}
                    $content.height(resizedH).css("overflow-y","scroll");
                }
            }
    
            if (isIE6) {
                top = $(document).scrollTop();
                windowH = windowH/2;
                if (top === 0) { 
                    top = windowH; 
                } else {
                    top = (windowH+top);
                }
                $lightBox.css("top",top-$lightBox.outerHeight(true)/2+"px");
            }
    
            // position the lightBox
            this.setPosition($lightBox);
            
            // IE6 hasLayout
            if (isIE6) {
                if ($.isFunction($.hasLayout)) {
                    $.hasLayout($lightBox); 
                }
            }
        }
        return $lightBox;
    },
    runCallBack: function(args, $lightBox) {
        // callBack handling if present
        var fn = this.getCallBack(args);
        if ($.isFunction(fn)) {
            fn.apply(this, [$lightBox]);            
        }
    },
    // callBack argument is supported
    showInPage: function(element, elementSettings) {
        var $element = $(element),
            lightBoxId, $lightBox, $content, contentId = $element.attr("id"),
            $movedElement = $("#"+contentId+"-tpl"),
            $iFrame, isIFrame, iFrameSrc, iFrameParam, iFrameArray,
            dataSettings, settings;

        if ($movedElement.length) {
            lightBoxId = $.data($movedElement.get(0),"lbId");
        } else {
            lightBoxId = $.data($element.get(0),"lbId");
        }
        
        if (!lightBoxId) {
            lightBoxId = 911;
            if ($.isFunction($.getRandomNumber)) {
                lightBoxId = $.getRandomNumber();
            }
            lightBoxId = "bell-lightBox-"+lightBoxId;           
        }
        $lightBox = $("#"+lightBoxId);
        // settings
        dataSettings = $.data($element.get(0),"settings");
        if (!$.isFunction(elementSettings)) {
            if (typeof(elementSettings) !== "object" && !dataSettings) {
                settings = this.defaults;
            } else if (dataSettings) {
                settings = $.extend(false, dataSettings, elementSettings);          
            } else {
                settings = $.extend(false, this.defaults, elementSettings);
            }
        } else {
            settings = this.defaults;
        }
        settings.lightBoxId = lightBoxId;
        settings.showInPage = true;
        if (typeof(window.lightBoxSettings) === "undefined") { window.lightBoxSettings = {}; }
        window.lightBoxSettings[lightBoxId] = settings;
        
        if ($lightBox.length === 0) {
            // lightbox html markup
            $lightBox = $.lightBox.generateBoxHTML(lightBoxId);

            // title
            $lightBox.find(".lbTitle h2").empty().append($element.find(".lightBoxTitleJs:first").text()).addClass("txtRep hType2");

			// Track with omniture: You can safely remove this code / bell.ca sepecific
			this.trackIt($lightBox, $element,"open");

            // content
            $content = $lightBox.find(".lbContent:first");
            $content.append($element.removeClass("accessAlt").show());
            // hide title from content since it has been moved into the lightBox header
            $content.find(".lightBoxTitleJs:first").remove();
            // move id of content to higher level to control the lightBox externaly
            if (contentId) {
                $lightBox.find(".lbBoxLining").attr("id", contentId);   
                $element.attr("id", contentId+"-tpl");
            }

            $iFrame = $lightBox.find("iframe:first");
            isIFrame = $iFrame.length?true:false;

            if (isIFrame) {
                iFrameSrc = $iFrame.attr("src");
                iFrameParam = "?rand="+$.getRandomNumber();
                if (iFrameSrc.indexOf("?") === -1) {
                    if (iFrameSrc.indexOf("#") === -1) {
                        iFrameSrc += iFrameParam; 
                    }
                } else if (iFrameSrc.indexOf("&") === -1) {
                    iFrameSrc += "&"+iFrameParam;
                } else if (iFrameSrc.indexOf("&") !== -1)  {
                    if (iFrameSrc.indexOf("#") !== -1) {
                        iFrameArray = iFrameSrc.split("#");
                        iFrameSrc = iFrameArray[0]+"&rand="+$.getRandomNumber()+"#"+iFrameArray[1];
                    } else {
                        iFrameSrc += +"&rand="+$.getRandomNumber(); 
                    }
                } 
                $iFrame.attr("src", iFrameSrc);
            }

            // resize lightbox now that its has the content
            window.lightBoxAjaxTimer = setTimeout(function() {
                clearTimeout(window.lightBoxAjaxTimer);
                $.lightBox.resize($lightBox);
            }, 0);

            // Adds and bind close action
            this.setCloseAction($lightBox);
        }
        
        $.data($element.get(0),"lbId", lightBoxId);

        // Animate background       
        return this.animateBox($lightBox, arguments);
    },
    // callBack argument is supported   
    showAjax: function(element, elementSettings) {
        var $element = $(element),
            rand = Math.floor(Math.random()*100),
            url, lightBoxId, $lightBox,
            $content, args, dataSettings, settings;
        
        // Get url to send to AJAX
        url = $element.attr('href');
        
        // Set element id
        lightBoxId = $.data($element.get(0),"lbId");
        
        if (!lightBoxId) {
            lightBoxId = rand;
            if ($.isFunction($.getRandomNumber)) {
                lightBoxId = $.getRandomNumber();
            }
            lightBoxId = "bell-lightBox-"+lightBoxId;           
        }       
        $lightBox = $("#"+lightBoxId);

        // settings
        dataSettings = $.data($element.get(0),"settings");
        if (!$.isFunction(elementSettings)) {
            if (typeof(elementSettings) !== "object" && !dataSettings) {
                settings = this.defaults;
            } else if (dataSettings) {
                settings = $.extend(false, dataSettings, elementSettings);          
            } else {
                settings = $.extend(false, this.defaults, elementSettings);
            }
        } else {
            settings = this.defaults;
        }
        if (typeof(window.lightBoxSettings) === "undefined") { window.lightBoxSettings = {}; }      
        window.lightBoxSettings[lightBoxId] = settings;

        if ($lightBox.length === 0){
            // lightbox html markup
            $lightBox = this.preRender(lightBoxId);
            
            $content = $lightBox.find(".lbContent:first");
            
            // Loads data synchronously. 
            // Blocks the browser while the requests is active. 
            // It is better to block user interaction by other means when synchronization is necessary.
            if (url.indexOf("&") !== -1) {
                url += "&refreshxyz="+rand;
            } else if (url.indexOf("?") === -1) {
                url += "?refreshxyz="+rand;
            }

            // callBack?
            args = arguments;
            
            $.ajax({
                url: url,
                async: false,
				dataType: "html",
                success: function(data) {
                    // IE6 select always on top fix
                    if ($.isIE(6)) {
                        if ($.isFunction($.setDropDownVisibility)) {
                            $.setDropDownVisibility(false);
                        }
                    }
                    
                    $lightBox.css("visibility","hidden");

					// Track with omniture: You can safely remove this code / bell.ca sepecific
					$.lightBox.trackIt($lightBox, $element,"open");
			
                    $content.html(data);
                    
                    // title
                    var $contentTitle = $content.find(".lightBoxTitleJs:first");
                    if ($contentTitle.length) {
                        $lightBox.find(".lbTitle h2").empty().append($contentTitle.text()).addClass("txtRep hType2");
                        $contentTitle.remove();             
                    }
                    // Adds and bind close action
                    $.lightBox.setCloseAction($lightBox);                   
                    $.lightBox.runCallBack(args, $lightBox);

                    $.lightBox.render($lightBox);
                    $.lightBox.resize($lightBox);

                    window.lightBoxAjaxTimer = setTimeout(function() {
                        $(".hScrollBarJs", $lightBox).scroller({fillSpace:true, toggle: false});
                        clearTimeout(window.lightBoxAjaxTimer);
                        $lightBox.css("visibility","visible");
                        $.lightBox.resize($lightBox);
                    }, 250);

                    $.data($element.get(0),"lbId",lightBoxId);
                },
                error: function() {
                    var defErrorText = "Error";
                    if ($.isFunction($.getText)) {
                        defErrorText = $.getText("error");
                    }
                    alert(defErrorText);
                    $.lightBox.hide($lightBox);
                    $lightBox.remove();                 
                }
            });
        } else {
            $.data($element.get(0),"lbId",lightBoxId);
            
            return this.animateBox($lightBox, arguments);
        }
    },
    showImage: function(element, elementSettings) {
        var $element = $(element),
            rand = Math.floor(Math.random()*10000),
            url, lightBoxId, triggerId, $lightBox, img,
            imageTitle, $child, $content, $overlay, args;
        
        // Get url of image
        url = $element.attr('href');
        
        // Set element id
        lightBoxId = "bell-lightBox";
        triggerId = $element.attr("id");
        if (triggerId === "" || triggerId === "undefined") {
            $element.attr("id",lightBoxId+"-image-"+rand);
            lightBoxId += "-"+rand;
        } else {
            lightBoxId = triggerId.replace("-image","");
        }
        $lightBox = $("#"+lightBoxId);

        // share the settings
        if (typeof(elementSettings) === "undefined") { 
            elementSettings = this.defaults; 
        } else if (typeof(elementSettings.onDemand) === "undefined") {
            elementSettings = $.extend(false, this.defaults, elementSettings);          
        }
        if (typeof(window.lightBoxSettings) === "undefined") { window.lightBoxSettings = {}; }      
        window.lightBoxSettings[lightBoxId] = elementSettings;

        if ($lightBox.length === 0) {
            // lightbox html markup
            $lightBox = $.lightBox.generateBoxHTML(lightBoxId);

            // LightBox image title
            imageTitle = $element.attr('title');            
            $child = $element.children();
            if ($child.length) {
                img = $child.get(0);
                if (img.nodeName === "IMG") {
                    imageTitle = $(img).attr("alt");
                }
            }
            if (imageTitle === "") { imageTitle = "Image"; }
            
            $content = $lightBox.find(".lbContent:first");
            $content.append("<div class='lbLining'><div class='lining'><img src='"+$element.attr('href')+"' alt='"+imageTitle+"' /></div></div>");
            
            $overlay = $.lightBox.generateOverlay($lightBox);
            
            if ($.isIE("<9")) {
                $.loadImages($content.find("img:first"));               
                $.lightBox.resize($lightBox);
            }
            
            $.lightBox.animateBox($lightBox, arguments);

            // callBack?
            args = arguments;
            
            $lightBox.find(".lbTitle h2").empty().append(imageTitle).addClass("txtRep hType2");

            $.lightBox.setCloseAction($lightBox);
            return $.lightBox.animateBox($lightBox, arguments);                             
        } else {
            return this.animateBox($lightBox, arguments);
        }
    },
    setCloseAction: function(lightBox) {
        var $lightBox = $(lightBox),
            config = window.lightBoxSettings[$lightBox.attr("id")];
            
        if (!config.modal) {
            if ($lightBox.find(".lbTitle a:first").length === 0) {
                $lightBox.find(".lbTitle:first").append("<a href='#' class='lightBoxCloseJs'>"+$.getText("actionClose")+"</a>");
            }
        }

        $lightBox.find(".lightBoxCloseJs").each(function() {
            $(this).click(function() {
                $.lightBox.hide($lightBox);
                return false;
            });
        });     
    },
    setPosition: function(lightBox) {
        var $lightBox = $(lightBox),
            winH = $(window).height(), $lbTopRight,
            lightBoxH = $lightBox.outerHeight(true),
            top = (winH - lightBoxH) / 2,
			left = ($(window).width() - $lightBox.width()) / 2;

		if (lightBoxH>winH) {
			$lbTopRight = $lightBox.find(".lbTopRight:first");
			if ($lbTopRight.length) {
				top = parseInt($lbTopRight.css("height"),10);   
			}
		}

		if (!$.detect.touch()) {
			$lightBox.css({
				left: left+"px",
				top: top+"px"
			});
	
			if ($.isIE(6)) {
				top = $(document).scrollTop();
				winH = winH/2;
				if (top === 0) { 
					top = winH; 
				} else {
					top = (winH+top);
				}
				$lightBox.css("top",top-lightBoxH/2+"px");
			}
		} else {
			$lightBox.css("left",left+"px");
			$($lightBox).stickyElement({position: "center"});
		}
        return $lightBox;
    },
    setSize: function(width, height) {
        var $lightBox = this.getObject(),
            $iFrame,isIFrame;

        if ($lightBox) {
            $iFrame = $lightBox.find("iframe:first");
            isIFrame = $iFrame.length?true:false;

            // different process for iFrame
            if (isIFrame) {     
                $iFrame.attr("width",width).attr("height",height);
    
                if ($.isFunction($.hasLayout)) {
                    $.hasLayout($lightBox);
                }
            } else {
                $lightBox.width(width).height(height);
            }
                
            this.resize($lightBox);
        }
    },
	trackIt: function($lightBox, $element, action) {
		if (!$.data($lightBox.get(0),"tracked")) {
			if (typeof $.bell === "object") {
				if ($.bell.external) {
					if ($.isFunction($.bell.external.tracker)) {
						var params = {}, contentId = "unknown", elementId;
						
						if (typeof $element !== "object") {
							if ($.data($lightBox.get(0),"id")) {
								contentId = $.data($lightBox.get(0),"id");
							} 
						} else {
							elementId = $element.attr("id");
							if (elementId) {
								if (elementId !== "") {
									contentId = elementId;	
								}
							}
						}
		
						params.s_oPGS = "040";
						params.s_oPRM = action + ", " + contentId;
						
						$.data($lightBox.get(0), "id", contentId);
						
						$.bell.external.tracker({
							appName: "omniture",
							data: params
						});
						
						if (action === "close") {
							$.data($lightBox.get(0),"tracked", true);		
						}
					}
				}	
			}
		}
	}
};
/**************************************************************/
//  jQuery plugin : $().lightBox()
//
//  version: 1.0
//
//  Developped by: Son Pham 
//
//  Date: november 2009
//
//  Description: ... to be completed
//
//  content ActionClassName: lightBoxTitleJs, lightBoxCloseJs ...
//              
//  requirement: jQuery 1.3.2
//
//  knowned issues: IE overlay transparency not working
//
//  usage:  1) $(".lightBoxModalJs").lightBox({modal:true})
//          2) $(".lightBoxInPageJs").lightBox({ajax:true})
//
//  TODO: add more information
/**************************************************************/    
jQuery.fn.lightBox = function(settings) {
    settings = $.extend(false, $.lightBox.defaults, settings);

    return this.each(function(idx) {
        var $element = $(this);
        
        // create overlay
        $.lightBox.generateOverlay();

        $.data(this,"settings", settings);

        // bind click event
        $element.click(function() {
            // flag to indicate that the lightBox is using the initialization method
            settings.onDemand = false;
            
            if (settings.image) {
                $.lightBox.showImage(this);
            } else if (!settings.ajax) {
                // content is in the page
                var targetId = $element.attr("href").split("#")[1];
                $.lightBox.showInPage("#"+targetId, $.data(this,"settings"));
            } else {
                // content is from url (AJAX)
                $.lightBox.showAjax($(this), $.data(this,"settings"));
            }
            return false;                      
        });
    });
};
/**************************************************************/
//  jQuery function : $.removeInlineCSSProp();
//
//  Developped by: Son Pham 
//
//  Date: november 2009
//
//  Description: removes a specific inline style on an element
//              
//  requirement: jQuery 1.3.2
//
//  usage:  1) $.removeInlineCSSProp("#myId","width");
//          2) $.removeInlineCSSProp($("#myId"),"display");
//          3) $.removeInlineCSSProp($("#myId .className"),"margin-left");
//
/**************************************************************/    
jQuery.removeInlineCSSProp = function(selector, cssProperty) {
    try {
        if (cssProperty) {
            if ($.trim(cssProperty) !== "") {
                var $element = $(selector),
                    $this, toRemove, styleArrTmp, styleArr,
                    trimmedValue, arrValue, i, styles;
                    
                $element.each(function() {
                    if (this.nodeType === 1) { // nodeType must be an element
                        $this = $(this); 
                        if ($this.attr("style")) {
                            toRemove = false;
                            styleArrTmp = $this.attr("style").split(";");
                            styleArr = [];
                            
                            // styles cleanup
                            $.each(styleArrTmp, function(i, value) {
                                trimmedValue = $.trim(value);
                                if(trimmedValue !== "") {
                                    styleArr.push(trimmedValue);
                                }
                            });
                            
                            // cssProp lookUp
                            styleArrTmp = styleArr.slice();
                            $.each(styleArr, function(i, value) {
                                arrValue = value.split(":");
                                if ($.trim(arrValue[0].toLowerCase()) === cssProperty.toLowerCase()) {
                                    styleArrTmp.splice(i, 1);
                                    toRemove = true;
                                }
                            });
                            
                            styleArr = styleArrTmp;

                            if (toRemove) {
                                // now rewrite styles
                                styles = "";
                                for (i=0;i<styleArr.length;i++) {
                                    styles += styleArr[i]+";";  
                                }
                                $this.removeAttr("style").attr("style", styles);
                            }
                        }
                    }
                });
            }
        }
    } catch(e) {}
};
/**************************************************************/
//  jQuery function : $.getText()  **** Try not to use as much as possible ****
//
//  Developped by: Son Pham 
//
//  Description: Search for Resource text by resourceKey
//
//  requirement: bell.resources.js
//
//  usage:  1) $.getText(resourceKey)
//
//  params:
//  @resourceKey: (string) resource key defined in bell.resources.js
/**************************************************************/    
jQuery.getText = function(resourceKey) {
    var text = "",
        lang = "en";

    /*global bellResources:false */
    if (typeof(bellResources) === "object") {
        if ($.isFunction($.getPageLang)) {
            lang = $.getPageLang(); 
        }
        if (typeof(bellResources[lang]) === "object") {
            if (typeof(bellResources[lang][resourceKey]) !== "undefined") {
                text = bellResources[lang][resourceKey];
            }
        }
    }
    return text;
};
/**************************************************************/
//  jQuery function : $.loadImages()
//
//  Developped by: Son Pham 
//
//  Description: Loads images and sets image dimension
//  !Important: this is not a preloader images because it should be
//              used when an image a been set and you want to set the image
//              width
//
//  requirement: jQuery 1.3.2
//               $.getBrowserStyle()
//
//  usage:  1) $.loadImages([imageObj1,imageObj2]);
//          2) $.loadImages($("img"));
//
//  params:
//  @1 (Array): Array of image objects 
/**************************************************************/
jQuery.loadImages = function(images) {
    function processImage(elementImage) {   
        if (elementImage.nodeName === "IMG") {
            if (!elementImage.complete) {
                if (elementImage.getAttribute('width') === null || elementImage.width === 0 || elementImage.width === "auto") {
                    elementImage.onload = (function(img) {
                        return function(image) {
                            if (image) {
                                if (image.target || image.srcElement) { 
                                    if (image.target) {
                                        if (image.target.naturalWidth) {
                                            image.target.setAttribute("width",image.target.naturalWidth);
                                            image.target.setAttribute("height",image.target.naturalHeight);
                                        } else if (image.target.clientWidth) {
                                            image.target.setAttribute("width",image.target.clientWidth);
                                            image.target.setAttribute("height",image.target.clientHeight);
                                        }
                                    } else {
                                        if (image.srcElement.naturalWidth) {
                                            image.srcElement.setAttribute("width",image.srcElement.naturalWidth);
                                            image.srcElement.setAttribute("height",image.srcElement.naturalHeight);
                                        } else if (image.srcElement.width) {
                                            image.srcElement.setAttribute("width",image.srcElement.width);
                                            image.srcElement.setAttribute("height",image.srcElement.height);
                                        }
                                    }
                                }
                            }
                        };
                    }(elementImage));
                }
            }
        }
    }

    if (images) {
        if (images instanceof jQuery === true) { 
            if (images.get(0)) {
                if (images.get(0).nodeName !== "IMG") {
                    images = images.find("img");
                }
            }
        } else {
            if (!images.push) { images = [images]; }
        }
        $.each(images, function(idx, elementImage) {
            processImage(elementImage);
        });     
    }
};
//*****************************************************
//  jQuery function: $.getRandomNumber()
//
//  developed by: Son Pham
//
//  description: will generate a random number (defaults 1-999)
//
//  scenario: You need to create unique random ID
//
//  Requirement: jQuery 1.3.2
//
//  usage:  1) $.getRandomNumber(); // 1-999
//          2) $.getRandomNumber(5); // 1-99999
//
//  params:
//  @1 numberLength (integer): number range
//  @2 randomType (string): type of random (by "max" / length "null/undefined" (default))
//***************************************************** 
jQuery.getRandomNumber = function(numberLength, randomType) {
    var strLength = "1", i;
    if (isNaN(numberLength)) { numberLength = 3; }

    if ((typeof(randomType) === "undefined") || (randomType !== "max") || (randomType === null)) {
        for (i=0; i<numberLength; i++) {
            strLength += i;
        }
        return Math.floor(Math.random()*parseInt(strLength,10));
    } else {
       return Math.round(Math.random()*numberLength);       
    }
};
/***************************************************/
//  Plugin: popup()
//
//  Developped by: Son Pham / Miguel Matos
//
//  description: Open a popup window using params 
// 
//  requirement: jQuery 1.3.2
//
//  usage:  1) $(this).popup(settings);
//
/**********************************************************/
jQuery.fn.popup = function(settings) {
    settings = $.extend(false, $.popup.defaults, settings);

    // Validate Params
    var validateParams = function() {
        if (typeof(settings.center) !== "boolean") {
            settings.center = true;
        }
        if (typeof(settings.target) !== "string") {
            settings.target = "_blank";
        }
        if (isNaN(settings.width)) {
            settings.width = 640;
        }
        if (isNaN(settings.height)) {
            settings.height = 480;
        }
        if (typeof(settings.scrollBars) !== "boolean") {
            settings.scrollBars = true;
        }
        if (typeof(settings.toolBar) !== "boolean") {
            settings.toolBar = true;
        }
        if (typeof(settings.location) !== "boolean") {
            settings.location = true;
        }
        if (typeof(settings.status) !== "boolean") {
            settings.status = true;
        }
        if (typeof(settings.menuBar) !== "boolean") {
            settings.menuBar = true;
        }
        if (typeof(settings.resizable) !== "boolean") {
            settings.resizable = true;
        }       
    };

    return this.each(function(idx) {
        if (idx===0) { validateParams(); }                            
                              
        $(this).click(function() {                            
            window.open($(this).attr("href"), settings.target, $.popup.generateParams(settings)).focus();
            return false;
        });
    });
};
// TODO: reconcile the defaults properties
jQuery.popup = {
    defaults:  {
        center: true,
        target: '_blank', 
        width: 640, 
        height: 480, 
        scrollBars: true, 
        toolBar: true, 
        location: true, 
        status: true, 
        menuBar: true, 
        resizable: true
    },
    open : function(elementObject, settings) {  
        settings = $.extend(false, this.defaults,settings);
        
        var validateParams, $lnk, windowObject;
        
        // Validate Params
        validateParams = function() {
            if (typeof(settings.center) !== "boolean") {
                settings.center = true;
            }
            if (typeof(settings.target) !== "string") {
                settings.target = "_blank";
            }
            if (isNaN(settings.width)) {
                settings.width = 640;
            }
            if (isNaN(settings.height)) {
                settings.height = 480;
            }
            if (typeof(settings.scrollBars) !== "boolean") {
                settings.scrollBars = true;
            }
            if (typeof(settings.toolBar) !== "boolean") {
                settings.toolBar = true;
            }
            if (typeof(settings.location) !== "boolean") {
                settings.location = true;
            }
            if (typeof(settings.status) !== "boolean") {
                settings.status = true;
            }
            if (typeof(settings.menuBar) !== "boolean") {
                settings.menuBar = true;
            }
            if (typeof(settings.resizable) !== "boolean") {
                settings.resizable = true;
            }
        };
    
        validateParams();
        $lnk = $(elementObject);

        windowObject = window.open($lnk.attr("href"), settings.target, this.generateParams(settings));
        windowObject.focus();
        
        return windowObject;
    },
    generateParams: function(settings) {
        var params, $window = $(window),
            width = settings.width,
            height = Math.ceil(settings.height),
            toolBar = settings.toolBar?1:0,
            location = settings.location?1:0,
            status = settings.status?1:0,
            menuBar = settings.menuBar?1:0,
            scrollBars = settings.scrollBars?1:0,
            resizable = settings.resizable?1:0,
            windowW = $window.width(), windowH = $window.height();
        
        params = "";
        if (settings.center) {
            params += "top="+(((windowH-height)/2)+50)+",";         
            params += "left="+(windowW-width)/2+",";
        }
        params += "width=" + width + ",";
        params += "height=" + height + ",";
        params += "toolbar=" + toolBar + ",";
        params += "location=" + location + ",";
        params += "status=" + status + ",";
        params += "menubar=" + menuBar + ",";
        params += "scrollbars=" + scrollBars + ",";
        params += "resizable=" + resizable;
        return params;
    }
};
/***************************************************/
//  Function: $.isIE()
//
//  Developped by: Son Pham
//
//  description: Tells if the browser is Internet Explorer and optionally
//               tells if it's IE version x
// 
//  requirement: jQuery 1.3.2+
//
//  usage:  1) $.isIE();
//          2) $.isIE(6); // returns true if the browser is IE6
//          3) $.isIE("6+"); // returns true if IE version is greater than IE6 (IE6 not included)
//          4) $.isIE("9-"); // returns true if IE version is less than IE9 (IE9 not included)
//          5) $.isIE(">6"); // returns true if IE version is greater than IE6 (IE6 not included)
//          6) $.isIE("<9"); // returns true if IE version is less than IE9 (IE9 not included)
//
//  params:
//  @1 (integer): Number of the internet explorer's version to check
/**********************************************************/
jQuery.isIE = function(version) {
    var ieDetected = false,
        toValidateVersion = false,
        valideVersion = false,
        browserVersion, versionStr;
    
    if ($.browser.msie) { ieDetected = true;}
    
    if (typeof(version) !== "undefined") {
        browserVersion = parseInt($.browser.version,10);
        versionStr = String(version);

        if (versionStr.indexOf("+") !== -1 || versionStr.indexOf("-") !== -1 || versionStr.indexOf("<") !== -1 || versionStr.indexOf(">") !== -1) {
            toValidateVersion = true;

            if (versionStr.indexOf("+") !== -1 || versionStr.indexOf(">") !== -1) {
                versionStr = versionStr.replace(new RegExp(">","gi"),"");
                if (browserVersion > parseInt(versionStr,10)) {
                    valideVersion = true;                   
                }
            } else {
                versionStr = versionStr.replace(new RegExp("<","gi"),"");
                if (browserVersion < parseInt(versionStr,10)) {
                    valideVersion = true;
                }
            }
        } else {
            version = parseInt(version,10);
            if (!isNaN(version)) { // number
                toValidateVersion = true;
                if (browserVersion === version) {
                    valideVersion = true;       
                }
            }
        }
    }
    if (toValidateVersion) {
        return (ieDetected && valideVersion);
    } else {
        return ieDetected;
    }
};
/***************************************************/
//  Function: $.labelOver()
//
//  Developped by: Jean-Francois Payant
//
//  description: Mostly used to place a label over the input text, and when
//               the focus is on the input text the label toggles hide/show
// 
//  requirement: 1) jQuery 1.3.2+
//               2) the <label for="#theIdOfTheInput">...  theIdOfTheInput must be the ID of the input you wish to labelOver
//               3) $.isIE();
//
//  usage:  1) $('label.labelOver').labelOver();
//
//  params:
//  @hideClassName (string): css className to hide the label.  We hide the label by positioning the label -9999px for instance
/**********************************************************/
jQuery.fn.labelOver = function(settings) {
    var defaults, validateParams;
    
    defaults = {
        hideClassName: 'accessAlt'
    };
    
    settings = $.extend(defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.hideClassName) !== "string") {
            settings.hideClassName = "accessAlt";
        }
    };

    return this.each(function(idx) {
        if (idx === 0) { validateParams(); }                                      
                              
        var $label = $(this),
            labelFor = $label.attr('for'), $input;
        
        if (labelFor){
            $input = $('#'+labelFor);
            $label.addClass('labelOverAct').insertBefore($input);

            if ($input.val()) {
                $label.addClass(settings.hideClassName);
            } else if ($.isIE("<9")) {
                $label.css("zoom",1);
            }
            
            $input.focus(function(){
                $label.addClass(settings.hideClassName);
            });
            
            $input.blur(function(){
                if (!$(this).val()) {
                    $label.removeClass(settings.hideClassName);
                }
            });
        }
    });
};
/***************************************************/
//  Function: $.itemGroupLayouting() *** DO NOT USE Internal usage only ****
//
//	version 1.5 (dec. 2010) supports new itemGroup structure
//	version 1.0 (2009)
//
//  Developped by: Jean-Francois Payant, Son Pham
//
//  description: Specific to BELL.ca, this function will set margins to a specific
//               html structure called itemGroup so images and text will be aligned
//               correctly.
//
//               bell.ca contains a lot a itemGroup structure so this function is
//               quite !important
//
//  requirement: 1) jQuery 1.3.2+
//
//  usage:  1) $.itemGroupLayouting();
//
//  params:
//  @context (string): 
/**********************************************************/
jQuery.itemGroupLayouting = function(context) {
    var loadMedias, 
        $itemGroup, $itemFigure, itemFigure, $itemInfo, $img,
        toProcess, itemFloatSide, marginSide, marginOppositeSide,
        margin, itemFigureWidth, imageWidth,
		itemFigureClass = ["itemPict","itemFigure"],
		itemContentClass = ["itemInfo", "sectionContent"];


    loadMedias = function(images) {
        if ($.isFunction($.loadImages)) {
            return (function(image) {
                $.loadImages(image);
            }(images));
        }
    };

    if (typeof(context) === "undefined") {  context = "";  } 
    
    $(".itemGroup", context).each(function(){
        $itemGroup = $(this);
		
		$.each(itemFigureClass, function(idx, value) {
			$itemFigure = $itemGroup.find("."+value+":first");
			if ($itemFigure.length) { return false; }	
		});
        
        $.each(itemContentClass, function(idx, value) {
			$itemInfo = $itemGroup.find("."+value+":first");	
			if ($itemInfo.length) { return false; }
		});

        if ($itemFigure.length && $itemInfo.length) {
            // in order to set the correct margins the browser needs to
            // know the itemPict width
            loadMedias($itemFigure);
            
            toProcess = true;
            
            // We process if and only if the $itemFigure has dimension
            itemFigureWidth = $itemFigure.outerWidth();
            itemFigure = $itemFigure.get(0);
            if (itemFigure.nodeName === "IMG") {
                itemFigureWidth = itemFigure.width;
                if (itemFigureWidth === 0) {
                    toProcess = false;
                }
            } else {
                $img = $itemFigure.find("img");
                if ($img.length) {
                    imageWidth = $img.outerWidth();
                    if (imageWidth === 0) {
                        toProcess = false;
                    } else if ((imageWidth > itemFigureWidth)||($img.length > 1)) {
						itemFigureWidth = imageWidth;
                    }
                } else if (itemFigureWidth === 0) {
                    toProcess = false;
                }
            }
            
            if (toProcess) {
                itemFloatSide = $itemFigure.css("float");
                
                if (itemFloatSide === "none") {
                    if ($itemFigure.css("position") === "absolute"){
                        if (parseInt($itemFigure.css("left"),10) === 0){itemFloatSide = "left";}
                        if (parseInt($itemFigure.css("right"),10) === 0){itemFloatSide = "right";}
                    }
                }
                if (itemFloatSide === "left") {
                    marginSide = "Left";
                    marginOppositeSide = "Right";
                } else {
                    marginSide = "Right";
                    marginOppositeSide = "Left";
                }
                
                if (itemFloatSide === "left" || itemFloatSide === "right") {
                    margin = parseInt(itemFigureWidth, 10) + parseInt($itemFigure.css("margin"+marginOppositeSide), 10);
                    if (margin.valueOf() > 0) {
                        $itemInfo.css("margin"+marginSide, margin + "px");                      
                    }
                }
            } 
        }
    });     
};
/***************************************************/
//  Function: $.txt.[methods]
//
//  Developped by: Son Pham
//
//  description: performs several string common task like count a word
//              number of occurence
//
//  requirement: 1) jQuery 1.3.2+
//
//  usage:  1) var myString = "hello word"
//              $.txt.countWord(myString) // will return 2
//
//          2) $.txt.countWordOccurence('d', myString) // will return 1
//
/**********************************************************/
jQuery.txt = {
    // params : 
    //  @text: (string) text to query against
    countWord: function(text) {
        var nb = 0, i, wordArray;
        
        if (typeof(text)!== "undefined") {
            text = String(text);
            wordArray = text.replace(/\s/g,' ');
            wordArray = wordArray.split(' ');
            for (i=0; i<wordArray.length; i++) {
                if (wordArray[i].length > 0) {
                    nb++;
                }
            }
        }
        return nb;
    },
    // params : 
    //  @word : (string) search word
    //  @text: (string) text to query against
    countWordOccurence: function(word, text) {
        var nb = 0;
        
        if (text.indexOf(word) !== -1) {
            nb = text.split(word).length - 1;       
        }
        return nb;
    }
};

/***************************************************/
// plugin: contentDisplayer
//
// Developped by: Son Pham
//
// description: behaves like the tabs plugin without having to have a required
//              html structure (this is like a tabs lite version).
//              This plugin will also work with scroller contained in the content
// 
// note: doesn't support content history tracking
//
// requirement: 1) jQuery 1.3.2+ (works with jQuery 1.4.2)
//              
//              2) HTML links structure MUST BE in a <ul><li><a></a></li></ul>
//
//
// usage: $(".selector").contentDisplayer({params})
//
// params : 
//  @containerRootClassName : (string) is the root element containing the links default : "cBox"
//  @activeClassName : (string) is the css className to indicate that a link is active default: "active"
//  @equalize: (boolean) indicate if the tallest content height should be set for every content default: false
/**********************************************************/
jQuery.fn.contentDisplayer = function(settings) {
    var defaults, $triggerContainer, $triggerRoot,
        showHide, validateParams;

    defaults = {
        containerRootClassName: "cBox",
        activeClassName: "active",
        equalize: false
    };
    
    settings = $.extend(false,defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.containerRootClassName) !== "string") {
            settings.containerRootClassName = "cBox";
        }
        if (typeof(settings.activeClassName) !== "string") {
            settings.activeClassName = "active";
        }
        if (typeof(settings.equalize) !== "boolean") {
            settings.equalize = false;
        }       
    };

    showHide = function(element) {
        var toRender = false,
            $element = $(element),
            href, $target, targetId, currentId;
            
        $element.each(function() {
            href = $(this).attr("href");
            if (href.indexOf("#") !== -1) {
                targetId = href.split("#")[1];
                if (targetId !== "") {
                    $target = $("#"+targetId);
                    if ($target.length) {
                        toRender = true;
                        currentId = $.data(this,"currentId");
                        if (!currentId) {
                            if ($(this).attr("rel")) {
                                currentId = $(this).attr("rel");
                            }
                        }
                        if (targetId) {
                            $("#"+currentId).addClass("accessAlt").hide().removeClass("accessAlt");
                            $target.removeClass("accessAlt").show();
                        }
                    }
                }
            }
        });
        if (toRender) { 
            if ($.isFunction($.pageRender)) {
                $.pageRender($target, "scroller");
            }
        }
    };

    $("a", this).live("click", function() {
        var $activeLink, activeTargetId,
            $link, $container, $li,
            href, targetId;

        $link = $(this);
        
        $container = $link.parents("ul:first");
        
        // Must validate if links are in UL
        if ($container.length) {
            // reset active
            $li = $("li", $container);
            
            $li.each(function() {
                $activeLink = $(this);
                if ($activeLink.hasClass(settings.activeClassName)) {
                    activeTargetId = $activeLink.find("a:first").attr("href").split("#")[1];
                }
                $activeLink.removeClass(settings.activeClassName);                          
            });
            $link.parents("li:first").addClass(settings.activeClassName);
    
            // keep in memory current active element to be able to hide it later
            href = $link.attr("href");
            if (href.indexOf("#") !== -1) {
                targetId = href.split("#")[1];
                $("a",$li).each(function() {
                    $.data(this,"currentId", activeTargetId);
                });             
            }
            
            // show selected content
            showHide(this);
    
            // You may have notice that "scroller" is used.  That's because
            // the contentDisplayer can contain a scroller and therefore
            // must me initialized when showned to work properly.
            // If your content doesn't contain a scroller then the function
            // will simply ignore the scroller.
            
            // initializing the scroller
            if (typeof($.scroller) === "object") {
                $container = $link.parents("."+settings.containerRootClassName+":first");
                $container.scroller({fillSpace:false, toggle: true});
                
                // updating title
                $.scroller.updateItemsCount($container, "h2");
            }
            return false;
        }       
    });

    return this.each(function(idx) {
        if (idx===0) { validateParams(); }
                              
        $triggerContainer = $(this);
        $triggerRoot = $triggerContainer.parents("."+settings.containerRootClassName+":first");

        if (idx===0) {
            // updating container scroller title once per initialization if applicable
            if ($.isFunction($.scroller.updateItemsCount)) {
                $.scroller.updateItemsCount($triggerRoot,"h2");
            }
        }
    });
};
/***************************************************/
//  Function: $.setClassToNthChild()
//
//  Developped by: Son Pham
//
//  description: Set a className to a nth-position of a selector
//
//  requirement: 1) jQuery 1.3.2+
//
//  usage:  1) $.setClassToNthPosition("ul li",3,"colLast");
//          2) $.setClassToNthPosition($("ul>li"),5,"endOfRow");
//
// params : 
//  @selector : (string/object) list of html elements to apply className
//  @nTh : (number) nth number for each to apply the className
//  @className: (string) css className to apply when nth-child is founded
/**********************************************************/
jQuery.setClassToNthPosition = function(selector, nTh, className) {
    var $element;
    if (selector && !isNaN(nTh)) {      
        $(selector).each(function(idx) {
            $element = $(this);
            $element.removeClass(className);
            if (idx!==0 && (idx+1)%nTh===0) {
                $element.addClass(className);
            }
        });
    }
};
/***************************************************/
//  Function: $.scrollToElement()
//
//  Developped by: Son Pham
//
//	version: 1.5 (november 2010) add callBack support
//	version: 1.0 (march 2010)
//
//  description: Scrolls to an element with an animation
//
//  requirement: 1) jQuery 1.3.2+
//				2) $.runCallBack();
//				3) $.getCallBack();
//
//  usage:  1) $.scrollToElement("#myTargetId");
//          2) $.scrollToElement($(".myClass"),{speed:800,offSet:70}); // note if multiple element founded, only the first one will be considered
//			3) $.scrollToElement("#myTargetId", function() {}); // function as a callBack
//
// params : 
//  @selector : (string/object) html element to scrollTo
//  @speed : (number) optional miliseconds of the animation // default: 500 ms
//  @offSet: (number) optional if you want to specify an offset distance when scroll hits target // default: 200 (in pixel)
/**********************************************************/
jQuery.scrollToElement = function(selector, settings) {
    var $selector = $(selector),
        $element, top, defaults, validateParams,
        hookMouse, unHookMouse, args = [$.getCallBack(arguments)],
        fnScroll = [], winFn;

    defaults = {
        speed: 1500,
        offSet: 50
    };  
    settings = $.extend(false,defaults, settings);

    $.extend(jQuery.easing,{
        fxEaseInOut: function (x, time, b, c, d) {
            if ((time/=d/2) < 1) {return c/2*time*time*time*time + b;}
            return -c/2 * ((time-=2)*time*time*time - 2) + b;
        }
    });

    hookMouse = function() {
        $(document,window).bind("mousewheel", function() {
            return false;
        }).bind("DOMMouseScroll", function() {
            return false;
        });
    };

    unHookMouse = function() {
        var i;
        for (i=0;i<fnScroll.length;i++) {
            $(window).unbind("onscroll").bind("onscroll", fnScroll[i]);
        }
        $(document,window).unbind("mousewheel").unbind("DOMMouseScroll");
    };

    // Validate Params
    validateParams = function() {
        if (isNaN(settings.speed)) {
            settings.speed = 1500;
        }
        if (isNaN(settings.offSet)) {
            settings.offSet = 50;
        }
    };


    if ($selector.length) {
        $element = $($selector[0]);
        validateParams();
        top = $element.offset().top - settings.offSet;
        
        winFn = window.onscroll;
        if (typeof(winFn) === "function") {
            fnScroll.push(winFn);   
        }
        
        $(window).bind("onscroll", function() {
            return false;                           
        });
        hookMouse();
        $("html,body").animate({scrollTop: top}, settings.speed, "fxEaseInOut", function() {
			unHookMouse();
			$.runCallBack(args);
		});       
    }
};
/***************************************************/
//  Function: $.setElementAttributes()
//
//  Developped by: Son Pham
//
//  description: Set a generic HTML element attributes
//
//  requirement: 1) jQuery 1.3.2+
//
//  usage:  1) $.setElementAttributes("#myDivId",{width:"410",height:"700"});
//          2) $.setElementAttributes("#myInput",{name:"myTextBox",type:"radio"});
//
// params : 
//  @selector : (string/object) list of html elements to apply className
//  @attributes: (object) list of hash attribute/value
/**********************************************************/
jQuery.setElementAttributes = function(selector, attributes) {
    var $selector = $(selector);
    if ($selector.length && typeof(attributes) === "object") {
        $selector.each(function() {
            try {
                $(this).attr(attributes);
            } catch(e) {}
        });
    }
};

/***************************************************/
//  Function: $.consoleDebug()
//
//  Developped by: Son Pham
//
//  description: Emulates a console into a DIV (still in basic debug)
//
//  requirement: 1) jQuery 1.3.2+
//
//  usage:  1) $.consoleDebug(MyVal)
//
// params : 
//  @MyVal : (string) variable I want to output
//  @toAppend: (boolean) indicates to append value
/**********************************************************/
jQuery.consoleDebug = function(debugValue, toAppend) {
    var debugId = "debugggg",
        $consoleLog = $("#"+debugId);
        
    if ($consoleLog.length===0) {
        $consoleLog = $('<div id="'+debugId+'"></div>');
        $consoleLog.css({
            position: $.isIE(6)?"absolute":"static",
            right: "10px",
            padding: "10px",
            top: "10px",
            border: "1px solid #fa0808",
            backgroundColor: "#0835fa",
            color: "#fff"
        });
        $("body").append($consoleLog);
    }
    if (typeof toAppend === "undefined" || toAppend) {
        $consoleLog.html($consoleLog.html()+debugValue+"<br>");
    } else {
        $consoleLog.html(debugValue);       
    }
};
//*****************************************************
//  function: $.convertToPDF() ** STILL IN DEV **
//
//	version: 1.0 (november 17th, 2010)
//
//  developed by: Son Pham
//
//  description: specific to BEll.ca is a function that allows
//				developers to pass a string or url to a third party application
//				to convert the parameter into a PDF document	
//
//  scenario: used on "convert to PDF" links
//
//  Requirement: 1) jQuery 1.4.2
//
//  usage:  1) $.convertToPDF.html(text, {params});  // params is optional
//          2) $.convertToPDF.url(url, {params}); // url and params are optional
//          3) $.convertToPDF.showError("My Title","Error Text"); 
//
//  params: (see method setParams)
//*****************************************************
jQuery.convertToPDF = {
	fieldHTML : "htmlText",
	fieldURL : "urlText",
	fieldPDFFileName : "pdfFileName",
	documentType : "<!DOCTYPE HTML PUBLIC \"-\/\/W3C\/\/DTD HTML 4.01\/\/EN\" \"http:\/\/www.w3.org\/TR\/html4\/strict.dtd\">",
	
    html : function(HTMLStr, settings) {
        var i, textString, settingsObj;
        for (i=0;i<arguments.length;i++) {
            if (typeof arguments[i] === "string") {
                textString = arguments[i];
            } else if (typeof arguments[i] === "object") {
                settingsObj = arguments[i]; 
            }
        }
        if (textString) {
            if (!settingsObj) { settingsObj = this.setParams({}); }
			settingsObj.fields[$.convertToPDF.fieldHTML] = textString;
			settingsObj.fields = $.extend(false, this.setParams({}).fields, settingsObj.fields);   
        } 
		if (settingsObj) {
			settingsObj.fields = $.extend(false, this.setParams({}).fields, settingsObj.fields);
		} else { settingsObj = {}; }
        this.convert("html", this.setParams(settingsObj));
        return false;
    },
    url : function(urlStr, settings) {
        var i, urlString, settingsObj;
        for (i=0;i<arguments.length;i++) {
            if (typeof arguments[i] === "string") {
                urlString = arguments[i];
            } else if (typeof arguments[i] === "object") {
                settingsObj = arguments[i]; 
            }
        }
        if (urlString) {
            if (!settingsObj) { settingsObj = this.setParams({}); }
			settingsObj.fields[$.convertToPDF.fieldURL] = urlString;
			settingsObj.fields = $.extend(false, this.setParams({}).fields, settingsObj.fields);   
        }
		if (settingsObj) {
			settingsObj.fields = $.extend(false, this.setParams({}).fields, settingsObj.fields);
		} else { settingsObj = {}; }
        this.convert("url", this.setParams(settingsObj));
        return false;
    },
    showError: function(title, message) {
        var $error = $("#convertErrorPDF"); 
        
        if ($error.length === 0) {
            $error = $("<div/>", {
                id : "convertErrorPDF",
                "class" : "hide"
            });
        
            $error.append("<p class='lightBoxTitleJs'>"+title+"</p><div class='lbLining'><div class='lining'>"+message+"<\/div><\/div>").appendTo("body");
        }
        if (!$.isEmptyObject($.lightBox)) {
            $.lightBox.showInPage($error);  
        }
    },
    setParams: function(settings) {
        var defaults = {
            form: { 
                id: "html2PDFForm",
                action: "/shopping/Html2PdfServlet",
                method: "post"
            },
            fields: {},
            iframe: {
                id: "html2PDFFrame",
                src: ""
            },
			docType: $.convertToPDF.documentType
        };
		defaults.fields[$.convertToPDF.fieldURL] = "";
        defaults.fields[$.convertToPDF.fieldHTML] = "";
		defaults.fields[$.convertToPDF.fieldPDFFileName] = "";	
		
        settings = $.extend(false, defaults, settings);
        return settings;
    },
    convert : function(from, settings) {
        var $form, $iframe, hiddenFieldsHTML = "",
            $url, fileName = "", html = "";
        
        $form = $("#"+settings.form.id);
        
        if ($form.length === 0){
            $form = $("<form/>", {
                id: settings.form.id,
                name: settings.form.id,
                action: settings.form.action,
                method: settings.form.method,
                submit: function() {
                    this.target = settings.iframe.id;
                }
            });
            $form.appendTo("body");
            
			$.each(settings.fields, function(field, val) {
				hiddenFieldsHTML += '<input type="hidden" id="'+field+'" name="'+field+'" />';                                         
			});
			$form.append(hiddenFieldsHTML);
			
			$.each(settings.fields, function(field, val) {
				$("#"+field).val(val);                   
			});
            
			if (!$.isIE()) {
				$iframe = $("<iframe/>", {
					id: settings.iframe.id,
					name: settings.iframe.id,
					src: settings.iframe.src
				}).appendTo("body");
			} else {
				$("body").append('<iframe class="" name="'+settings.iframe.id+'" id="'+settings.iframe.id+'"></iframe>');	
			}
        }
        
		// fileName
		if (settings.fields[$.convertToPDF.fieldPDFFileName] === "") {
			fileName = $("title").html()+".pdf";
			fileName = fileName.split(' ').join('_'); 
			$("#"+$.convertToPDF.fieldPDFFileName).val(fileName);
		} else {
			fileName = settings.fields[$.convertToPDF.fieldPDFFileName];	
		}

        if (from === "html") {
			// reset url
			$("#"+$.convertToPDF.fieldURL).val("");
			
			if (settings.fields[$.convertToPDF.fieldHTML] !== "") { 
				// custom html 
				html = settings.fields[$.convertToPDF.fieldHTML];				
			} else { 
				// current page html
				html = settings.docType+"<html>"+$("html").html()+"</html>";
			}
			$("#"+$.convertToPDF.fieldHTML).val(html);		
		} else {
             // reset HTML
			 $("#"+$.convertToPDF.fieldHTML).val("");
             
			 /*global location */
             $url = $("#"+$.convertToPDF.fieldURL);
             $url.val($url.val() !== ""?$url:$(window.location).attr("href"));
        }

		$("#"+$.convertToPDF.fieldPDFFileName).val(fileName);        
        $form.submit();
    }
};
//*****************************************************
//  function: $.detect.[features]
//
//	version: 1.0 (novembre 2010)
//
//  developed by: Son Pham
//
//  description: Feature detection
//
//  scenario: Use this function when you need to know if a
//				feature is enabled
//
//  Requirement: 1) jQuery 1.3.2+
//
//  usage:  1) $.detect.positionFix()
//*****************************************************
jQuery.detect = {
	canvas: function() {
		if (document.createElement) {
			var elCanvas = document.createElement("canvas");
			return !!(elCanvas && elCanvas.getContext && elCanvas.getContext("2d"));
		}
		return false;
	},
	html5: function() {
		return this.canvas();	
	},
	events:	function(eventName){
		var el = document.createElement("div"),
			supported = false;
		
		eventName = 'on' + eventName;
		supported = (eventName in el);
		if (!supported) {
			el.setAttribute(eventName, 'return;');
			supported = typeof el[eventName] == 'function';
		}
		$(el).remove();
		return supported;
	},
	touch: function() { // Webkit 
		return this.events("touchstart");	
	},
	isMac: function() {
		/*global navigator*/
		return RegExp("Mac").test(navigator.userAgent);
	},
	mobile: function() { // not safe but in this case I must use user agent
		return RegExp("Mobile").test(navigator.userAgent);
	},
	mobileDevice: function() { // not safe but in this case I must use user agent
		if (!this.mobile()) {
			return null;
		}
		var fields = RegExp("(Mozilla/5.0 \\()([^;]+)").exec(navigator.userAgent);
		if (!fields || fields.length < 3) {
			return null;
		}
		
		if (typeof fields[2] === "string") {
			return fields[2].toLocaleLowerCase();	
		} else {
			return null;
		}	
	},
	iDevice: function() { // iPad, iPhone, iPod
		var iOS = ["ipad","iphone","ipod"], i;

		if (this.mobile() && this.touch() && this.html5()) {
			for (i=0;i<iOS.length;i++) {
				if (this.mobileDevice().indexOf(iOS[i]) !== -1) {
					return true;	
				}
			}
		}
		return false;
	}
};
//*****************************************************
//  function: $().stickyElement()
//
//	version: 1.0 (october 2010)
//
//  developed by: Son Pham
//
//  description: Will stick an element to a fixed position
//					after a certain interval										
//
//  scenario: Use this function when position: fixed is not supported
//
//  Requirement: 1) jQuery 1.3.2+
//
//  usage:  1) $(".selector").stickyElement(params)
//
//	params:
//  @offSetY : (number) offSet Y will be added to the current position default: 0
//  @interval: (number) interval before each re-positioning computing default: 250 ms
//	@position: (string) sets the position of the element (top | center | right) default: "top"
//*****************************************************
jQuery.fn.stickyElement = function(settings) {
    var defaults, stickIt, oldPosition, validateParams;

    defaults = {
		offSetY: 0,
		interval: 250,
		position: "top" // top|center|bottom
    };
    
    settings = $.extend(false,defaults, settings);
	
    // Validate Params
    validateParams = function() {
        if (typeof(settings.offSetY) !== "number") {
            settings.offSetY = 0;
        }
        if (typeof(settings.interval) !== "number") {
            settings.interval = 250;
        }
        if (typeof(settings.position) !== "string") {
            settings.position = "top";
        } else if (settings.position !== "top" || settings.position !== "center" || settings.position !== "bottom") {
			settings.position = "top";
		}
    };
	
	oldPosition = settings.offSetY;
		
	stickIt = function($element) {
		var pos, positionTimerId, winH = window.innerHeight ? window.innerHeight : $(window).height();
		
		if (window.innerHeight) {
			pos = window.pageYOffset;
		} else if (document.documentElement && document.documentElement.scrollTop) {
			pos = document.documentElement.scrollTop;
		} else if (document.body) {
			pos = document.body.scrollTop;
		}

		if (settings.position === "top") {
			if (pos < settings.offSetY) {
				pos = settings.offSetY;
			} else {
				pos += settings.offSetY;
			}
		} else if (settings.position === "bottom") {
			pos += winH - $element.height();
			$element.css("bottom","inherit");
		} else {
			pos += (winH - $element.height())/2;
		}

		if (pos === oldPosition) {
			$element.css({
				top: pos+"px"
			});
		}

		oldPosition = pos;
		positionTimerId = setTimeout(function() {
			stickIt($element);		
		},settings.interval);		
	};
	
	return this.each(function() {
		stickIt($(this));
	});
};
//*****************************************************
//  function: $().fontSizeSwitcher()
//
//	version: 1.0 (feb 2011)
//
//  developed by: Son Pham
//
//  description: Will set a class to an HTML targeted element
//				the class will be the String after your passed selector to the plugin
//
//  Requirement: 1) jQuery 1.3.2+
//				2) jQuery.getSelector
//				3) this version allows only a single selector of type class e.g (.selector) passing an ID will not work e.g (#selector)
//				4) When passing multiple class as a selector, the first class will be used
//
//  usage:  1) $(".selector").fontChanger(params);
//
//	Note: if your selector is "fontSizerSize1" the plugin will add the class Size1	
//
//	params:
//  @target : (string) representing the target HTML to add the size class to default "body"
//	@slug: : (string) is the string used to be appended to the selector to get the size value default "Size"
//	@lowerCase: (boolean) indicate whenever or not to lowerCase the first letter of the Slug. default: true
//	@persistent: (boolean) indicate whenever or not to add a cookie to remember size (cookies must be enabled) default: false
//*****************************************************************************************
jQuery.fn.fontSizeSwitcher = function(settings) {
	var defaults, getSize, removeSize, setPersistence,
		validateParams, selector = this.selector, selectors = this;
	
	defaults = {
		target: "body",
		slug: "Size",
		lowerCase: true,
		persistent: true
	};
	
	settings = $.extend(false, defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.target) !== "string") {
            settings.target = "body";
        }
        if (typeof(settings.slug) !== "string") {
            settings.slug = "Size";
        }
        if (typeof(settings.lowerCase) !== "boolean") {
            settings.lowerCase = true;
		}
        if (typeof(settings.persistent) !== "boolean") {
            settings.persistent = false;
		}
    };
	
	getSize = function(selector, cssClass) {
		var size, sizeArr;
		if (cssClass.indexOf(selector) !== -1) {
			sizeArr = cssClass.split(selector+settings.slug);
			if (sizeArr.length > 1) {
				size = sizeArr[1];
				return selector+settings.slug+size;
			}
		}
		return size;
	};
	
	removeSize = function($target) {
		var size;
		selectors.each(function() {
			size = $.data(this,"fontSize");
			if (size) {
				$target.removeClass(size);
			}
		});
		return $target;
	};
	
	setPersistence = function(fontSizeClass) {
		if (typeof $.cookies === "object") {		
			var cookieName = "fontSizer", fontClass;
			fontClass = $.cookies.get(cookieName);
			if (settings.persistent) {
				if (typeof fontSizeClass !== "undefined") {
					$.cookies.set(cookieName,fontSizeClass);
				} else if (typeof fontClass !== "object" && typeof fontClass !== "undefined") {
					$(settings.target).addClass(fontClass);
				}
			} else {
				if (typeof fontClass === "object") {
					$.cookies.remove(cookieName);
				}
			}
		}
	};
	
	return this.each(function(idx) {
		if (idx === 0) {
			validateParams();
			selector = $.getSelector(selector);
			setPersistence();
		}

		var $element = $(this),
			$target = $(settings.target), size;
		
		if ($target.length) {				
			if (typeof selector !== "undefined") {
				size = getSize(selector, this.className);
				if (typeof size !== "undefined") {
					$.data($element.get(0), "fontSize", size);
					$element.click(function() {
						removeSize($target).addClass(size);
						setPersistence(size);						
						return false;
					});
				}
			}
		}
	});
};
//*****************************************************
//  function: $.getSelector() **** INTERNAL USAGE for plugins *****
//
//	version: 1.0 (march 2011)
//
//  developed by: Son Pham
//
//  description: Sometimes plugins need to know what was the selector passed in the function
//					without the "." or "#" to append with another word example: toggle -> toggleOpen
//
//  Requirement: 1) jQuery 1.3.2+
//
//  usage:  1) $.getSelector(selector, onlyFirst);
//				ex: $.getSelector(".toggle"); // will return "toggle"
//				ex: $.getSelector(".toggle .toggleThemeA", true); // will return "toggle" the first one
//				ex: $.getSelector(".toggle .toggleThemeA", false); // will return "toggle toggleThemeA"
//				ex: $.getSelector("#myId"); // will return "myId"
//				ex: $.getSelector("#myId .toggle", true); // will return "myId" the last one
//				ex: $.getSelector("#myId .toggle", false); // will return "myId toggle" original
//
//	params:
//  @selector : (string) string representing the selector
//	@onlyFirst: (boolean) indicate whenever function returns only first selector or only the original one default: true
//*****************************************************************************************
jQuery.getSelector = function(selector, onlyFirst) {
	if (typeof selector === "string" && selector.length && $.trim(selector).length) {
		var str, arr = selector.split(" ");

		if (typeof onlyFirst !== "boolean") {
			onlyFirst = true;	
		}

		if (arr.length) {
			if (arr.length || onlyFirst) {			
				str = arr[arr.length-1];
			} else {
				str = selector;
			}
			return str.replace(new RegExp("#","gi"),"").replace(/\./gi,"");	
		}
	}
	return "";
};
//*****************************************************
//  function: $.getTheme() **** INTERNAL USAGE for plugins *****
//
//	version: 1.0 (march 2011)
//
//  developed by: Son Pham
//
//  description: Bell UIKit uses themes to style Bell UIKit components
//				So many plugins may need to get the component theme
//
//  Requirement: 1) jQuery 1.3.2+
//
//  usage:  1) $.getTheme(selector, className);
//				ex: $.getTheme(".toggle", ".toggle .toggleThemeA"); // will return "toggleThemeA"
//				ex: $.getTheme(".toggle", ".toggleThemeA themeB"); // will return "toggleThemeA"
//				ex: $.getTheme(".toggle", ".toggleTheme"); // will return ""
//
//	params:
//  @selector: (string) search word in className
//	@className: (string) string containing the className value
//*****************************************************************************************
jQuery.getTheme = function(selector, className) {
	if (typeof selector === "string" && selector.length && typeof className === "string" && className.length) {
		if (selector.indexOf(" ") !== -1) {
			selector = $.getSelector(selector);	
		}
		className = className.replace(/\#/gi,"").replace(/\./gi,"");
		selector = selector.replace(/\#/gi,"").replace(/\./gi,"");
				
		var arr, theme = selector+"Theme";		
		
		if (className.indexOf(theme) !== -1) {
			arr = className.split(theme);
			if (arr.length > 1 && arr[1] !== "") {
				if (arr[1].indexOf(" ") !== -1) {
					return theme+arr[1].split(" ")[0];		
				} else {
					return theme+arr[1];
				}
			}
		}
	}
	return "";
};
/***************************************************/
// plugin: $().splitter()
//
// Developped by: Son Pham
//
// version: 1.0 (april 9, 2011)
//
// description: will split any separated item equaly taking
//				in consideration the margin for example
// 
// requirement: 1) jQuery 1.4+
//				2) $.isIE()
//
// usage:	1) $(".selector").splitter({separator:['.column']});
//
// settings: 
// @separator (array of string): elements to be separated default: [".splitJs",".column"]
// @substract (array of string): css properties to be substracted from separeted elements default: ["marginRight", "paddingLeft", "paddingRight"]
// @exclude (array of string): elements by className to exclude from the split calculation default: []
// @automatic (boolean) : indicates whenever to automaticaly split first level childrens default: false	
/**********************************************************/
jQuery.fn.splitter = function(settings) {
	var defaults, validateParams, splitIt;
	
	defaults = {
		separator: [".splitJs",".column"],
		substract: ["marginRight", "paddingLeft", "paddingRight"],
		exclude: [],
		automatic: false
	};
	
	settings = $.extend(false, defaults, settings);

    // Validate Params
    validateParams = function() {
        if (typeof(settings.separator) !== "object") {
            if (typeof(settings.separator.push) !== "function") {
				settings.separator = [".column"];
			}
        }
        if (typeof(settings.substract) !== "object") {
            if (typeof(settings.substract.push) !== "function") {
				settings.substract = ["marginRight", "paddingLeft", "paddingRight"];
			}
        }
        if (typeof(settings.exclude) !== "object") {
            if (typeof(settings.exclude.push) !== "function") {
				settings.exclude = [];
			}
        }		
        if (typeof(settings.automatic) !== "boolean") {
			settings.automatic = false;
		}
    };
	
	splitIt = function($element, $splittedItems) {
		var width, elementWidth, finalWidth, subWidth, $splitItem, $lastItem, extraWidth = 0;
			
		if (settings.exclude.length) {
			$splittedItems = $splittedItems.not(settings.exclude.toString());
		}
		if ($splittedItems.length > 1) {
			elementWidth = $element.width();
			// exclude items from width calculation
			if (settings.exclude.length) {
				$.each(settings.exclude, function(idx, value) {
					elementWidth -= $element.find(value).outerWidth(true);
				});				
			}
			// border problem: since borders adds width to an element we must substract them
			$splittedItems.each(function() {
				$splitItem = $(this);
				if ($splitItem.css("border-right-width") !== "") {
					elementWidth -= parseInt($splitItem.css("border-right-width"),10);
				}
				if ($splitItem.css("border-left-width") !== "") {
					elementWidth -= parseInt($splitItem.css("border-left-width"),10);				
				}
			});
			
			width = elementWidth/$splittedItems.length;
			$splittedItems.each(function() {
				$splitItem = $(this);
				subWidth = 0;
				$.each(settings.substract, function(subIdx, subValue) {
					subWidth += parseInt($splitItem.css(subValue),10);
				});
				finalWidth = width-(subWidth);
				if (String(finalWidth).indexOf(".") !== -1) {
					extraWidth += parseFloat("0."+String(finalWidth).split(".")[1]);
				}
				$splitItem.width(finalWidth);
			});
			if ($.isFunction($.isIE)) {				
				if ($.isIE("<9")) {
					$lastItem = $splittedItems.last();
					$lastItem.width($lastItem.width()+Math.ceil(extraWidth)-1);
				}
			}
		}		
	};

	return this.each(function(idx) {
		if (idx === 0) {
			validateParams();	
		}
		var $element = $(this);
		if (settings.automatic) {
			splitIt($element, $element.children());
		} else {
			$.each(settings.separator, function(idx, value) {
				splitIt($element, $element.find(value));
			});
		}
	});
};
/***************************************************/
// plugin: $().maximizeTable()
//
// Developped by: Son Pham
//
// version: 1.0 (mar. 18, 2011)
//
// description: Will set a width to the table based on
//				the largest tr (tableRow).
// 
// requirement: 1) jQuery 1.4+
//
// usage:	1) $(".selector").maximizeTable();
//
/**********************************************************/
jQuery.fn.maximizeTable = function() {
	return this.each(function() {
		var $element = $(this), trWidth, largestWidth = 0;
		$element.find("tr").each(function() {
			trWidth = $(this).width();
			if (trWidth > largestWidth) {
				largestWidth = trWidth;
			}
		});
		if (largestWidth > 0) {
			$element.css("table-layout","fixed").width(largestWidth);		
		}
	});
};
/***************************************************/
// plugin: $().alternater()
//
// Developped by: Son Pham
//
// version: 1.0 (april. 1, 2011)
//
// description: will add aternate CSS className to even/odd html elements
// 
// requirement: 1) jQuery 1.4+
//
// usage:	1) $(".selector").alternater(); // defaults
//			2) $(".selector").alternater({similarItems:"myDiv"}); // will alternate on only HTML elements having myDiv as a className 
//
// settings: 
// @similarItem (string): if specified the alternate will occur on those items otherwise it will be the child default = ""
// @even (string): even CSS className default = "even"
// @odd (string): odd CSS className default = "odd"
/**********************************************************/
jQuery.fn.alternater = function(settings) {
	var defaults, validateParams;
	
	defaults = {
		similarItem: "",
		even: "even",
		odd: "odd"
	};
	
	settings = $.extend(false, defaults, settings);
	
	// Validate Params
    validateParams = function() {
        if (typeof(settings.similarItem) !== "string") {
			settings.similarItem = "";
        }
        if (typeof(settings.even) !== "string") {
			settings.even = "even";
        }
        if (typeof(settings.odd) !== "string") {
			settings.odd = "odd";
        }				
    };
	
	return this.each(function(idx) {
		if (idx === 0) {
			validateParams();	
		}
		var $element = $(this), $elements;
		if ($.trim(settings.similarItem) === "") {
			$elements = $element.children(); 
		} else {
			$elements = $element.find("."+settings.similarItem); 
		}
		
		$elements.each(function(idx) {
			if (idx%2 === 0) {
				$(this).addClass(settings.even);	
			} else {
				$(this).addClass(settings.odd);				
			}
		});
	});
};
/***************************************************/
// plugin: $.displayElement()
//
// Developped by: Son Pham
//
// version: 1.0 (april. 26, 2011)
//
// description: sometimes developers need an element to be visible in order
//				to get its dimension
// 
// requirement: 1) jQuery 1.3.2+
//
// usage:	1) $.displayElement(element, function() { // do stuff in callBack}); // after first parent visible is displayed, callBack function will be executed then this element will be hidden
//
// parameters: 
// @element (object): indicates whenever to hide previoulsy displayed element
// @callBack (function): callBack function to call after element is visible
/**********************************************************/
jQuery.displayElement = function(element, fn) {
	var $element = $(element), displayIt, $visibleNode, theNode;
	
	displayIt = function($element) {
		if (!$element.is(":visible")) {
			$.data($element.parent().get(0), "last", $element); 
			return displayIt($element.parent());
		} else {
			return $element;
		}
	};
	
	if ($element.length & typeof fn === "function") {
		if ($.data(displayIt($element).get(0),"last")) {
			$visibleNode = $($.data(displayIt($element).get(0),"last"));
			$visibleNode.show();
			fn.call();
			$visibleNode.hide();
		} else {
			fn.call();	
		}
	}
};
}(jQuery));
