/**
 * $Id: delayedpopupinterface.js 64367 2009-02-20 01:56:36Z kchiu $
 * $Author: kchiu $
 * $Revision: 64367 $
 * $Name$
 * $Date: 2009-02-19 17:56:36 -0800 (Thu, 19 Feb 2009) $
 *
 * @jsRequire interfaces.Interface
 * @jsRequire interfaces.PopupInterface
 *
 *
 * @version    $Revision: 64367 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 * @see        interfaces.Interface
 */

/**
 * DelayedPopupInterface Constructor / Definition
 *
 * This interface is built on top of the Interface object
 * and is NOT intended to be instantiated directly. See
 * documentation on interfaces.Interface for a complete
 * explanation.
 *
 * @access public
 * @since  v1.1
 * @return DelayedPopupInterface
 */
function DelayedPopupInterface() {
    this.elemId      = null;
    this.visible     = false;
    this.linked      = new Array;
    this.timer       = null;
    this.delay       = null;
    this.hide        = DelayedPopupInterface_Hide;
    this.show        = DelayedPopupInterface_Show;
    this.toggle      = PopupInterface_Toggle;
    this.cancelTimer = DelayedPopupInterface_CancelTimer;
    this.implement(PopupInterface);
    return this;
}

// Setup DelayedPopupInterface prototype chain
DelayedPopupInterface.prototype             = new PopupInterface;
DelayedPopupInterface.prototype.constructor = DelayedPopupInterface;
DelayedPopupInterface.superclass            = PopupInterface.prototype;

/**
 * Calls PopupInterface_Hide after timer runs out.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function DelayedPopupInterface_Hide() {
    this.cancelTimer();
    var obj = this;
    this.timer = setTimeout(function() {
        PopupInterface_Hide.call(obj);
        obj.timer = null;
    }, this.delay);
    return true;
}

/**
 * Calls PopupInterface_Show after timer runs out.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function DelayedPopupInterface_Show() {
    this.cancelTimer();
    var obj = this;
    this.timer = setTimeout(function() {
        PopupInterface_Show.call(obj);
        obj.timer = null;
    }, this.delay);
    return true;
}

/**
 * Cancels any currently running timers.
 *
 * This effectively stops the show / hide / toggle
 * functions in their tracks, allowing us to cancel
 * them at any time.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function DelayedPopupInterface_CancelTimer() {
    if (this.timer) {
        clearTimeout(this.timer);
        this.timer = null;
    }
    return true;
}
/**
 * $Id: roundedcornersinterface.js 76074 2009-11-19 20:53:10Z kchiu $
 * $Author: kchiu $
 * $Revision: 76074 $
 * $Name$
 * $Date: 2009-11-19 12:53:10 -0800 (Thu, 19 Nov 2009) $
 *
 * @jsRequire DomUtils
 * @jsRequire interfaces.Interface
 * @jsRequire classes.ResourceManager
 *
 *
 * @version    $Revision: 76074 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 * @see        interfaces.Interface
 */

/**
 * RoundedCornersInterface Constructor / Definition
 *
 * This interface is built on top of the Interface object
 * and is NOT intended to be instantiated directly. See
 * documentation on interfaces.Interface for a complete
 * explanation.
 *
 * @access public
 * @since  v1.1
 * @return RoundedCornersInterface
 */
function RoundedCornersInterface() {
    this.elemId       = null;
    this.cornerStyle  = null;
    this.init         = RoundedCornersInterface_Init;
    this.draw         = RoundedCornersInterface_Draw;
    this.erase        = RoundedCornersInterface_Erase;
    this.cornersDrawn = false;
    this.init();
}

// Setup RoundedCornersInterface prototype chain
RoundedCornersInterface.prototype             = new Interface;
RoundedCornersInterface.prototype.constructor = RoundedCornersInterface;
RoundedCornersInterface.superclass            = Interface.prototype;






/****** BEGIN EDIT SECTION ******/

/**
 * Rounded corners style definitions.
 *
 * This data structure allows for the definition of various different
 * rounded corners "styles" that can be applied by setting the roundedCornersStyle
 * of the object implementing RoundedCornersInterface.
 *
 * Example:
 *
 *    <script language="JavaScript">
 *    RoundedCornersInterface.settings.style = 'Default';
 *    var popup = new RoundedCornersPopup();
 *    </script>
 *
 * You can also define a rounded corner style at any time after
 * inclusion of this file and then reference that style instead if you
 * like.
 *
 * Note: This style definition is site-wide, not object specific. This
 * will be changing in the near future as this interface adopts the
 * same style interface that DropShadowInterface uses.
 *
 * @access public
 * @since  v1.1
 * @todo   Add .roundedCornersStyle to interface (see DropShadowInterface)
 * @var    RoundedCornersInterface.styles   struct
 */
RoundedCornersInterface.styles = {
    Default: {
        images: {
            tr: { src: 'http://i.pgcdn.com/images/balloon/top_right_6x6.gif',    width: 6, height: 6 },
            tl: { src: 'http://i.pgcdn.com/images/balloon/top_left_6x6.gif',     width: 6, height: 6 },
            bl: { src: 'http://i.pgcdn.com/images/balloon/bottom_left_6x6.gif',  width: 6, height: 6 },
            br: { src: 'http://i.pgcdn.com/images/balloon/bottom_right_6x6.gif', width: 6, height: 6 }
        }
    }
};

/**
 * General settings struct.
 *
 * @access public
 * @since  v1.1
 * @var    RoundedCornersInterface.settings  struct
 *
 */
RoundedCornersInterface.settings = { style: 'Default' };

/****** END EDIT SECTION ******/








/**
 * Internal image ids used for keeping track of image resources.
 *
 * !DO NOT MODIFY THIS!
 *
 * @access private
 * @since  v1.1
 * @var    RoundedCornersInterface.imgIds   struct
 */
RoundedCornersInterface.imgIds   = { tr: 0, tl: 1, bl: 2, br: 3 };

