/*-----------------------------------------------
    kui.window - Core Window Extension Library
    Author: (Ran Baron 12/2009)
    Copyright (c) 2009 Flying Baron.
  -----------------------------------------------*/
  
kui.win = null;
kui.openWin = function(options) {
    if (options && options.update) { kui.win.update = options.update; }
    var newWin = new top.kui.window(Object.extend({
            theme : options.theme || 'hBox',
            title : options.title || '',
            src   : options.src || ((options.srcObj) ? options.srcObj : null) || null
        }, options || {}));
};
kui.overlay = function(){ var overWin = new kui.window({overlayOnly:true,shaded:false,close:false}); };
kui.resizeOverlay = function(){
        var vph = kui.win.viewport.getHeight(), bh = kui.win.container.getHeight();
        vph = (vph>bh) ? vph : bh;
        $$('div.overlay').invoke('setStyle','height:'+vph+'px;width:100%');
        if (kui.win.active()) { (function(){
            kui.win.active().setCenter().resize();
        }).defer(); }
    };

kui.inBounds = function(options) {
    if (options.width) {
        var winDims = top.document.viewport.getDimensions(), defWidth = 790;
        options.width = (options.width) ? (Number(options.width)>(winDims.width-60)) ? winDims.width-60 : Number(options.width) : defWidth;
        if (options.height) {
            options.height    = (Number(options.height)>(winDims.height-60)) ? (winDims.height-60) : Number(options.height);
        }
    }
    return options;
};

kui.windowManager = Class.create({
    options: {
        container:   null, // will default to document.body
        zIndex:      500000
    },

    initialize: function(options) {    
        this.options = Object.extend(this.options, options || {});
        this.container = $(this.options.container || document.body);
        if (this.container === $(document.body)) {
            this.viewport = top.document.viewport;
            this.scrollContainer = window;
        } else { this.viewport = this.scrollContainer = this.container; }
        this.stack = new kui.windowManager.Stack();
    },
  
    active:function()  { return kui.win.stack.windows.last() || false; },
    parent:function()  { return (kui.win.active()) ? kui.win.active().options.caller : window; },
    destroy:function() { this.windows().invoke('destroy'); this.stack.destroy(); },
    update:function()  {},
    register:function(win) { this.stack.add(win); this.options.zIndex++; },
    unregister:function(win) { this.stack.remove(win); this.options.zIndex--; }
});
kui.windowManager.Stack = Class.create(Enumerable, {
    initialize: function() { this.windows = [ ]; },
    add: function(win, position) { this.windows.splice(position || this.windows.length, 0, win); },
    remove: function(win) { this.windows = this.windows.without(win); }
});

