var Overlay = new Class({
    options: {
        'executeScripts':       true,       // Option to evaluate scripts in the response text
        'ajaxMethod':           'get',      // Option to evaluate the whole response text
        'status':               'closed'   // Status of ModalWindow (open, recycling or closed)
    },
    
    initialize: function(templateUrl, options) {
        this.template = {'url': templateUrl, 'base': null, 'title': null, 'properties': null};
        this.eventKeyDown = this.closeKeyListener.bindWithEvent(this);
        this.eventPosition = this.setCover.bind(this);
        this.getTemplate();
        this.overlayMargin = 0;
        this.setOptions(options);
    },
    
    buildTemplate: function(response) {
        this.template.base = response.body;
        this.template.title = response.title;
        var properties = {};
        for(var i = 0; i < response.scripts.length; i++) {
            if(response.scripts[i].type.toLowerCase() == "text/properties") {
                properties = response.scripts[i].code;
                break;
            }
        }
        this.template.properties = eval("(" + properties + ")");
        this.overlay = new Element('div', {'id': 'overlay' + new Date().getTime().toString()}).setStyles({'position': 'absolute', 'zIndex': '1001', 'left': '50%', 'overflow': 'hidden', 'width': this.template.properties.options.initialWidth + 'px', 'marginLeft': '-' + (this.template.properties.options.initialWidth / 2) + 'px', 'display': 'none'});
        this.overlay.setHTML(this.template.base);
        
        this.templateHeight = this.overlay.offsetHeight;        
        if(this.template.properties.options.overlayMargin) this.overlayMargin = this.template.properties.options.overlayMargin;
        
        if(this.template.properties.cover) this.buildCover();
    },
    
    buildCover: function() {
        var coverProps = this.template.properties.cover;
        if(coverProps.enabled) {
            var coverId = "cover" + new Date().getTime().toString();
            this.cover = new Element('div', {'id': coverId});
            this.cover.setStyles({'position': 'absolute', 'width': '100%', 'left': '0', 'display': 'none', 'zIndex': '1000'});
            if(coverProps.background) this.cover.setStyle('background-color', coverProps.background);
            if(coverProps.opacity) this.cover.setStyle('opacity', coverProps.opacity);            
            if(coverProps.close) {this.cover.addEvent('click', this.close.bind(this)); this.cover.setStyle('cursor', 'pointer');} 
            this.cover.injectInside(document.body);
        }
    },
    
    displayContent: function(response) {
        if(this.template.properties.zones.titlebar && response.title) $(this.template.properties.zones.titlebar).setHTML(response.title);
        if(response.body) $(this.template.properties.zones.content).setHTML(response.body);
        if(this.template.properties.options.autoHeight) {
            var maxHeight = (Window.getHeight() - (this.overlayMargin*2))-60;
            if((this.overlay.offsetHeight > maxHeight) && (maxHeight > 0)) {$(this.template.properties.zones.content).setStyle('height', maxHeight + 'px');}
        }
        if(this.options.executeScripts && response.scripts) this.contentLoader.executeScripts();
    },
    
    getTemplate: function() {
        var buildTemplate = this.buildTemplate.bind(this);
        this.templateLoader = new Loader(this.template.url, {onLoad: buildTemplate});
        this.templateLoader.load();
    },
    
    getContent: function(url, formid) {
        var displayContent = this.displayContent.bind(this);
        this.contentLoader = new Loader(url, {onLoad: displayContent});
        this.contentLoader.load();
    },
    
    setCover: function() {
        this.cover.setStyles({'display': '', 'top': Window.getScrollTop() + 'px', 'height': Window.getHeight() + 'px'});
    },
    
    setButtons: function() {
        var closers = this.template.properties.buttons.close;
        if(closers != null) {
            for(var i=0; i < closers.length; i++) {
                $(closers[i]).setStyle('cursor', 'pointer');
                $(closers[i]).addEvent('click', this.close.bind(this));
            }
        }
    },
    
    open: function(url, formid) {
        if(this.template.properties.cover && this.template.properties.cover.enabled) this.setCover();
        this.top = Window.getScrollTop() + this.overlayMargin;
        this.overlay.setStyles({'display': '', 'top': this.top + 'px'});
        
        if(this.options.status == "closed") this.overlay.injectInside(document.body)//this.template.properties.transitions.open();
        else if(this.options.status == "open") this.template.properties.transitions.recycle();

        $(this.template.properties.zones.content).setStyle('height', '');
        document.addEvent('keydown', this.eventKeyDown);
        window.addEvent('scroll', this.eventPosition).addEvent('resize', this.eventPosition);
        
        if(this.template.properties.buttons) this.setButtons();
        
        this.options.status == "open";
        this.getContent(url, formid);
    },    
    
    closeKeyListener: function(event) {
        // close the ModalWindow when the user presses CTRL + W, CTRL + X, ESC
        if((event.control && event.key == "w") || (event.control && event.key == "x") || (event.key == "esc")) {
            this.close();
            event.stop();
        }
    },
    
    close: function() {
        if(this.template.properties.transitions && this.template.properties.transitions.close) {
        }
        else {
            this.overlay.setStyle('display', 'none');
            this.cover.setStyle('display', 'none');
        }
        document.removeEvent('keydown', this.eventKeyDown);
        window.removeEvent('scroll', this.eventPosition).removeEvent('resize', this.eventPosition);
        $(this.template.properties.zones.content).setHTML("");
        this.options.status = "closed";
    }
});

Overlay.implement(new Events, new Options);