/**
 * Initializes an object that implements the RoundedCornersInterface.
 * Call this function prior to any draw() functions.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function RoundedCornersInterface_Init() {
    var style = RoundedCornersInterface.styles[RoundedCornersInterface.settings.style];
    if (typeof(window.preloadImage) == 'function') {
        window.preloadImage(style.images.tr.src, style.images.tr.width, style.images.tr.height);
        window.preloadImage(style.images.tl.src, style.images.tl.width, style.images.tl.height);
        window.preloadImage(style.images.bl.src, style.images.bl.width, style.images.bl.height);
        window.preloadImage(style.images.br.src, style.images.br.width, style.images.br.height);
    }
} // End RoundedCornersInterface_Init

/**
 * "Draws" the actual rounded corners by creating the necessary dom elements and applying them to
 * the object's element.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function RoundedCornersInterface_Draw() {
    //window.messageQueue.add( new Message('RoundedCornersInterface_Draw', 'called') );
    if (this.cornersDrawn) { RoundedCornersInterface_Erase.call(this); }
    var elem = document.getElementById(this.elemId);
    if (elem) {
        //if (typeof(writeDebug) == 'function') writeDebug('drawing background...');
        var style = RoundedCornersInterface.styles[RoundedCornersInterface.settings.style];
        /** BACKGROUND **/
        var div                   = document.createElement('div');
        div.id                    = 'roundedCorners_Background';
        div.style.position        = 'absolute';
        div.style.left            = style.images.tl.width+'px';
        div.style.top             = style.images.tl.height+'px';
        var eHeight  = DomUtils.getElementHeight(elem);
        var tlHeight = style.images.tl.height;
        var blHeight = style.images.bl.height;
        //window.messageQueue.add( new Message(funcname(this), 'getting width') );
        var eWidth   = DomUtils.getElementWidth(elem);
        var tlWidth  = style.images.tl.width;
        var blWidth  = style.images.bl.width;
        div.style.height          = (parseInt(eHeight)-tlHeight-blHeight)+'px';
        div.style.width           = (parseInt(eWidth)-tlWidth-blWidth)+'px';
        div.style.backgroundColor = '#ffffff';
        div.style.zIndex          = '-1';
        //if (typeof(writeDebug) == 'function') writeDebug('background zIndex: '+div.style.zIndex);
        elem.appendChild(div);
        elem.style.backgroundColor = 'transparent';
        
        /** EDGES **/
        //if (typeof(writeDebug) == 'function') writeDebug('drawing bottom edge...');
        // Bottom edge
        div                       = document.createElement('div');
        div.id                    = 'roundedCorners_BottomEdge';
        div.style.position        = 'absolute';
        div.style.left            = style.images.bl.width+'px';
        div.style.top             = (parseInt(DomUtils.getElementHeight(elem))-style.images.bl.height)+'px';
        div.style.height          = (style.images.bl.height)+'px'; // -1 accounts for bottom border
        //window.messageQueue.add( new Message(funcname(this), 'getting bottom width') );
        div.style.width           = (parseInt(DomUtils.getElementWidth(elem)) - style.images.bl.width - style.images.br.width)+'px';
        div.style.borderBottom    = '1px solid #999999';
        div.style.backgroundColor = '#ffffff';
        div.style.overflow        = 'hidden';
        elem.appendChild(div);
        //if (typeof(writeDebug) == 'function') writeDebug('drawing top edge...');
        // Top edge
        div                       = document.createElement('div');
        div.id                    = 'roundedCorners_TopEdge';
        div.style.position        = 'absolute';
        div.style.left            = style.images.tl.width+'px';
        div.style.top             = '0px';
        div.style.height          = (style.images.tl.height)+'px'; // -1 accounts for top border
        //window.messageQueue.add( new Message(funcname(this), 'getting top width') );
        div.style.width           = (parseInt(DomUtils.getElementWidth(elem))-style.images.tl.width-style.images.tr.width)+'px';
        div.style.borderTop       = '1px solid #999999';
        div.style.backgroundColor = '#ffffff';
        div.style.overflow        = 'hidden';
        elem.appendChild(div);
        // Left edge
        //if (typeof(writeDebug) == 'function') writeDebug('drawing left edge...');
        div                       = document.createElement('div');
        div.id                    = 'roundedCorners_LeftEdge';
        div.style.position        = 'absolute';
        div.style.left            = '0px';
        div.style.top             = style.images.tl.height+'px';
        div.style.width           = (style.images.tl.width)+'px'; // -1 accounts for left border
        div.style.height          = (parseInt(DomUtils.getElementHeight(elem)) - style.images.tl.height - style.images.bl.height)+'px';
        div.style.borderLeft      = '1px solid #999999';
        div.style.backgroundColor = '#ffffff';
        div.style.overflow        = 'hidden';
        elem.appendChild(div);
        //if (typeof(writeDebug) == 'function') writeDebug('drawing right edge...');
        // Right edge
        div                       = document.createElement('div');
        div.id                    = 'roundedCorners_RightEdge';
        div.style.position        = 'absolute';
        //window.messageQueue.add( new Message(funcname(this), 'getting right width') );
        div.style.left            = (parseInt(DomUtils.getElementWidth(elem))-style.images.tr.width)+'px';
        div.style.top             = style.images.tr.height+'px';
        div.style.width           = (style.images.tr.width)+'px';
        div.style.height          = (parseInt(DomUtils.getElementHeight(elem))-style.images.tr.height-style.images.br.height)+'px';
        div.style.borderRight     = '1px solid #999999';
        div.style.backgroundColor = '#ffffff';
        div.style.overflow        = 'hidden';
        elem.appendChild(div);
        /** CORNERS **/
        //if (typeof(writeDebug) == 'function') writeDebug('drawing top right corner...');
        // Top right
        var img                   = document.createElement('img');
        img.id                    = 'roundedCorners_TopRightCorner';
        img.src                   = style.images.tr.src;
        img.height                = style.images.tr.height;
        img.width                 = style.images.tr.width;
        img.border                = 0;
        img.style.position        = 'absolute';
        //window.messageQueue.add( new Message(funcname(this), 'getting tr width') );
        img.style.left            = parseInt(parseInt(DomUtils.getElementWidth(elem))-(img.width))+'px';
        img.style.top             = '0px';
        elem.appendChild(img);
        //if (typeof(writeDebug) == 'function') writeDebug('drawing top left corner...');
        // Top left
        var img                   = document.createElement('img');
        img.id                    = 'roundedCorners_TopLeftCorner';
        img.src                   = style.images.tl.src;
        img.height                = style.images.tl.height;
        img.width                 = style.images.tl.width;
        img.border                = 0;
        img.style.position        = 'absolute';
        img.style.left            = '0px';
        img.style.top             = '0px';
        elem.appendChild(img);
        //if (typeof(writeDebug) == 'function') writeDebug('drawing bottom left corner...');
        // Bottom left
        var img                   = document.createElement('img');
        img.id                    = 'roundedCorners_BottomLeftCorner';
        img.src                   = style.images.bl.src;
        img.height                = style.images.bl.height;
        img.width                 = style.images.bl.width;
        img.border                = 0;
        img.style.position        = 'absolute';
        img.style.left            = '0px';
        img.style.top             = parseInt(parseInt(DomUtils.getElementHeight(elem))-parseInt(img.height))+'px';
        elem.appendChild(img);
        // Bottom right
        var img                   = document.createElement('img');
        img.id                    = 'roundedCorners_BottomRightCorner';
        img.src                   = style.images.br.src;
        img.height                = style.images.br.height;
        img.width                 = style.images.br.width;
        img.border                = 0;
        img.style.position        = 'absolute';
        //window.messageQueue.add( new Message(funcname(this), 'getting br width') );
        img.style.left            = parseInt(parseInt(DomUtils.getElementWidth(elem))-(img.width))+'px';
        img.style.top             = parseInt(parseInt(DomUtils.getElementHeight(elem))-(img.height))+'px';
        elem.appendChild(img);
        
        this.cornersDrawn = true;
    }
    //window.messageQueue.add( new Message('RoundedCornersInterface_Draw', 'finished') );
} // End RoundedCornersInterface_Draw

/**
 * "Erases" the rounded corners by removing the dom elements created with RoundedCornersInterface.draw().
 *
 * @access public
 * @since  v0.0.1a
 * @return void
 */
function RoundedCornersInterface_Erase() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> RoundedCornersInterface_Erase() called.', '#000000', '#ffff00');
    var elem = document.getElementById(this.elemId);
    if (elem.hasChildNodes()) {
        //if (typeof(writeDebug) == 'function') writeDebug('elem has child nodes: '+elem.childNodes.length);
        for (var i=elem.childNodes.length; i>0; i--) {
            var nodeId = elem.childNodes[i-1].id;
            var eq = '!=';
            var idPre = 'roundedCorners_';
            if (nodeId && nodeId.substr(0, idPre.length) == idPre) {
                eq = '==';
                //elem.removeChild(elem.childNodes[i-1]);
                DomUtils.removeElement(elem.childNodes[i-1]);
            }
            //if (typeof(writeDebug) == 'function') writeDebug(nodeId.substr(0, idPre.length)+' '+eq+' '+idPre);
        }
    } //else if (typeof(writeDebug) == 'function') writeDebug('no child nodes!');
    this.cornersDrawn = false;
    //if (typeof(writeDebug) == 'function') writeDebug('<< RoundedCornersInterface_Erase() finished.', '#000000', '#ffff00');
} // End RoundedCornersInterface_Erase