kui.window = Class.create({
    options : {},
    
    initialize: function(options) {
        var defOptions = {
            windowManager: null,
            ajax:          null,
            id:            null,
            top:        0,
            left:       0,
            width:      790,
            height:     450,
            shadow:     false,
            overlay:    null,
            shaded:     true,
            close:      true,
            closeBtn:   false,
            zIndex:     null,
            theme:      'hBox',
            caller:     window
        };
        this.options = Object.extend(defOptions, options || {});
        this.options.o_height = this.options.height;
        this.options.o_width = (this.options.width+14); //14 as extra border/padding.
        
        //Register Event Callbacks
        this.handlers = (options.callback) ? options.callback : {};
        if (this.options.srcObj) { this.options.src = $(this.options.srcObj).readAttribute('href'); }
        if (this.options.timer)  { this.setTimer(this.options.timer); }
        
        this.windowManager = kui.win;
        this.windowManager.register(this);
        this.options.zIndex = this.windowManager.options.zIndex;

        if (!this.options.maximize) { this.createOverlay(); }
        else {
            var vpDims = top.document.viewport.getDimensions();
            this.options.width  = vpDims.width;
            this.options.height = vpDims.height;
            this.options.shaded = false;
            this.options.theme  = 'hMax'; 
        }

        if (this.options.overlayOnly) { return; }
        
        this.create();
        this.id = this.element.id;

        //Hide Flash Content from Macs
        if (navigator.userAgent.indexOf("Mac")!=-1) { var flashMods = $$('div.flashModule').each(function(idx){idx.setStyle({visibility:'hidden'});}); }

        this.render();
    },
  
      callback: function(event, options) {
        //if (window.console) { console.log(event); console.log(options); }
        if (this.handlers[event]) { this.handlers[event](options||{}); }
    },

    overlayClicked : function() { 
        if (this.options.overconfirm) { if (!confirm('Are you sure you wish to close this window?')) { return; }}
        if (this.options.overfunction) { this.options.overfunction(); }
        this.callback('overlay:onClick',null);
        this.close(); 
    },
    createOverlay : function() {
        var ovDims = kui.win.viewport.getDimensions();
        var bdDims = kui.win.container.getDimensions();
        ovDims.height = (ovDims.height>bdDims.height) ? ovDims.height : bdDims.height;
        ovDims.width = (ovDims.width>bdDims.width) ? ovDims.width : bdDims.width;
        this.overlay = this.createDiv("overlay", {    
              style: "height:"+ovDims.height+"px;width:"+ovDims.width+"px;z-index:"+this.options.zIndex
        });
        if (!this.options.shaded) { $(this.overlay).addClassName('clear'); }
        this.overlay.identify();
        
        if (this.options.close) {
            this.overlay.observe("click",              this.overlayClicked.bind(this))
                        .observe("mousewheel",         function(event){ Event.stop(event);}, false)
                        .observe("DOMMouseScroll",     function(event){ Event.stop(event);}, false);
        } else {
             this.overlay.setStyle({cursor:'default'});
        }
        this.addElements(this.overlay);
        Event.observe(window,'resize',kui.resizeOverlay,false);
        this.stopScroll(true);
    },
  
    stopScroll:function(state){
        //Stop Page Scroll
        if (state) {
            Event.observe(window,'DOMMouseScroll',function(event){Event.stop(event);});
        } else {
            Event.stopObserving(window,'DOMMouseScroll');
        }
    },
  
    render: function() {
        this.addElements(this.element);
        this.setBounds(this.options);
        this.visible = true;
        if (this.options.onload) { this.options.onload(); }
        this.callback('window:load',null);
    },
    
    setTimer : function (timer) { 
        var defTime = (!timer) ? 2800 : timer;
        if (defTime!=="") { 
            this.options.timeoutObj = window.setTimeout(function(){ if (this && this.visible) { 
                if (this.options.timeoutObj) { window.clearTimeout(this.options.timeoutObj); }
                this.close(); 
            }}.bind(this), defTime); }
    },
  
    close: function(event, options) {
        if (event) { event.stop(); }
        if ((options && options.confirm) || this.options.confirm) { if (!confirm('Are you sure you wish to close this window?')) { return; }}
        this.hide();
        if (this.overlay) { 
            this.stopScroll(false);
            this.overlay.remove(); 
        }
        
        //Show Flash Content for Macs
        if (navigator.userAgent.indexOf("Mac")!=-1) { var flashMods = $$('div.flashModule').each(function(idx){$(idx).setStyle({visibility:'visible'});}); }
        
        this.windowManager.unregister(this);
        if ((options && options.reload) || this.options.reload===true) { klGeneric.pageRefresh(); }
        if ((options && options.onclose) || this.options.onclose) { this.options.onclose(); }
        this.callback('window:close',options || {});
    },
  
    setCenter: function(options) {
        var size      = this.element.getScrollDimensions();
        viewport      = this.windowManager.viewport;
        viewportArea  = viewport.getDimensions();
        this.options.top  = (viewportArea.height - size.height) / 2;
        this.options.left = (viewportArea.width  - size.width)  / 2;
        var winTop  = ((this.options.maximize) ? 0 : (this.options.top>0) ? this.options.top : 5);
        var winLeft = ((this.options.left>0) ? this.options.left : (this.options.maximize) ? 0 : 5);
        if (Prototype.Browser.IE6) { 
            this.element.setStyle({position:'absolute'}); 
            scrollDims = document.viewport.getScrollOffset();
            winTop = winTop+scrollDims[1];
        }
        this.element.setStyle({top:winTop+'px',left:winLeft+'px'});
        return this;
    },
    
    resize: function() {
        this.validateBounds(this.options);
        if (this.options.height!=this.options.o_height) { this.options.height = this.options.o_height; }
        if (this.options.width!=this.options.o_width) { this.options.width = this.options.o_width; }
        if (this.content.getWidth()>this.options.o_width) { this.options.width = this.options.o_width; }
        this.setBounds(this.options);
        var iframe = this.content.down('iframe');
        if (iframe) { iframe.writeAttribute('height','100%'); }
    },
    
    setBounds: function(options) { 
        this.validateBounds(options);
        if (options.height) { $(this.content).setStyle({ height:options.height+'px' }); }
        if (options.width)  { $(this.element).setStyle({ width:options.width+'px' }); }
        this.setCenter();
    },
    
    validateBounds: function(options) {
        if (!options.maximize) {
            var winDims = top.document.viewport.getDimensions(), kWidth, kHeight;
            this.options.width  = (options.width) ? (Number(options.width)>(winDims.width-60)) ? (winDims.width-60)  : Number(options.width)+12 : 790; //14= Padding+Borders [5px Padding]
            if (options.height) {
                this.options.height = (Number(options.height)>(winDims.height-60)) ? (winDims.height-60) : Number(options.height);
            }
        }
    },
    
    create: function() {
        this.element = new Element('div', { 
            className:'kWin '+this.options.theme,
            id: this.options.id,
            style: "top:-10000px;left:-10000px;z-index:"+(this.options.zIndex+1)
        });
        this.validateBounds(this.options);
        
        this.wrapperHead     = new Element('div',{className:'kwinTL'}).insert(new Element('div',{className:'kwinTR'}));
        this.wrapperCnt     = new Element('div',{className:'kwinCnt'});
        this.wrapperFoot     = new Element('div',{className:'kwinBL'}).insert(new Element('div',{className:'kwinBR'}));
        
        var titleTxt = this.options.title || ' ';
        this.header  = new Element('div',{className:'titlebar'}).update(unescape(titleTxt));
        
        if (this.options.close && !this.options.closeBtn) { this.header.insert(new Element("a",{className:'close',href:"#"}).observe('click', this.close.bind(this))); }
        this.content = new Element('div',{className:'content'});
        
        if (this.options.src) {
            var iframeElmnt = new Element('iframe', {
                style: '',
                src: this.options.src,
                frameborder: 0,
                frameBorder: 0,
                marginwidth:0,
                marginheight:0,
                scrolling:'auto',
                width:'100%',
                height:this.options.height+'px'
            });
            iframeElmnt.identify();
            this.content.insert(iframeElmnt);
        } 

        if (this.options.img) {
            var imgElmnt = new Element('img', {
                className:'pointer',
                src: this.options.img,
                border: 0,
                alt:"",
                width:this.options.imgw || null,
                height:this.options.imgh || null,
                title:(unescape(this.options.imgtitle) || '')
            }).observe('click', this.close.bind(this));
            this.content.insert(imgElmnt);
            if (this.options.imgw) { this.options.width  = this.options.imgw; }
            if (this.options.imgh) { this.options.height = this.options.imgh; }
        }

        if (this.options.html) { this.content.insert(this.options.html); }
        else { if (this.options.content) { this.content.appendText(this.options.content || ' '); } }
        
        if (this.options.ajax) { var setAjax = new Ajax.Updater(this.content, this.options.ajax, {evalScripts:true, method:'get'}); }
        if (this.options.style) { this.content.setStyle(this.options.style); }
        this.element.insert(this.wrapperHead).insert(this.wrapperCnt.insert(this.header).insert(this.content)).insert(this.wrapperFoot).identify();
    },
  
    hide: function() {
        if (!this.visible) { return this; }
        this.element.hide(); //this.effect('hide'); --Could be an effect later on
        var pexec = new PeriodicalExecuter(function(executer) {
            if (this.element.visible()) { return; }
            this.visible = false;
            this.element.remove();
            executer.stop();
        }.bind(this), 0.1);
        return this;
    },

    // Adds window elements to the DOM
    addElements : function(elmnt) { this.windowManager.container.insert({bottom:elmnt}); },
    createDiv : function (className, options) { return new Element('div', Object.extend({ 'class': className }, options)); },
    observe:function(eventName, handler, args) { this.handlers[eventName] = handler; },
    fire:    function(eventName, memo) {
        memo = memo || { };
        memo.window = this;
        return this.element.fire('window:' + eventName, memo);
    }
});

