/**
 * $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);
}