function ResourceManager() {

    var resourceManager = this;

    this.preloadedImages = new Array;


    window.preloadImage = ResourceManager_PreloadImage;
    window.getImage     = ResourceManager_GetImage;
    window.getImageSrc  = ResourceManager_GetImageSrc;
    window.swapImageSrc = ResourceManager_SwapImageSrc;


    return this;
}




function ResourceManager_PreloadImage(url, width, height) {
    if (!window.resourceManager.preloadedImages) window.resourceManager.preloadedImages = new Array;
//    if (typeof(writeDebug) == 'function') writeDebug('ResourceManager_PreloadImage(): checking for preloaded '+url);
    if (!window.resourceManager.preloadedImages[url]) {
//        if (typeof(writeDebug) == 'function') { writeDebug('ResourceManager_PreloadImage(): preloading '+url+', w: '+width+', h: '+height); }
        var image = new Image(width, height);
        image.src = url;
        window.resourceManager.preloadedImages[url] = image;
    }// else if (typeof(writeDebug) == 'function') writeDebug('ResourceManager_PreloadImage(): image already preloaded: '+url);
    return window.resourceManager.preloadedImages[url];
}

function ResourceManager_GetImage(url, width, height) {
    return window.preloadImage(url, width, height);
}

function ResourceManager_GetImageSrc(url) {
    return window.getImage(url).src;
}

function ResourceManager_SwapImageSrc(imgElem, url) {
    if (imgElem && imgElem.nodeType == 'IMG') {
        imgElem.oldSrc = imgElem.src;
        imgElem.src    = window.getImageSrc(url);
    }
}




window.resourceManager = new ResourceManager();/**
 * $Id: reportreviewpopup.js 64367 2009-02-20 01:56:36Z kchiu $
 * $Author: kchiu $
 * $Revision: 64367 $
 * $Name$
 * $Date: 2009-02-19 17:56:36 -0800 (Thu, 19 Feb 2009) $
 *
 * @jsRequire DomUtils
 * @jsRequire classes.BaseObject
 * @jsRequire classes.EventManager
 * @jsRequire interfaces.DropShadowInterface
 * @jsRequire interfaces.CalloutInterface
 * @jsRequire interfaces.DelayedPopupInterface
 *
 *
 *
 *
 * @version    $Revision: 64367 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 * @see        classes.BaseObject
 * @see        interfaces.DropShadowInterface
 * @see        interfaces.CalloutInterface
 * @see        interfaces.DelayedPopupInterface
 */

/**
 * ReportReviewPopup Constructor / ReportReview
 *
 * This is NOT intended to be instantiated directly. Instead, use the
 * singleton accessor methods ReportReviewPopup.getInstance(),
 * ReportReviewPopup.show(), ReportReviewPopup.hide() and ReportReviewPopup.toggle().
 *
 * @access public
 * @since  v1.1
 * @param  DOMElement       anchor
 * @return ReportReviewPopup
 */
function ReportReviewPopup(anchor) {
    this.elemId            = null;
//    this.elem              = null;
    // Callout interface implementation
    this.calloutId         = null;
//    this.callout           = null;
    this.calloutPadding    = 0;
    // Drop shadow interface implementation
    this.dropShadowId      = null;
//    this.dropShadow        = null;
    this.color             = null;
    this.xOffset           = null;
    this.yOffset           = null;
    this.blur              = { iRadius: null, iSigma: null };
    this.opacity           = null;
    this.xShrink           = null;
    this.yShrink           = null;
    this.shadowStyle       = null;
    this.images            = new Array;
    this.setBlur           = DropShadowInterface_SetBlur;
    // Delayed popup interface implementation
    this.timer             = null;
    this.visible           = false;
    this.delay             = null;
    this.linked            = new Array;
    this.cancelTimer       = DelayedPopupInterface_CancelTimer;
    this.hide              = DelayedPopupInterface_Hide;
    this.toggle            = PopupInterface_Toggle;
    // Anchored interface implementation
    this.anchorId          = null;
//    this.anchor            = anchor || null;
    this.getAnchorX        = AnchoredInterface_GetAnchorX;
    this.getAnchorY        = AnchoredInterface_GetAnchorY;
    this.getAnchorZ        = AnchoredInterface_GetAnchorZ;
    this.getAnchorWidth    = AnchoredInterface_GetAnchorWidth;
    this.getAnchorHeight   = AnchoredInterface_GetAnchorHeight;
    this.getAnchorPosition = AnchoredInterface_GetAnchorPosition;
    this.getElemWidth      = AnchoredInterface_GetElemWidth;
    this.getElemHeight     = AnchoredInterface_GetElemHeight;
    this.setAnchor         = AnchoredInterface_SetAnchor;
    this.disableScroll     = true;
    // Rounded corners interface implementation
//    this.cornerStyle       = null;
//    this.cornersDrawn      = false;
    // Drop shadow interface && Callout interface joint implementation
    this.erase             = ReportReviewPopup_Erase;
    this.draw              = ReportReviewPopup_Draw;
    this.init              = ReportReviewPopup_Init;
    // Drop shadow interface && Delayed popup interface joint implementation
    this.show              = ReportReviewPopup_Show;
    // Drop shadow interface && Anchored interface joint implementation
    this.alignElement      = ReportReviewPopup_AlignElement;
    
    this.def               = null;
    this.term              = null;
    this.setElement        = ReportReviewPopup_SetElement;
    this.setDefinition     = ReportReviewPopup_SetDefinition;
    this.setTerm           = ReportReviewPopup_SetTerm;
    this.setTermColor      = ReportReviewPopup_SetTermColor;

    this.implement(DropShadowInterface);
    this.implement(CalloutInterface);
    this.implement(DelayedPopupInterface);
    this.implement(AnchoredInterface);
//    this.implement(RoundedCornersInterface);
    
    this.id    = 'ReportReviewPopup';
    this.style = 'Default';
    this.delay = 0;
    this.init();
} // End ReportReviewPopup

// Setup ReportReviewPopup prototype chain
ReportReviewPopup.prototype             = new BaseObject;
ReportReviewPopup.prototype.constructor = ReportReviewPopup;
ReportReviewPopup.superclass            = BaseObject.prototype;









/****** BEGIN EDIT SECTION ******/

/**
 * Style definitions for ReportReviewPopup widget.
 *
 * These style settings can be overridden by a simple variable set call.
 * Note that if you set the backgroundColor to anything other than #ffffff
 * you will most likely want to create some rounded corner images and define
 * them too.
 * 
 * Example:
 *   <?php
 *   if (!$pricegrabber_site)
 *       echo "    ReportReviewPopup.styles.Default.term.color = '".$color."';\n";
 *   ?>
 */
ReportReviewPopup.styles = {
    Default: {
        term: {
            font: {
                family:  'Verdana, Arial, Helvetica, sans-serif',
                size:    '11px',
                weight:  'bold'
            },
            color:       '#589c1c'
        },
        font: {
            family:      'Verdana, Arial, Helvetica, sans-serif',
            size:        '11px',
            weight:      'normal'
        },
        backgroundColor: '#ffffff',
		borderColor: '#E9E9E9',
        weight:  'bold',
        color:           '#000000'
    }
} // End ReportReviewPopup.styles

/****** END EDIT SECTION ******/