kui.popup = Class.create({
    options : {},
    
    initialize: function(options) {
        var defOptions = {
            caller:            window,
            width:             790,
            height:            590
        };
        this.options = Object.extend(defOptions, options || {});
        var popup = this.options;
        var popUrl = (popup.srcObj) ? popup.srcObj.readAttribute('href') || '' : '';
        
        if (!popUrl.empty())
        {
            winDims = { width: screen.availWidth, height: screen.availHeight };
            kWidth    = (popup.width)  ? (Number(popup.width)>(winDims.width-60))   ? (winDims.width-60)  : Number(popup.width)  : 790;
            kHeight    = (popup.height) ? (Number(popup.height)>(winDims.height-60)) ? (winDims.height-60) : Number(popup.height) : 590;
            popup.options.width = kWidth;
            popup.options.height = kHeight;
            var popOptions = (popup.options) ? Object.toQueryString(popup.options).gsub('&',',') : '';
            var posX = 0, posY = 0;
            if (kWidth && kHeight) {
                if (kWidth<winDims.width)     { posX = Math.floor((winDims.width-Number(kWidth))/2,0); }
                if (kHeight<winDims.height) { posY = Math.floor((winDims.height-Number(kHeight))/2,0); }
                if (!popOptions.empty())     { popOptions += ',left='+posX+',top='+posY; }
            }
            var popWin = window.open(popUrl, "portalWin", popOptions);
            if (!popWin) { alert('Popup Blocker encountered, Please try again!'); } else { popWin.focus(); }
        }
    }
});

document.observe("dom:loaded", function() { 
    kui.win = (top!=window) ? top.kui.win : new kui.windowManager();
    
    if (top!=window) {
        /*
        Event.observe(document.body, 'mousewheel', function(event){ 
            if (!Event.element(event).up('.scroll')) { Event.stop(event); } });
        Event.observe(window, 'DOMMouseScroll', function(event){ 
            if (!Event.element(event).up('.scroll')) { Event.stop(event); } });
        */
    }
    
    if (top!=window && kui.keys) {
        kui.keys.register(27, function() { 
            if (confirm("Are you sure you wish to close this window?")){kui.cancel();}
        }, false, false, false);
    }
});
