/**
 * @author Fahrettin Kutyol
 * This is the rebuilt for dojo 1.2.x of the former 0.4 widget by Josip Delic and Khaled Soliman.
 * 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:
 *  loads content via xhr and provides the content by a fade in and fade out animation.
 *
 *  Receiving tag attributes:
 *  'href' : The url where to fetch the information pane content
 *  'connectId': The node where to connect main actions
 */
dojo.provide("haufedojo.widget.bcquickinfo");

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

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

// building the widget class
dojo.declare("haufedojo.widget.bcquickinfo", //our subclass
 dijit.z_Widget, // superclasses
{
    href: "", // get information from this url
    connectId: "", // bind primary mouse events to this id - EOF receiving tag attributes
    init: true, // if true, fires an action by the first mouseover
    connectNode: undefined, // node of the connectId
    isShowing: false, // does the information show?
    comingFromContent: false,// if a mouse over got fired this is how to test if it's reffering from the information pane
    fadeOutTimer: undefined, // the timer to delay the fade out animation
    fadeOutDelay: 100, // delay until fade out gets fired
    shadowNode: undefined, // shadow node
    shadowMargin: 4, // margin of the shadow
    isLoaded: false, // Wait until content is loaded
    extraMarginY: 20, // margining y of the content
    fadeOutAnimation: undefined, // container for the content fade out animation
    fadeOutShadowAnimation: undefined, // container for the shadow fade out animation
    contentHeight: 0, // Height of the content pane

    // Called after Constructor
    postCreate: function(){
        // getting the widget css
        this.importCss("/haufedojo/widget/bcquickinfoStyles.css");

        //adjusting the content
        this.domNode.className = "dojoTooltipBcQuickInfo";
        contentStyle = this.domNode.style;
        contentStyle.position ="absolute";
        contentStyle.display ="block";
        contentStyle.visibility = "hidden";
        contentStyle.zIndex = "100000";
        contentStyle.overflowX = "hidden";
        contentStyle.overflowY = "hidden"; //"auto", "visible", "scroll"
        this.connectNode = dojo.byId(this.connectId);

        // creating the shadow element
        this.shadowNode = document.createElement("DIV");
        this.shadowNode.className = "bcquickinfoShadow";
        var shadowStyle = this.shadowNode.style;
        shadowStyle.position = "absolute";
        shadowStyle.display = "block";
        shadowStyle.visibility = "hidden";
        var inner = "<div class='rBoxShadow' id ='"+this.id+"Shadow'><span class='rBoxTop'><span class='rBox1'></span><span class='rBox2'></span><span class='rBox4'>";
            inner += "<span class='rBoxCenterTop'></span></span></span><div class='rBoxOuterBox' id='quickInfoShadowBox'><div class='rBoxInnerBox' >";
            inner += "</div></div><span class='rBoxBottom'><span class='rBox4'><span class='rBoxCenterBottom'></span></span>";
            inner += "<span class='rBox2'></span><span class='rBox1'></span></span></div>";
            this.shadowNode.innerHTML = inner;
        dojo.body().appendChild(this.shadowNode);
        this.shadowNodeInnerBox = dojo.byId('quickInfoShadowBox');
        this.shadowNodeInnerBox.removeAttribute('id');
        dojo._setOpacity(dojo.byId(this.id+"Shadow"),0.2);

        // Loading the content using href
        var xhrArgs = {
            handleAs:"text",
            timeout: 60000,
            url: this.href,
            load:  dojo.hitch(this,"callback"),
            error: function(response, ioArgs){
                console.log("Failed XHR: ", response, ioArgs);
            }
        };
        dojo.xhrGet(xhrArgs)
        // binding events to connectId
        this.connect(this.connectNode, "onmouseover", "onMouseOver");
        this.connect(this.connectNode, "onmouseout", "onMouseOut");
        // binding events to the content node
        this.connect(this.domNode, "onmouseover", "contentMouseOver");
        this.connect(this.domNode, "onmouseout", "contentMouseOut");
        // binding event if window resize
        this.connect(window,"onresize","windowResize");

    },
    callback : function(response, ioArgs){
        try {
            //this.domNode.appendChild(response)
            this.domNode.innerHTML = response;
        }
        catch(e) {
            // IE Workaround - innerHTML throws and error when trying to insert block elements
            // whithin an inline element
            dojo.body().appendChild(this.domNode)
            this.domNode.innerHTML = response;
        }
        var connectBounds = dojo.coords(this.connectNode, true);
        var contentBounds = dojo.coords(this.domNode, true);

        dojo.body().appendChild(this.domNode);
        this.domNode.style.visibility = "hidden";
        this.domNode.style.left = (connectBounds.x + connectBounds.w/2) + "px";
        this.domNode.style.top = (connectBounds.y + this.extraMarginY) + "px";
        this.shadowNode.style.left = (connectBounds.x + connectBounds.w/2 + this.shadowMargin) + "px";
        this.shadowNode.style.top = (connectBounds.y + this.extraMarginY + this.shadowMargin) + "px";
        this.shadowNode.style.width = contentBounds.w + "px";
        this.isLoaded = true;
        this.extraMargin = 40
        },

    // Internal widget css requirement doesn't exist anymore in dojo 1.x
    // This is a hack to import a css file
    importCss: function(fileName){
        var fileref = document.createElement("link");
        fileref.setAttribute("rel", "stylesheet");
        fileref.setAttribute("type", "text/css");
        fileref.setAttribute("href", fileName);
        if (typeof fileref != "undefined")
            document.getElementsByTagName("head")[0].appendChild(fileref);
    },

    // Connect node mouse over
    onMouseOver: function(evt){

        // cancel until content is loaded
        if(!this.isLoaded)
            return;

        // initializing the height by first call. needed because the real height can not be
        // fetched after loading of the content.
        if (this.init) {
            var newHeight = dojo.coords(this.domNode, true).h - this.shadowMargin;
            this.contentHeight = newHeight;
            // because IE does interpret style `height:100%` different than FF, it need's to be setted explicitely.
            this.shadowNodeInnerBox.style.height = (newHeight - this.shadowMargin) + "px";
            this.init = false;
        }

        // cancelling the fade out timer
        if (this.fadeOutTimer) {
            clearTimeout(this.fadeOutTimer);
            this.fadeOutTimer = undefined;
        }
        // cancelling all fade out animation if in motion
        if (this.fadeOutAnimation){
            this.fadeOutAnimation.stop();
            this.fadeOutAnimation = undefined;
            this.fadeOutShadowAnimation.stop();
            this.fadeOutShadowAnimation = undefined;
        }
        // cancelling mouse over animation if content already shows
        if (this.isShowing || this.comingFromContent)
            return;

        var connectBounds = dojo.coords(this.connectNode, false);
        var standardY = connectBounds.y + this.extraMarginY;
        var viewPort = dijit.getViewport();
        var bottom = standardY + this.contentHeight;
        var scroll = dojo._docScroll().y;

        if(bottom > viewPort.h){
            this.domNode.style.top = (scroll + viewPort.h - this.contentHeight - (this.shadowMargin*2)) + "px";
            this.shadowNode.style.top = (scroll + viewPort.h - this.contentHeight - this.shadowMargin) + "px";
        } else {
            this.domNode.style.top = (standardY + scroll) + "px";
            this.shadowNode.style.top = (standardY + scroll + this.shadowMargin) + "px";
        }


        this.domNode.style.display = "block";
        this.shadowNode.style.display = "block";
        dojo._setOpacity(this.domNode,0);
        dojo._setOpacity(this.shadowNode,0);
        this.domNode.style.visibility = "visible";
        this.shadowNode.style.visibility = "visible";

        // content fade in animation
        dojo.fadeIn({
            node: this.domNode
        }).play();
        // shadow fade in animation
        dojo.fadeIn({
            node: this.shadowNode
        }).play();
    },

    // Connect node mouse out
    onMouseOut: function(evt){
        // cancel until content is loaded
        if(!this.isLoaded)
            return;

        // providing a delay
        this.fadeOutTimer = setTimeout(dojo.hitch(this, this.onMouseOutFollow), this.fadeOutDelay);
    },

    // Follow up after delay function for connect node mouse out
    onMouseOutFollow: function(){
        this.isShowing = false;
        this.comingFromContent = false;

        // content fade out animation
        this.fadeOutAnimation =  dojo.fadeOut({
            node: this.domNode,
            onEnd: dojo.hitch(this, function(){
                if(!this.isShowing)
                    this.domNode.style.display = "none";
            })
        }).play();

        // shadow fade out animation
        this.fadeOutShadowAnimation = dojo.fadeOut({
            node: this.shadowNode,
            onEnd: dojo.hitch(this, function(){
                if(!this.isShowing)
                    this.shadowNode.style.display = "none";
            })
        }).play();
    },
    // content node mouse over
    contentMouseOver: function(evt){
        this.isShowing = true;
        if (this.fadeOutTimer) {
            clearTimeout(this.fadeOutTimer);
            this.fadeOutTimer = undefined;
        }
    },
    // content node mouse out
    contentMouseOut: function(evt){
        this.comingFromContent = true;
        this.fadeOutTimer = setTimeout(dojo.hitch(this, this.onMouseOutFollow), this.fadeOutDelay);
    },
    // fired if window resizes. adjusting the left position
    windowResize: function(evt){
        var bounds = dojo.coords(this.connectNode,true);
        if(bounds.x > 0) {
            this.domNode.style.left = bounds.x + this.extraMargin+ "px";
            this.shadowNode.style.left = (bounds.x + this.shadowMargin + this.extraMargin) + "px";
        }
    }

});