/**
 * Sets the DOMElement that the ReportReviewPopup works with.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_SetElement(elem) {
    //if (typeof(writeDebug) == 'function') writeDebug('ReportReviewPopup_SetContent() called.');
    //this.elem = elem;
    this.elemId = elem.id;
    //if (typeof(writeDebug) == 'function') writeDebug('ReportReviewPopup_SetContent() finished.');
}

/**
 * Initializes the ReportReviewPopup in preparation for drawing.
 *
 * Call this method before any draw methods as it handles initialization of
 * any implemented interfaces as well.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_Init() {
    //if (typeof(writeDebug) == 'function') writeDebug('ReportReviewPopup_Init() called.');
    //this.elem                       = document.createElement('div');
    var elem = document.createElement('div');
    document.getElementsByTagName('body')[0].appendChild(elem);
    //this.elem.id                    = 'report_review_content';
    this.elemId = 'report_review_content';
    elem.id = this.elemId;
    //this.elem.style.backgroundColor = ReportReviewPopup.styles[this.style].backgroundColor;
    elem.style.backgroundColor = ReportReviewPopup.styles[this.style].backgroundColor;
    
    //this.term                       = document.createElement('span');
    var term = document.createElement('span');
    //this.term.id                    = this.id+'_term';
    this.termId = this.elemId+'_term';
    term.id = this.termId;
    if (typeof(writeDebug) == 'function') writeDebug('style name: '+this.style+"\ncolor: "+ReportReviewPopup.styles[this.style].term.color);
    term.style.color           = ReportReviewPopup.styles[this.style].term.color;
    term.style.paddingBottom   = '5px';
    term.style.fontFamily      = ReportReviewPopup.styles[this.style].term.font.family;
    term.style.fontSize        = ReportReviewPopup.styles[this.style].term.font.size;
    term.style.fontWeight      = ReportReviewPopup.styles[this.style].term.font.weight;
//    term.style.backgroundColor  = "#ffffff";
    elem.appendChild(term);
    
    //this.def                        = document.createElement('div');
    var def = document.createElement('div');
    //this.def.id                     = this.id+'_def';
    this.defId = this.elemId+'_def';
    def.id = this.defId;
    def.style.color            = ReportReviewPopup.styles[this.style].color;
    def.style.fontFamily       = ReportReviewPopup.styles[this.style].font.family;
    def.style.fontSize         = ReportReviewPopup.styles[this.style].font.size;
    def.style.fontWeight       = ReportReviewPopup.styles[this.style].font.weight;
//    this.def.style.backgroundColor  = "#ffffff";
    elem.appendChild(def);
    
    this.calloutPadding = 10;
    this.cornerStyle = 'Default';
//    RoundedCornersInterface_Init.call(this);
    this.shadowStyle = 'Default';
    DropShadowInterface_Init.call(this);
    //if (typeof(writeDebug) == 'function') writeDebug('ReportReviewPopup_Init() finished.');
} // End ReportReviewPopup_Init

/**
 * Erases the definition popup by removing the dom elements created in ReportReviewPopup_Draw.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_Erase() {
    CalloutInterface_Erase.call(this);
    DropShadowInterface_Erase.call(this);
//    RoundedCornersInterface_Erase.call(this);
    this.linked = new Array;
} // End ReportReviewPopup_Erase

/**
 * Draws the definition popup by creating the necessary dom elements and attaching them to the document accordingly.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_Draw() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_Draw() called.', '#ffffff', '#0000ff');
    this.linked = new Array;

    var elem = document.getElementById(this.elemId);
    if (!elem) throw new Error('Unable to find element: '+this.elemId);
    var anchor = document.getElementById(this.anchorId);
    if (!anchor) throw new Error('Unable to find anchor element: '+this.anchorId);

    bHeight = 2;
    elem.style.border = '1px solid '+ReportReviewPopup.styles[this.style].borderColor;
    elem.style.backgroundColor = ReportReviewPopup.styles[this.style].backgroundColor;
    elem.style.color = ReportReviewPopup.styles[this.style].color;
//    RoundedCornersInterface_Draw.call(this);
//    CalloutInterface_Draw.call(this);

    var pos = this.getAnchorPosition();

    var aLeft   = DomUtils.getElementLeft(anchor);
    var aTop    = DomUtils.getElementTop(anchor);
    var aHeight = DomUtils.getElementHeight(anchor);
    var aWidth  = DomUtils.getElementWidth(anchor);
    var eHeight = DomUtils.getElementHeight(elem);
    var eWidth  = DomUtils.getElementWidth(elem);
    switch (pos) {
        case AnchoredInterface.ALIGN.RIGHT_TOP:
            elem.style.left = parseInt(aLeft)+'px';
            elem.style.top  = parseInt(aTop-eHeight - 8)+'px';
            break;
        case AnchoredInterface.ALIGN.RIGHT_BOTTOM:
            elem.style.left = parseInt(aLeft)+'px';
            elem.style.top  = parseInt(aTop+aHeight + 8)+'px';
            break;
        case AnchoredInterface.ALIGN.LEFT_TOP:
            elem.style.left = parseInt(aLeft+aWidth-eWidth)+'px';
            elem.style.top  = parseInt(aTop-eHeight)+'px';
            break;
        case AnchoredInterface.ALIGN.LEFT_BOTTOM:
        default:
            elem.style.left = parseInt(aLeft+aWidth-eWidth)+'px';
            elem.style.top  = parseInt(aTop+aHeight)+'px';
            break;
    }
	
    DropShadowInterface_Draw.call(this);
    window.addEvent(elem, 'mouseover', this.cancelTimer, this, true);
    window.addEvent(elem, 'mouseout',  this.hide,        this, true);
//    this.elem.style.borderWidth = '1px';
//    this.elem.style.border = 'solid';
//    this.elem.style.backgroundColor = 'white';
    //this.linked.push(this.dropShadow);
    this.linked.push(this.dropShadowId);
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_Draw() finished.', '#ffffff', '#0000ff');
} // End ReportReviewPopup_Draw

/**
 * Shows the definition popup on the screen.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function ReportReviewPopup_Show() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_Show() called.', '#ffffff', '#0000ff');
    this.cancelTimer();

    var elem = document.getElementById(this.elemId);
    if (!elem) throw new Error('Unable to find element: '+this.elemId);
    var anchor = document.getElementById(this.anchorId);
    if (!anchor) throw new Error('Unable to find anchor element: '+this.anchorId);

//    if (!this.anchor) {
//        throw new Error('ReportReviewPopup.anchor not set, unable to show.');
//        return false;
//    }
    var wasVisible = this.visible;
    if (this.visible) PopupInterface_Hide.call(this);
    if (!this.visible) {
        this.erase();
//        this.elem.style.zIndex       = parseInt(this.getAnchorZ()+3); // +3 so the drop shadow & rounded corner content has room
        elem.style.zIndex       = parseInt(DomUtils.getZIndex(elem)+3); // +3 so the drop shadow & rounded corner content has room
        this.draw();
//        this.callout.style.zIndex    = parseInt(DomUtils.getZIndex(this.elem))-1;
        var dropShadow = document.getElementById(this.dropShadowId);
        if (!dropShadow) throw new Error('Unable to find drop shadow element: '+this.dropShadowId);
        dropShadow.style.zIndex = parseInt(DomUtils.getZIndex(elem))-2;
        if (wasVisible) PopupInterface_Show.call(this);
        else            DelayedPopupInterface_Show.call(this);
    }
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_Show() finished.', '#ffffff', '#0000ff');
    return true;
} // End ReportReviewPopup_Show

/**
 * Aligns the definition popup by calling implemented interfaces' AlignElement functions.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_AlignElement(pos) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_AlignElement() called.', '#ffffff', '#0000ff');
    CalloutInterface_AlignElement.call(this, pos);
    DropShadowInterface_AlignElement.call(this, pos);
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_AlignElement() finished.', '#ffffff', '#0000ff');
} // End ReportReviewPopup_AlignElement

/**
 * Sets the definition in the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_SetDefinition(definitionString) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_SetDefinition() called.', '#ff0000', '#ffffff');
    var def = document.getElementById(this.defId);
    if (!def) throw new Error('Unable to find definition element: '+this.defId);
    def.innerHTML = definitionString;
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_SetDefinition() finished.', '#ff0000', '#ffffff');
}

/**
 * Sets the term in the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_SetTerm(termString) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_SetTerm() called.', '#ff0000', '#ffffff');
    var term = document.getElementById(this.termId);
    if (!term) throw new Error('Unable to find term element: '+this.termId);

    while (term.hasChildNodes()) term.removeChild(term.firstChild);
    var txtTerm = document.createTextNode(termString);
    term.appendChild(txtTerm);
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_SetTerm() finished.', '#ff0000', '#ffffff');
}

/**
 * Sets the term color of the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ReportReviewPopup_SetTermColor(color) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup_SetTermColor() called.', '#ff0000', '#ffffff');
    var term = document.getElementById(this.termId);
    if (!term) throw new Error('Unable to find term element: '+this.termId);
    term.style.color = color;
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup_SetTermColor() finished.', '#ff0000', '#ffffff');
}



/****** SINGLETON ACCESSORS SECTION ******/

