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

