var Popup = new Class({

    Implements: [Options, Events],
    
    options: {
        width: 350,
        offsetHeight: 0, // % between [-1, 1]
        zIndex: 2,
        filter: {
            opacity: 0.85,
            bgColor: "#000000"
        },
        draggable: true,
        duration: 100,
        className: "popupContainer"
    },
    
    initialize: function(options) {
        this.setOptions(options);
        
        this.container = new Element("div", {
            "class": this.options.className,
            "styles": {
                'position': 'absolute',
                'display': 'none',
                'opacity': 0,
                'width': this.options.width,
                'z-index': this.options.zIndex,
                'text-align': 'left'
            }
        });
        
        this.top = new Element("div", {
            "class": "popupTop"
        });
        this.top.inject(this.container);
        
        this.middle = new Element("div", {
            "class": "popupMiddle"
        });
        this.middle.inject(this.container);
        
        this.bottom = new Element("div", {
            "class": "popupBottom"
        });
        this.bottom.inject(this.container);
        
        this.container.inject(document.body);
        
        if(this.options.draggable) {
            this.top.style.cursor = "move";
            new Drag(this.container, {
                handle: this.top
            });
        }
        
        
        // filter
        this.filter = new Element("div", {
            "styles": {
                'position': 'absolute',
                'display': 'none',
                'opacity': 0,
                'left': 0,
                'top': 0,
                'z-index': this.options.zIndex - 1,
                'background-color': this.options.filter.bgColor
            }
        });
        
        this.filter.inject(document.body);
        
        
        // popup fx
        this.showFx = new Fx.Tween(this.container, {
            link: "cancel",
            property: "opacity",
            duration: this.options.duration
        });
        this.showFx.addEvent("onComplete", function(popup) {
            if(this.subject.getOpacity() == 0) {
                // hidden
                popup.filter.setStyle("display", "none");
                popup.container.setStyle("display", "none");
            } else {
                // dispayed
            }
        }.pass(this, this.showFx));
        
        // filter fx
        this.showFilterFx = new Fx.Tween(this.filter, {
            link: "cancel",
            property: "opacity",
            duration: this.options.duration
        });
        
        window.addEvent("resize", function() {
            this.redraw();
        }.bind(this));
        
        window.addEvent("scroll", function() {
            var scroll = window.getScroll();
            this.filter.setStyles({
                'top' : scroll.y,
                'left': scroll.x
            });
        }.bind(this)); 
    },
    
    setHeader: function(html) {
        this.top.innerHTML = html;
    },
    
    setContent: function(html) {
        this.middle.innerHTML = html;
    },
    
    setBottom: function(html) {
        this.bottom.innerHTML = html;
    },
    
    grabHeader: function(node) {
        node = $(node);
        this.top.grab(node);
        node.setStyle("display", "block");
    },
    
    grabContent: function(node) {
        node = $(node);
        this.middle.grab(node);
        node.setStyle("display", "block");
    },
    
    grabBottom: function(node) {
        node = $(node);
        this.bottom.grab(node);
        node.setStyle("display", "block");
    },
    
    redraw: function() {
        var wSize = window.getSize();
        var scroll = window.getScroll();
        this.filter.setStyles({
            "height": wSize.y,
            "width": wSize.x
        });
        var top = (wSize.y/2 * (1 + this.options.offsetHeight) - this.container.offsetHeight/2 + scroll.y);
        this.container.setStyles({
            "top": top > 0 ? top : 0,
            "left": wSize.x/2 - this.container.offsetWidth/2 + scroll.x
        });
    },
    
    open: function() {
    	this.fireEvent("beforeOpen");
        this.filter.setStyle("display", "block");
        this.container.setStyle("display", "block");
        this.redraw();
        this.showFilterFx.start(this.options.filter.opacity);
        this.showFx.start(1);
    },
    
    close: function() {
        this.showFilterFx.start(0);
        this.showFx.start(0);
    }
});

var ConfirmPopup = new Class({
    Extends: Popup,
    
    options: {
        okButtonLabel: "ok",
        cancelButtonLabel: "cancel",
        onOk: null,
        onCancel: null,
        okValidateFn: function() {
			return true
		}
    },
    
    initialize: function(options) {
        this.parent(options);
        this.bottom.setStyle("text-align", "right");
        this.setBottom(this.options.okButtonLabel, this.options.cancelButtonLabel);
        var buttons = $$(this.bottom.getElementsByTagName("button"));
        buttons[0].addEvent("click", function() {
            this.close();
            if(typeof this.options.onCancel == "function") {
                this.options.onCancel(this.args.fnArgs);
            }
        }.bind(this));
        buttons[1].addEvent("click", function() {
        	if(this.options.okValidateFn()) {
	            this.close();
	            if(typeof this.options.onOk == "function") {
	                this.options.onOk(this.args.fnArgs);
	            }
        	}
        }.bind(this));
    },
    
    setBottom: function(okButtonLabel, cancelButtonLabel) {
        this.bottom.innerHTML = "<a href='javascript:void(0);'><button class='cancelButton' type='button'>" + cancelButtonLabel + "</button></a>"
                              + "<a href='javascript:void(0);'><button class='okButton' type='button'>" + okButtonLabel + "</button></a>";
    },
    
   /**
    * @param args:
    *   - fnArgs
    *   - onOk : @see options
    *   - onCancel : @see options
    */
    confirm: function(args) {
        this.args = args || {};
        if(typeof this.args.onOk == "function") {
            this.options.onOk = this.args.onOk;
        }
        if(typeof this.args.onCancel == "function") {
            this.options.onCancel = this.args.onCancel;
        }
        if(typeof this.args.okValidateFn == "function") {
            this.options.okValidateFn = this.args.okValidateFn;
        }
        this.open();
    }
});