/**
 * Singleton instance variable.
 *
 * @access public
 * @since  v1.1
 * @var    instance   ReportReviewPopup
 */
ReportReviewPopup.instance = null;

/**
 * Singleton accessor for retrieving the definition popup instance.
 *
 * @access public
 * @since  v1.1
 * @return ReportReviewPopup
 */
ReportReviewPopup.getInstance = function() {
    if (!ReportReviewPopup.instance) ReportReviewPopup.instance = new ReportReviewPopup();
    return ReportReviewPopup.instance;
} // End ReportReviewPopup.getInstance

/**
 * Singleton accessor for initializing the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
//ReportReviewPopup.initInstance = function() {
//    if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup.init() called.', '#ff0000', '#ffff00');
//    ReportReviewPopup.instance = new ReportReviewPopup();
//    if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup.init() finished.', '#ff0000', '#ffff00');
//} // End ReportReviewPopup.init

/**
 * Singleton accessor for showing the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
ReportReviewPopup.show = function(anchorElement, termString, definitionString) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ReportReviewPopup.show() called.', '#ff0000', '#ffff00');
    ReportReviewPopup.getInstance().setAnchor(anchorElement);
    ReportReviewPopup.getInstance().setDefinition(definitionString);
    ReportReviewPopup.getInstance().setTerm(termString);
    ReportReviewPopup_Show.call(ReportReviewPopup.getInstance());
    //if (typeof(writeDebug) == 'function') writeDebug('<< ReportReviewPopup.show() finished.', '#ff0000', '#ffff00');
} // End ReportReviewPopup.show

/**
 * Singleton accessor for hiding the definition popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
ReportReviewPopup.hide = function() {
    DelayedPopupInterface_Hide.call(ReportReviewPopup.getInstance());
} // End ReportReviewPopup.hide

/**
 * Singleton accessor for toggling the definition popup.
 *
 * @access public
 * @since  v1.1
 * @param  DOMElement  anchorElement
 * @param  string      termString
 * @param  string      definitionString
 * @return void
 */
ReportReviewPopup.toggle = function(anchorElement, termString, definitionString) {
    if (ReportReviewPopup.getInstance().visible) ReportReviewPopup.hide();
    else                                         ReportReviewPopup.show(anchorElement, termString, definitionString);
}
/**
 * $Id: imagepopup.js 64367 2009-02-20 01:56:36Z kchiu $
 * $Author: kchiu $
 * $Revision: 64367 $
 * $Name$
 * $Date: 2009-02-19 17:56:36 -0800 (Thu, 19 Feb 2009) $
 *
 * @jsRequire DomUtils
 * @jsRequire classes.BaseObject
 * @jsRequire classes.EventManager
 * @jsRequire interfaces.DropShadowInterface
 * @jsRequire interfaces.CalloutInterface
 * @jsRequire interfaces.PopupInterface
 * @jsRequire interfaces.AnchoredInterface
 * @jsRequire interfaces.RoundedCornersInterface
 *
 *
 *
 *
 * @version    $Revision: 64367 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 * @see        classes.BaseObject
 * @see        interfaces.DropShadowInterface
 * @see        interfaces.CalloutInterface
 * @see        interfaces.PopupInterface
 * @see        interfaces.AnchoredInterface
 * @see        interfaces.RoundedCornersInterface
 */

/**
 * ImagePopup Constructor / Definition
 *
 * This is NOT intended to be instantiated directly. Instead, use the
 * singleton accessor methods ImagePopup.getInstance(),
 * ImagePopup.show(), ImagePopup.hide() and ImagePopup.toggle().
 *
 * @access public
 * @since  v1.1
 * @param  DOMElement       anchor
 * @return ImagePopup
 */
function ImagePopup(anchor) {
    this.elemId            = null;
    //this.elem              = null;
    // Callout interface implementation
    this.calloutId         = null;
    //this.callout           = null;
    this.calloutPadding    = 0;
    // Drop shadow interface implementation
    this.dropShadowId      = null;
    //this.dropShadow        = null;
    this.color             = null;
    this.xOffset           = null;
    this.yOffset           = null;
    this.blur              = { iRadius: null, iSigma: null };
    this.opacity           = null;
    this.xShrink           = null;
    this.yShrink           = null;
    this.shadowStyle       = null;
    this.images            = new Array;
    this.setBlur           = DropShadowInterface_SetBlur;
    // Popup interface implementation
    this.visible           = false;
    this.linked            = new Array;
    this.hide              = PopupInterface_Hide;
    this.show              = PopupInterface_Show;
    this.toggle            = PopupInterface_Toggle;
    // Anchored interface implementation
    this.anchorId          = null;
    //this.anchor            = anchor || null;
    this.getAnchorX        = AnchoredInterface_GetAnchorX;
    this.getAnchorY        = AnchoredInterface_GetAnchorY;
    this.getAnchorZ        = AnchoredInterface_GetAnchorZ;
    this.getAnchorWidth    = AnchoredInterface_GetAnchorWidth;
    this.getAnchorHeight   = AnchoredInterface_GetAnchorHeight;
    this.getAnchorPosition = AnchoredInterface_GetAnchorPosition;
    this.getElemWidth      = AnchoredInterface_GetElemWidth;
    this.getElemHeight     = AnchoredInterface_GetElemHeight;
    this.setAnchor         = AnchoredInterface_SetAnchor;
    this.disableScroll     = true;
    // Rounded corners interface implementation
    this.cornerStyle       = null;
    this.cornersDrawn      = false;
    // Drop shadow interface && Callout interface joint implementation
    this.erase             = ImagePopup_Erase;
    this.draw              = ImagePopup_Draw;
    this.init              = ImagePopup_Init;
    // Drop shadow interface && popup interface joint implementation
    this.show              = ImagePopup_Show;
    // Drop shadow interface && Anchored interface joint implementation
    this.alignElement      = ImagePopup_AlignElement;
    
    this.contentId         = null;
    //this.content           = null;
    this.onMouseOver       = null;
    this.onMouseOut        = null;
    this.setElement        = ImagePopup_SetElement;
    this.setContent        = ImagePopup_SetContent;
    this.setMouseOver      = ImagePopup_SetMouseOver;
    this.setMouseOut       = ImagePopup_SetMouseOut;

    this.implement(DropShadowInterface);
    this.implement(CalloutInterface);
    this.implement(PopupInterface);
    this.implement(AnchoredInterface);
    this.implement(RoundedCornersInterface);
    
    this.id           = 'ImagePopup';
    this.elemId       = this.id;
    this.contentId    = this.elemId+'_content';
    this.dropShadowId = this.elemId+'_dropShadow';
    this.style       = 'Default';
    this.delay       = 500;
    this.init();
} // End ImagePopup

