function Popup (el){

    Finder.call(this, el);

    this.init();

}

extend(Popup, Finder);

Popup.prototype.baseattr = "popup";

Popup.prototype.attributes = {"id" : {},
                              "contentUrl" : {}, 
                              "popupUrl" : {}, 
                              "popupContent" : {}, 
                              "closeCallback" : {}, 
                              "popupClass" : {}, 
                              "eventLaunch" : {"default" : "click"},
                              "eventClose" : {},
                              "launch" : {"default" : true},
                              "launchClose" : {"default" : "owner"},
                              "fadeDecrement" : {},
                              "fadeInterval" : {},
                              "closeTime" : {},
                              "parent" : {}
                             }


Popup.prototype.getDocument = function(){
    return Popup.prototype.document ? Popup.prototype.document : document;
};


Popup.prototype.getBaseXHROpts = function (){ 

    return {"method" : "GET",
            "timeout" : 10000,
            "params" : null,
            "async" : false
           }; 
}

Popup.prototype.init = function(){
    var _this = this;

    this.setPopupContainer();
    this.setContent();
    this.addCloseListeners();

    //add event listeners
    if(this.owner) {
        if(this.eventLaunch == "mouseoverout"){
            addMouseOverOutListener(this.owner, function(e){_this.show(e);}, function(e){_this.hide(e);});
        } else if (this.eventLaunch == "toggle"){

            function makeToggleClose(){ 
                return function (){
                    _this.hide();
                    removeEventListener(_this.owner, "click", toggleClose);
                    addEventListener(_this.owner, "click", toggleShow);
                }
            }

            function makeToggleShow(){
                return function(){
                    _this.show();
                    removeEventListener(_this.owner, "click", toggleShow);
                    addEventListener(_this.owner, "click", toggleClose);
                }
            }

            var toggleClose = makeToggleClose();            
            var toggleShow = makeToggleShow();

            addEventListener(this.owner, "click", toggleShow);

        } else if (this.eventLaunch && this.launch) {
            addEventListener(_this.owner, _this.eventLaunch, function(e){_this.show(e)});
        }

        if(this.eventClose)
            addEventListener(_this.launchClose == "owner" ? _this.owner : _this.popup, _this.eventClose, function(e){stopEvent(e); _this.hide();});

    }





}

Popup.prototype.addCloseListeners = function(){
    var _this = this;
    //add close listener
    //var result = getNodesWithAttr(this.popup, this.XPATH_POPUP_CLOSE);
    var result = getNodesWithAttr(this.popup, "popupClose");
    if(result && result.length > 0) {

        function makeDoClose(){
            return function(){
                _this.hide(1,0);

                if(this.closeCallback)
                    this.closeCallback();
            }
        }

        for(var x = 0; x<result.length; x++){
            if(!result[x].popupCloseHandler){
                result[x].popupCloseHandler = makeDoClose();
                addEventListener(result[x], "click", result[x].popupCloseHandler);
            }
        }
    }

}

Popup.prototype.reset = function(){

    this.setPopupContainer();
    this.setContent();

}

Popup.prototype.setPopupContainer = function(popupUrl){
    var div = this.getDocument().createElement("DIV");

    if(popupUrl || this.popupUrl) {
        var opts = this.getBaseXHROpts();
        opts.url = popupUrl ? popupUrl : this.popupUrl;
        var req = XHR.prototype.get(opts);
        div.innerHTML = req.responseText;
        this.popup = div.firstChild;
        addClass(this.popup, "hide");
        createEvent(this.getDocument().body, "htmlchange");

    } else if(this.popupContent){
        this.popup = div;
        this.popup.innerHTML = this.popupContent;
     } else {
        var result = getNodesWithAttr(this.owner, "popupContent");
        if(result.length > 0) 
            this.popup = result[0];
    }


    if(!isChildOf(this.popup, this.owner)){
        if(this.parent) {
            if(this.parent == "owner") {
                this.parent = this.owner;
            } else {
                this.parent = $(this.parent) ? $(this.parent) : this.getDocument().body;
            }
            this.parent.appendChild(this.popup);

        }  else {
            this.owner.parentNode.insertBefore(this.popup, this.owner.nextSibling);
        }
    }

    if(this.popup){
        if(this.popupClass)
            this.popup.className = this.popupClass;
            //addClass(this.popup, this.popupClass);

        if(this.postAppend) {
            this.postAppend(this.owner, this.popup);
        } else {
            this.hide();
        }
    }

}


/**
 * @contentUrl Optional param for dynamic setting of the content
 */
Popup.prototype.setContent = function(contentUrl){
    if(this.contentUrl || contentUrl){
        var opts = this.getBaseXHROpts();
        opts.url = contentUrl ? contentUrl : this.contentUrl;
        var req = XHR.prototype.get(opts);

        var res = getNodesWithAttr(this.popup, "popupContent");

        var parent =  res[0] ? res[0] : this.popup;
        xInnerHTML(parent, req.responseText);
    } 
}


Popup.prototype.show = function(e){
    this.setOpacity(this.popup, 1);
    removeClass(this.popup, "hide");

    if(this.showPosition){
        this.showPosition(e, this.popup);
    }



    var _this = this;
    if(this.closeTime){
        var t = setTimeout(function(){_this.hide();}, this.closeTime);
    }
}

Popup.prototype.setOpacity = function(el, opacity){
    var style = el.style;
    var op = opacity * 100;
    if (el.filters != undefined) {
        try {
            style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + op + ")";
        } catch(e){
            style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + op + ")";
        }
    }
    if(style.MozOpacity != undefined)
        style.MozOpacity = opacity;
    if(style.opacity != undefined)
	    style.opacity = opacity;

}

Popup.prototype.getOpacity = function(el){
    var style = el.style;
    if(!style)
        return 0; 

    if (el.filters != undefined){
        var op = style.filter.match(/\d+/);
        return op != null ? op[0]/100 : 0;
    }
    if(style.MozOpacity != undefined)
        return style.MozOpacity;

    if(style.opacity != undefined)
	    return style.opacity;

}

Popup.prototype.fade = function(el, decrement, interval, callback){
    var _this = this;
    var intervalID;
    startFade();
    addEventListener(el, "mouseover", stopFade);
    addEventListener(el, "mouseout", startFade);

    function stopFade(){
        _this.setOpacity(el, 1);
        clearInterval(intervalID);
        intervalID = null;
    }

    function startFade(){
        if(!intervalID)
            intervalID = setInterval(startFade, interval);
        var opacity = _this.getOpacity(el)
        if(opacity > 0) {
	        _this.setOpacity(el, opacity - decrement);
        } else {
            stopFade();
            removeEventListener(_this.popup, "mouseover", stopFade);
            removeEventListener(_this.popup, "mouseout", startFade);
            clearInterval(intervalID);
            callback();
        }

    }

}

Popup.prototype.hide = function(fadeDecrement, fadeInterval){
    var decr = fadeDecrement != undefined ? fadeDecrement : this.fadeDecrement;
    var interval = fadeInterval != undefined ? fadeInterval : this.fadeInterval;

    var _this = this;
    function doHide(){
        addClass(_this.popup, "hide");
    }

    if(decr != null && interval != null) {
        this.fade(this.popup, decr, interval, doHide);
    } else {
        doHide();
    }

}


Popup.prototype.invoke("Popup");