/**
 * @author Fahrettin Kutyol
 * This is the rebuilt for dojo 1.2.x of the former 0.4 widget by Josip Delic.
 * This widget had to be coded from scratch, because the fundamental design of widgets
 * had been changed since dojo 0.9.x. Unlike to the old version this widget doesn't extend
 * a tooltip widget.
 *
 *  Summary:
 *  A square animation flys in and an information pane appears.
 *  Content of the information pane loads by xhr from an external url.
 *  By leaving the hover area or by leaving the information pane this disappears and
 *  the square animation flys out.
 *
 *  Receiving tag attributes:
 *  'href' : The url where to fetch the information pane content
 *  'context' : can be "category" or "theme". Appends a css class to the information pane
 *  'fadeOutDelay' : The time in ms until the information pane disappears. Default = 400 ms
 *  'isOpaqueSquare': Setting the opacity of the square animation. If this is undefined no
 *                    opacity will be set. Default = undefined
 */
dojo.provide("haufedojo.widget.tooltipoverview");

// debug now goes that way.
console.debug("providing haufe.widget.tooltipoverview");

// requirering the refactored widget superclass
dojo.require("dijit.z_Widget");

// building the widget class
dojo.declare("haufedojo.widget.tooltipoverview", //our subclass
 dijit.z_Widget, // superclasses
{
    href: "", // xhr get url
    context: "", // stylesheet decleration of the content node
    fadeOutDelay: 50, // Delay for fade out
    isOpaqueSquare: undefined, // opacity of the square animation
    square: null, // node square animation
    content: null, // node information pane
    shadow: null, // node information pane shadow
    squareStartX: 0, // x-coord of buttons center
    squareStartY: 0, // y-coord of buttons center
    squareEndX: 0, // x-coord of end fly in and information panes position
    squareEndY: 0, // y-coord of end fly in and information panes position
    squareEndWidth: 0, // width of end fly in and information panes width
    squareEndHeight: 0, // height of end fly in and information panes height
    inMotion: false, // Flag for detecting if the square animation is in motion
    isShowing: false, // Flag for detecting if the information pane is showing
    fadeIn: null, // variable for fade in animation
    fadeOut: null,// variable for fade out animation
    fadeOutTimer: null, // Timer for delay
    aOut: false, // flag a for detecting the specific mouse out by root node
    bOut: true, // flag b for detecting the specific mouse out by information pane
    //This is an extension of the Constructor
    postCreate: function(){
        console.debug("postCreate");
        this.createView();
        // inherited from the 0.4 widget solution
        switch (this.context) {
            case "category":
                this.content.className = "dojocategoryOverviewTooltip";
                break;
            case "theme":
                this.content.className = "dojothemeOverviewTooltip";
                break;
            default:
                this.content.className = "dojocategoryOverviewTooltip";
                break;
        }
        // callback function for xhr handling
        // also for setting the bounds of the 3 dom elements
        var bounding = dojo.hitch(this, function(response, ioArgs){
            this.content.innerHTML = response;
            var contentBounds = dojo.coords(this.content, true);
            var buttonBounds = dojo.coords(this.domNode, true);
            this.squareStartX = Math.round(buttonBounds.x + buttonBounds.w / 2);
            this.squareStartY = Math.round(buttonBounds.y + buttonBounds.h / 2);
            this.squareEndY = Math.round(buttonBounds.y + buttonBounds.h) - 2;

            // Improvement of the formerly used positioning
            // This automatically positions the information pane to the middle position
            // if the width is larger than 300 px
            var maxWidth = 300;
            if (contentBounds.w < maxWidth) {
                this.squareEndX = Math.round(buttonBounds.x) - 1;
            }
            else {
                this.squareEndX = Math.round(this.squareStartX - contentBounds.w / 2);
            }
            // This is a hack to emulate the formerly look and feel
            // adding 45 px to the width of the information pane
            var add2SquareEndWidth = 45;
            this.squareEndWidth = contentBounds.w + add2SquareEndWidth;
            this.squareEndHeight = contentBounds.h;
            // setting the bounds of the 3 elements
            this.setBounds(this.square, this.squareStartX, this.squareStartY, 0, 0);
            this.setBounds(this.content, this.squareEndX, this.squareEndY, contentBounds.w + 45, contentBounds.h);
            this.setBounds(this.shadow, this.squareEndX + 5, this.squareEndY + 5, contentBounds.w + 45, contentBounds.h);
            if(this.isOpaqueSquare)
                dojo._setOpacity(this.square,this.isOpaqueSquare);
        });

        // Loading the content using href
        dojo.xhrGet({
            url: this.href,
            load: bounding,
            error: function(response, ioArgs){
                console.log("Failed XHR: ", response, ioArgs);
            }
        });

        // Event binding
        this.connect(this.domNode, "onmouseover", "onMouseEnter");
        this.connect(this.domNode, "onmouseout", "onMouseLeave");
        this.connect(this.content, "onmouseover", "contentEntered");
        this.connect(this.content, "onmouseout", "contentLeaved");
        this.connect(window,"onresize","windowResize");
    },
    // Creating the view
    // Regarding the coding styleguide "style" shouldn't be used.
    // The following function is a workaround for several style instructions with dojo
    // to avoid a coding overhead
    createView: function(){
        var view = '<div id="squareAnimation" style="width:0px;height:0px;visibility:hidden;position:absolute; z-index:1000;background-color:#eeeeee;display:block;border:1pt solid #aaaaaa;"></div>' +
        '<div id="overviewContent" style="position:absolute;z-index:1002;visibility:hidden;"></div>' +
        '<div id="overviewShadow" style="visibility:hidden;position:absolute;z-index:1001;background-color:#000000;display:block;filter:alpha(opacity=50);opacity:0.5;"></div>';

        var wrap = document.createElement("DIV");
        wrap.innerHTML = view;
        dojo.body().appendChild(wrap);
        this.square = dojo.byId("squareAnimation");
        this.content = dojo.byId("overviewContent");
        this.shadow = dojo.byId("overviewShadow");
    },
    // helper for setting the visibility style to visible
    show: function(node){
        node.style.visibility = "visible";
    },
    // helper for setting the visibility style to hidden
    hide: function(node){
        node.style.visibility = "hidden";
    },
    // helper for setting the style bounds
    setBounds: function(node, left, top, width, height){
        var nS = node.style;
        if(left)
            nS.left = left + "px";
        if(top)
            nS.top = top + "px";
        if(width)
            nS.width = width + "px";
        if(height)
            nS.height = height + "px";
    },
    // Fired if button has been entered
    onMouseEnter: function(evt){
        this.aOut = false;
        if (this.fadeOutTimer) {
            clearTimeout(this.fadeOutTimer);
            this.fadeOutTimer = undefined;
        }

        if (this.inMotion || this.isShowing)
            return;

        this.fadeIn = dojo.animateProperty({
            node: "squareAnimation",
            properties: {
                height: {
                    start: '0',
                    end: this.squareEndHeight,
                    unit: 'px'
                },
                width: {
                    start: '0',
                    end: this.squareEndWidth,
                    unit: 'px'
                },
                left: {
                    start: this.squareStartX,
                    end: this.squareEndX,
                    unit: 'px'
                },
                top: {
                    start: this.squareStartY,
                    end: this.squareEndY,
                    unit: 'px'
                }
            },
            onPlay: dojo.hitch(this, function(){
                this.show(this.square);
                this.inMotion = true;
            }),
            onEnd: dojo.hitch(this, function(){
                this.hide(this.square);
                this.show(this.shadow);
                this.show(this.content);
                this.inMotion = false;
                this.isShowing = true;
                if((this.aOut && this.bOut)){
                    this.aOut = false;
                    this.bOut = true;
                    this.onMouseLeaveFollow();
                }
            })
        }).play();
    },
    // Fired if button has been left
    onMouseLeave: function(evt){
        this.aOut = true;
        if (this.inMotion)
            return;
        // Give user a delay until information pane disappears
        this.fadeOutTimer = setTimeout(dojo.hitch(this, this.onMouseLeaveFollow), this.fadeOutDelay);
    },
    onMouseLeaveFollow: function(){
        this.fadeOut = dojo.animateProperty({
            node: "squareAnimation",
            properties: {
                height: {
                    start: this.squareEndHeight,
                    end: '0',
                    unit: 'px'
                },
                width: {
                    start: this.squareEndWidth,
                    end: '0',
                    unit: 'px'
                },
                left: {
                    start: this.squareEndX,
                    end: this.squareStartX,
                    unit: 'px'
                },
                top: {
                    start: this.squareEndY,
                    end: this.squareStartY,
                    unit: 'px'
                }
            },
            onPlay: dojo.hitch(this, function(){
                this.show(this.square);
                this.hide(this.shadow);
                this.hide(this.content);
                this.isShowing = false;
                this.inMotion = true;
            }),
            onEnd: dojo.hitch(this, function(){
                this.hide(this.square);
                this.inMotion = false;
            })
        }).play();
    },
    // Fired if information pane has been entered
    contentEntered: function(evt){
        this.bOut = false;
        if (this.fadeOutTimer) {
            clearTimeout(this.fadeOutTimer);
            this.fadeOutTimer = undefined;
        }
        this.isShowing = true;
    },
    // Fired if information pane has been left
    contentLeaved: function(evt){
        this.bOut = true;
        this.fadeOutTimer = setTimeout(dojo.hitch(this, this.onMouseLeaveFollow), this.fadeOutDelay);
    },
    // Actions if window resize
    windowResize: function(evt){
        var bounds = dojo.coords(this.domNode,true);
        var contentBounds = dojo.coords(this.content, true);
        this.squareStartX = Math.round(bounds.x+bounds.w/2);
        var maxWidth = 300;
            if (contentBounds.w < maxWidth) {
                this.squareEndX = Math.round(bounds.x) - 1;
            }
            else {
                this.squareEndX = Math.round(this.squareStartX - contentBounds.w / 2);
            }
        this.content.style.left = this.squareEndX + "px";
        this.shadow.style.left = this.squareEndX + 5 + "px";
    }

});