// Setup ImagePopup prototype chain
ImagePopup.prototype             = new BaseObject;
ImagePopup.prototype.constructor = ImagePopup;
ImagePopup.superclass            = BaseObject.prototype;









/****** BEGIN EDIT SECTION ******/

/**
 * Style definitions for ImagePopup widget.
 *
 * These style settings can be overridden by a simple variable set call.
 * Note that if you set the backgroundColor to anything other than #ffffff
 * you will most likely want to create some rounded corner images and define
 * them too.
 * 
 * Example:
 *   <?php
 *   if (!$pricegrabber_site)
 *       echo "    ImagePopup.styles.Default.term.color = '".$color."';\n";
 *   ?>
 */
ImagePopup.styles = {
    Default: {
        term: {
            font: {
                family:  'Arial, Helvetica, sans-serif',
                size:    '13px',
                weight:  'bold'
            },
            color:       '#589c1c'
        },
        font: {
            family:      'Arial, Helvetica, sans-serif',
            size:        '13px',
            weight:      'normal'
        },
        backgroundColor: '#ffffff',
        color:           '#656565'
    }
} // End ImagePopup.styles

/****** END EDIT SECTION ******/


















/**
 * Sets the DOMElement that the ImagePopup works with.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_SetElement(elem) {
    if (typeof(writeDebug) == 'function') writeDebug('ImagePopup_SetContent() called.');
    this.elemId = elem.id;
    //this.elem = elem;
    if (typeof(writeDebug) == 'function') writeDebug('ImagePopup_SetContent() finished.');
}

/**
 * Initializes the ImagePopup in preparation for drawing.
 *
 * Call this method before any draw methods as it handles initialization of
 * any implemented interfaces as well.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_Init() {
    //if (typeof(writeDebug) == 'function') writeDebug('ImagePopup_Init() called.');
    var elem = document.getElementById(this.elemId);
    if (!elem) {
        elem                       = document.createElement('div');
        document.getElementsByTagName('body')[0].appendChild(elem);
        elem.id                    = this.elemId;
    }

    var content = document.getElementById(this.contentId);
    if (!content) {
        content = document.createElement('div');
        elem.appendChild(content);
        content.id = this.contentId;
    }

    elem.style.backgroundColor = ImagePopup.styles[this.style].backgroundColor;
    content.style.color        = ImagePopup.styles[this.style].color;
    content.style.fontFamily   = ImagePopup.styles[this.style].font.family;
    content.style.fontSize     = ImagePopup.styles[this.style].font.size;
    content.style.fontWeight   = ImagePopup.styles[this.style].font.weight;
 
    this.calloutPadding = 20;
    this.cornerStyle = 'Default';
    RoundedCornersInterface_Init.call(this);
    this.shadowStyle = 'Default';
    DropShadowInterface_Init.call(this);
    //if (typeof(writeDebug) == 'function') writeDebug('ImagePopup_Init() finished.');
} // End ImagePopup_Init

/**
 * Erases the popup by removing the dom elements created in ImagePopup_Draw.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_Erase() {
    CalloutInterface_Erase.call(this);
    DropShadowInterface_Erase.call(this);
    RoundedCornersInterface_Erase.call(this);
    this.linked = new Array;
} // End ImagePopup_Erase

/**
 * Draws the image popup by creating the necessary dom elements and attaching them to the document accordingly.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_Draw() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ImagePopup_Draw() called.', '#ffffff', '#0000ff');
    var elem = document.getElementById(this.elemId);
    if (!elem) throw new Error('Unable to find element: '+this.elemId);

    this.linked = new Array;
    bHeight = 2;
    elem.style.border          = '1px solid '+ImagePopup.styles[this.style].backgroundColor;
    elem.style.backgroundColor = ImagePopup.styles[this.style].backgroundColor;
    elem.style.color           = ImagePopup.styles[this.style].color;
    window.addEvent(elem, 'click', this.hide, this, true);
    CalloutInterface_Draw.call(this);
    RoundedCornersInterface_Draw.call(this);
    DropShadowInterface_Draw.call(this);
    elem.style.border          = 'none';
    elem.style.backgroundColor = 'transparent';

    this.linked.push(this.dropShadowId);
    this.linked.push(this.calloutId);

/*
    var callout = document.getElementById(this.calloutId);
    if (!callout) throw new Error('Unable to find callout element: '+this.calloutId);

    var dropShadow = document.getElementById(this.dropShadowId);
    if (!dropShadow) throw new Error('Unable to find drop shadow element: '+this.dropShadowId);


    var pos = this.getAnchorPosition();
    AnchoredInterface_AlignElement.call(this);
    if (pos == AnchoredInterface.ALIGN.LEFT_TOP || pos == AnchoredInterface.ALIGN.RIGHT_TOP) {
        callout.style.top = (parseInt(callout.style.top)-(bHeight))+'px'; // Due to removal of 1px border
        elem.style.top = (parseInt(elem.style.top)+(bHeight))+'px';
        dropShadow.style.top = elem.style.top;
    } else {
        elem.style.top = (parseInt(elem.style.top)-(bHeight*2))+'px'; // Due to removal of 1px border
        dropShadow.style.top = elem.style.top;
    }
*/
    //if (typeof(writeDebug) == 'function') writeDebug('<< ImagePopup_Draw() finished.', '#ffffff', '#0000ff');
} // End ImagePopup_Draw

/**
 * Shows the image popup on the screen.
 *
 * @access public
 * @since  v1.1
 * @return boolean
 */
function ImagePopup_Show() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ImagePopup_Show() called.', '#ffffff', '#0000ff');
    var wasVisible = this.visible;
    if (wasVisible) {
        PopupInterface_Hide.call(this);
        this.erase();
    }
    this.draw();

    var anchor     = document.getElementById(this.anchorId);
    if (!anchor)     throw new Error('Unable to find anchor element: '+this.anchorId);

    var elem       = document.getElementById(this.elemId);
    if (!elem)       throw new Error('Unable to find element: '+this.elemId);

    var dropShadow = document.getElementById(this.dropShadowId);
    if (!dropShadow) throw new Error('Unable to find drop shadow element: '+this.dropShadowId);

    var callout    = document.getElementById(this.calloutId);
    if (!callout)    throw new Error('Unable to find callout element: '+this.calloutId);

    // Get the z-index of our anchor element
    var zIndex = parseInt(DomUtils.getZIndex(anchor));
    // If it doesn't have one make it 1000
    if (zIndex == 0) {
        zIndex = 1000;
        anchor.style.zIndex = zIndex;
    }
    dropShadow.style.zIndex = zIndex+1;
    callout.style.zIndex    = zIndex+2;
    elem.style.zIndex       = zIndex+3;

    //if (typeof(writeDebug) == 'function') writeDebug('<< ImagePopup_Show() finished.', '#ffffff', '#0000ff');
    this.alignElement();
    PopupInterface_Show.call(this);
    return true;
} // End ImagePopup_Show

/**
 * Aligns the image popup by calling implemented interfaces' AlignElement functions.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_AlignElement() {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ImagePopup_AlignElement() called.', '#ffffff', '#0000ff');
    AnchoredInterface_AlignElement.call(this);
    CalloutInterface_AlignElement.call(this);
    DropShadowInterface_AlignElement.call(this);
    //if (typeof(writeDebug) == 'function') writeDebug('<< ImagePopup_AlignElement() finished.', '#ffffff', '#0000ff');
} // End ImagePopup_AlignElement

/**
 * Sets the content in the image popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function ImagePopup_SetContent(contentString) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ImagePopup_SetContent() called.', '#ff0000', '#ffffff');
    var content = document.getElementById(this.contentId);
    if (!content) throw new Error('Unable to find content element: '+this.contentId);
    content.innerHTML = contentString;
    //if (typeof(writeDebug) == 'function') writeDebug('<< ImagePopup_SetContent() finished.', '#ff0000', '#ffffff');
}

/**
 * Sets the onMouseOver event for the image popup.
 *
 * @access public
 * @since  v1.3
 * @param  reference  funcRef    A function reference (just the unquoted name), scope being the image popup.
 * @return void
 */
function ImagePopup_SetMouseOver(funcRef) {
    this.onMouseOver = funcRef;
}

/**
 * Sets the onMouseOut event for the image popup.
 * @access public
 * @since  v1.3
 * @param  reference  funcRef    A function reference (just the unquoted name), scope being the image popup.
 * @return void
 */
function ImagePopup_SetMouseOut(funcRef) {
    this.onMouseOut = funcRef;
}








/****** SINGLETON ACCESSORS SECTION ******/

/**
 * Singleton instance variable.
 *
 * @access public
 * @since  v1.1
 * @var    instance   ImagePopup
 */
ImagePopup.instance = null;

/**
 * Singleton accessor for retrieving the image popup instance.
 *
 * @access public
 * @since  v1.1
 * @return ImagePopup
 */
ImagePopup.getInstance = function() {
    if (!ImagePopup.instance) ImagePopup.instance = new ImagePopup();
    return ImagePopup.instance;
} // End ImagePopup.getInstance

/**
 * Singleton accessor for showing the image popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
ImagePopup.show = function(anchorElement, contentString) {
    //if (typeof(writeDebug) == 'function') writeDebug('>> ImagePopup.show() called.', '#ff0000', '#ffff00');
    ImagePopup.getInstance().setAnchor(anchorElement);
    ImagePopup.getInstance().setContent(contentString);
    ImagePopup.getInstance().show();
    //if (typeof(writeDebug) == 'function') writeDebug('<< ImagePopup.show() finished.', '#ff0000', '#ffff00');
} // End ImagePopup.show

/**
 * Singleton accessor for hiding the image popup.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
ImagePopup.hide = function() {
    PopupInterface_Hide.call(ImagePopup.getInstance());
} // End ImagePopup.hide

/**
 * Singleton accessor for toggling the image popup.
 *
 * @access public
 * @since  v1.1
 * @param  DOMElement  anchorElement
 * @param  string      contentString
 * @return void
 */
ImagePopup.toggle = function(anchorElement, contentString) {
    if (ImagePopup.getInstance().visible) ImagePopup.hide();
    else                                  ImagePopup.show(anchorElement, contentString);
}

// set this global var if on a secure page for ajax calls
var PG_use_https;
/**
 *  Add user favorite
 *   ajax call to add a user favorite (merchant or brand)
 */ 
function addUserFavorite(user_id, preference_id_type, preference_id, element_id, element_class, element_content, callback)
{

	// if no user id is given, then load the login overlay bubble
	if (!user_id) {
		user_id = util.readCookie('bake_userid');

		// this hack is for IE6 only.... we saved the userid in document.login cuz it cant read cookies well
		if (!user_id && document.login && document.login.loginSuccessUserid) {
			user_id = document.login.loginSuccessUserid;
		}
		// end IE6 hack
		
		if (!user_id) {
			if (document.login) {
				// set login success callback
				// (try adding to favorites again, once login is successful)
				document.login.loginSuccessCallback = function () { addUserFavorite('', preference_id_type, preference_id, element_id, element_class, element_content, callback); };
			}

                        callbackfuncafterlogin = "addUserFavorite('"+(user_id?user_id:"")+"','"+preference_id_type+"','"+preference_id+"','"+element_id+"','"+element_class+"','"+(element_content?element_content:"")+"','"+(callback?callback:"")+"');";
                        //Tracking from where we require user login/registration
                        if (preference_id_type == 'vendor') refer_page = 'Add Brand to Favs';
                        if (preference_id_type == 'merchant') refer_page = 'Add Merchant to Favs';
                        
                        iframe_login('login_registration', callbackfuncafterlogin, refer_page);
			return;
		}
	}

	if (!user_id) {
		return false;
	}
	
//	console.log('addUserFavorite ' + user_id + ' - ' + preference_id_type + ' - ' + preference_id);
	var ajax = new AjaxRequest('GET', '/ajax.php', true, 3000);
	ajax.setParameter('action', 'addUserFavorite');
	ajax.setParameter('user_id', user_id);
	ajax.setParameter('preference_id_type', preference_id_type);
	ajax.setParameter('preference_id', preference_id);
	ajax.setParameter('element_id', element_id);
	ajax.setParameter('element_class', element_class);
	if (element_content) {
		ajax.setParameter('element_content', element_content);
	}
	
	// lame secure hack
	if (PG_use_https) {
		ajax.setParameter('secure', 1);
	}

	if (callback) {
		ajax.setCallback(callback);
	}
	else {
	    ajax.setCallback(addUserFavoriteResponse);
	}
	ajax.send();
}

/**
 * default ajax response after adding user favorite
 */ 
function addUserFavoriteResponse(xml)
{
	// get json
    var data = eval('(' + xml.getElementsByTagName('json')[0].firstChild.nodeValue + ')');

	if (!data['success']) {
		return false;
	}    
	
    if (data['element_id']) {
	    em = document.getElementById(data['element_id']);
	    if (data['element_class']) {
		    em.className = data['element_class'];
		}
	    em.innerHTML = data['message'];
	}

	// update browse favorite stores/brands link if its on the page
	// todo: this should be moved elsewhere
	var store_link = document.getElementById('browse_favorite_stores_link');
	if (store_link && data['preference_id_type'] == "merchant") {
		// update count
		stores_link_count_em = document.getElementById('favorite_stores_count');
		var count = parseInt(stores_link_count_em.innerHTML);
		count++;
		stores_link_count_em.innerHTML = count;
		// update href link
		store_link.href += '/retid[]=' + data['preference_id'];
	}
	var brands_link = document.getElementById('browse_favorite_brands_link');
	if (brands_link && data['preference_id_type'] == "vendor") {
		// update count
		brands_link_count_em = document.getElementById('favorite_brands_count');
		var count = parseInt(brands_link_count_em.innerHTML);
		count++;
		brands_link_count_em.innerHTML = count;
		// update href link
		brands_link.href += '/vendorIds[]=' + data['preference_id'];
	}
        
}

/**
 *	delete a user preference/favorite
 */ 
function deleteUserPreference(user_preference_id, preference_id_type, element_id, callback)
{
	user_id = util.readCookie('bake_userid');

	if (!user_id) {
		LoginOverlay_login();
		return;
	}

	var ajax = new AjaxRequest('GET', '/ajax.php', true, 3000);
	ajax.setParameter('action', 'deleteUserFavorite');
	ajax.setParameter('user_id', user_id);
	ajax.setParameter('secure', 1);
	ajax.setParameter('user_preference_id', user_preference_id);
	ajax.setParameter('preference_id_type', preference_id_type);
	ajax.setParameter('element_id', element_id);
    ajax.setCallback(callback);
	ajax.send();
}

// functions related to login popup to load the external JS files required to handle it
function LoginOverlay_login() {
        if(!loginLoaded) {
                var s2 = document.createElement('script'); s2.src = login_pop_script;
                document.body.appendChild(s2);
        }
        if(!ajaxLoaded) {
                var s1 = document.createElement('script'); s1.src = login_pop_ajax;
                document.body.appendChild(s1);
        }
        LoginOverlay_waitForLoad();
}
function LoginOverlay_waitForLoad() {
        if(!loginLoaded) {
                if (window.login_js) {
                        loginLoaded = 1;
                        ShowLoginMessage('<img src="'+login_pop_wait+'" width=16 height=16>',login_pop_msg,'#666666');}
                else {
                        setTimeout('LoginOverlay_waitForLoad("");',200);
                        return 0;
                }
        }
        if(!ajaxLoaded) {
                if(window.ajax) {
                        ajaxLoaded = 1;
                }
                else {
                        setTimeout('LoginOverlay_waitForLoad("");',200);
                        return 0;
                }
        }
        if (ajaxLoaded && loginLoaded) {
                showLoginBubble();
        }
}
function MM_preloadImages() { 
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function MM_swapImgRestore() { 
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_findObj(n, d) { 
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document); return x;
}

function MM_swapImage() { 
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}

function setfocus() {
	if (document.forms['mastsearch'].form_keyword) document.forms['mastsearch'].form_keyword.focus();
}
var show;
function showmenu()
{
  var el = document.getElementById("channels");
  var iframe_menu = document.getElementById('iframe_menu');
  var moretab=document.getElementById("menupos");
  if (el) {
	  	el.style.top=(DomUtils.getElementTop(moretab)+23)+"px";
		el.style.left=(DomUtils.getElementLeft(moretab)-100)+"px";
    el.style.visibility = "visible";
    el.style.zIndex = '100';
      iframe_menu.style.width = el.offsetWidth;
      iframe_menu.style.height = el.offsetHeight;
      iframe_menu.style.top = el.style.top;
      iframe_menu.style.left = el.style.left;
      iframe_menu.style.zIndex = el.style.zIndex - 1;
      iframe_menu.style.display = "block";
    show = 1;
  }
}


function hidemenu()
{
  show = 0;
  setTimeout("hide()", 600);
}
function hide()
{
  var el = document.getElementById("channels");
  var iframe_menu = document.getElementById('iframe_menu');
  if (el) {
    if (!show)
    {
      el.style.visibility = "hidden";
      iframe_menu.style.display = "none";
    }
  }
}
function showmenu2()
{
  var el = document.getElementById("back");
  if (el) {
    el.style.visibility = "visible";
    show = 1;
  }
}
function hidemenu2()
{
  show = 0;
  setTimeout("hide2()", 400);
}
function hide2()
{
  var el = document.getElementById("back");
  if (el) {
    if (!show)
    {
      el.style.visibility = "hidden";
    }
  }
}



/**
 * Append this JavaScript to every page
 */
if (document.getElementById('footerMenuContent') != undefined) {
	var footerMenuContentEl = document.getElementById('footerMenuContent');
}

// When there is no footer menu in action in the page, we should not try to execute
// this series of actions.  It is not just pointless but also causes JS errors.
if (typeof footerMenuContentEl != undefined && footerMenuContentEl) {
  window.addOnLoad(padPopupLinks);
  new ypSlideOutMenu('footerMenu', 'up', getMenuLeftPos(), getMenuTopPos(), 140, 155);
  window.addOnResize(repositionMenu);
  initCursorTargets();

  // position main menu pointer needle
  // possible x coords
  var cursorTimeout;

  // init menu pointer
  setMenuCursorPos();
}

function padPopupLinks() {
    var anchorElements = footerMenuContentEl.getElementsByTagName('a');
	for (var i = 0; i < anchorElements.length; i++) {
		var text = anchorElements[i].firstChild.nodeValue;
		anchorElements[i].removeChild( anchorElements[i].firstChild );
		var span = document.createElement('span');
		span.style.position = 'relative';
		span.style.top  = '5px';
		span.style.left = '10px';
		span.appendChild( document.createTextNode(text) );
		anchorElements[i].appendChild( span );
	}
}

function getMenuLeftPos() {
	var targetLeft = DomUtils.getElementLeft( document.getElementById('i18nMoreButton') );
	var x = targetLeft - 67;
	return x;
}

function getMenuTopPos() {
	var cursorTop = DomUtils.getElementTop( document.getElementById('cursorElement') );
	var y = cursorTop - 160;
	return y;
}

function repositionMenu() {
	ypSlideOutMenu.repositionMenu('footerMenu', getMenuLeftPos(), getMenuTopPos());
}

function initCursorTargets() {
	var i18nEl = document.getElementById('i18n');
	var li = i18nEl.getElementsByTagName('li'); // make global
	var cursorEl = document.getElementById('cursorElement');
	var cursorElWidth = 0;
	for ( var i = 0; i < li.length; i++ ) {
		if ( document.all ) { /* IE */
			cursorElWidth += DomUtils.getElementWidth(li[i]) + 15;
		}
		else {
			cursorElWidth += DomUtils.getElementWidth(li[i]);
		}
		if ( i == (li.length - 1) ) break; /* skip more button element */
		window.addEvent(li[i], 'mouseover', setMenuCursorPos, cursorEl, false);
		window.addEvent(li[i], 'mouseout', resetMenuCursorPos, cursorEl, false);
	}
	cursorEl.style.width = cursorElWidth + 'px';
	i18nEl.style.width = cursorElWidth + 'px';
	var moreLangEl = document.getElementById('footerMenuContent');
	window.addEvent(moreLangEl, 'mouseover', hideMenuCursor, document, false);
	window.addEvent(moreLangEl, 'mouseout', resetMenuCursorPos, document, false);
	var moreLangButton = document.getElementById('i18nMoreButton');
	window.addEvent(moreLangButton, 'mouseover', hideMenuCursor, document, false);
	window.addEvent(moreLangButton, 'mouseout', resetMenuCursorPos, document, false);
}

function setMenuCursorPos(e) {
	var cursorElement;
	var targetEl;
	if (e) {
	/* 
	 * event triggered 
	 * e.target ( moz target )
	 * e.srcElement ( ie target )
	 */
		cursorElement = this;
		targetEl = (e.target) ? e.target : (e.srcElement) ? e.srcElement : null;
	}
	else {
		cursorElement = document.getElementById('cursorElement');
		var anchorElements = cursorElement.getElementsByTagName('a');
		for (var i = 0; i < anchorElements.length; i++) {
			if ( anchorElements[i].hreflang == PG_LOCALE ) {
				targetEl = anchorElements[i];
				break;
			}
		}
	}
	var absContainerLeft = DomUtils.getElementLeft(cursorElement);
	var absTargetLeft = DomUtils.getElementLeft(targetEl);
	var targetLeft = absTargetLeft - absContainerLeft;
	var targetWidth = DomUtils.getElementWidth(targetEl);
	// minus anchor left padding
	targetWidth = targetWidth - 5;
	cursorElement.style.backgroundPosition = ( targetLeft + (targetWidth / 2) ) +'px bottom';
	if ( cursorTimeout )
		clearTimeout(cursorTimeout);
}

function resetMenuCursorPos() {
	cursorTimeout = setTimeout('setMenuCursorPos()', 500);
}

function hideMenuCursor(e) {
	var cursorElement = this.getElementById('cursorElement');
	cursorElement.style.backgroundPosition = '-10px bottom';
	
	if ( cursorTimeout )
		clearTimeout(cursorTimeout);
}
