/**
 * @project         Jx
 * @revision        $Id: jxdialog.js,v 1.20 2007/06/20 20:42:17 pspencer Exp $
 * @author          Paul Spencer (pspencer@dmsolutions.ca)
 * @copyright       &copy; 2006 DM Solutions Group Inc.
 */

Jx.addStyleSheet('dialog/dialog.css');


Jx.Dialog = Class.create();
Jx.Dialog.prototype = {
    onClose : null,
    onOpen : null,
    onChange : null,
    title : null,
    content : null,
    values : null,
    actions : null,
    handler : null,
    bContentLoaded : null,
    zIndex: [101],
    stack: [],
    blanket: null,
    modal: true,
    initialize: function(options) {
        this.initUniqueId();
        this.values = {};
        this.actions = {};
        this.handler = options.handler?options.handler:null;
        if (options.onChange) {this.onChange = options.onChange;}
        if (options.onClose) {this.onClose = options.onClose;}
        if (options.onOpen) {this.onOpen = options.onOpen;}
        if (options.onContentLoaded) {this.onContentLoaded = options.onContentLoaded;}
        
        this.modal = typeof options.modal == 'undefined' ? true : options.modal;
        
        var w = options.width || 250;
        var h = options.height || 250;
        var b = (typeof options.bottom != 'undefined') ? options.bottom : null;
        var r = (typeof options.right != 'undefined') ? options.right : null;
        var t = (typeof options.top != 'undefined') ? options.top : (b != null ? null : 0);
        var l = (typeof options.left != 'undefined') ? options.left : (r != null ? null : 0);
        //var t = (options.top && options.top > 0) ? options.top : 0;
        //var l = (options.left && options.left > 0) ? options.left : 0;
        
        this.blanket = document.createElement('div');
        this.blanket.className = 'jxDialogModal';
        this.blanket.style.display = 'none';
        
        if (!window.opera && this.modal) {
            var iframe = document.createElement('iframe');
            //iframe.src = 'javascript:false';
            iframe.className = 'jxDialogShim';
            iframe.scrolling = 'no';
            iframe.frameborder = 0;
            this.blanket.appendChild(iframe);
            if (options.parentObj) {
                $(options.parentObj).appendChild(this.blanket);
            } else {
                document.body.appendChild(this.blanket);            
            }        }
        /* create the dialog box first so we can measure it */
        var d2 = document.createElement('div');
        d2.style.position = 'absolute';
        d2.style.top = '6px';
        d2.style.left = '6px';
        d2.style.width = w + 'px';
        d2.style.height = h + 'px';
        d2.className = 'jxDialog';
        
        this.title = document.createElement('div');
        this.title.className = 'jxDialogTitle';
        /* this is required for IE and Opera */
        //this.title.style.height = '22px';
        Element.setBorderBoxSize(this.title, {height:options.titleHeight || 22});
        
        var span = document.createElement('span');
        span.innerHTML = options.title || '';
        this.title.appendChild(span);
        
        /* element must be in the page to be measured */
        this.title.style.visibility = 'hidden';
        document.getElementsByTagName('BODY')[0].appendChild(this.title);
        var titleHeight = Element.getBorderBoxSize(this.title);
        document.getElementsByTagName('BODY')[0].removeChild(this.title);
        this.title.style.visibility = 'visible';
        
        d2.appendChild(this.title);
        
        var atag = document.createElement('a');
        atag.href = 'javascript:void(0)';
        atag.className = 'jxDialogCloseButton';
        atag.onclick = this.close.bindAsEventListener(this);
        
        var close = document.createElement('img');
        if(options.closeImg) {
            close.src = options.closeImg;
        }
        else {
            close.src = Jx.baseURL + 'images/icon_close.png';
        }
        close.alt = 'Close Dialog';
        close.title = 'Close Dialog';
        atag.appendChild(close);
        this.title.appendChild(atag);
        
        if (options.helpID || options.helpHTML || options.helpURL || options.help) {
            var atag2 = document.createElement('a');
            atag2.href = 'javascript:void(0)';
            atag2.className = 'jxDialogHelpButton';
            atag2.onclick = this.toggleHelp.bindAsEventListener(this);
            //TODO: don't add help in title if it isn't needed
            var help = document.createElement('img');
            help.src = Jx.baseURL + 'images/icon_quickhelp.png';
            help.alt = 'Help';
            help.title = 'Help';
            atag2.appendChild(help);
            this.title.appendChild(atag2);
        }
        
        this.action = document.createElement('div');
        this.action.className = 'jxDialogAction';
        Element.setBorderBoxSize(this.action, {height:30});
        /* element must be in the page to be measured */
        this.action.style.visibility = 'hidden';
        document.getElementsByTagName('BODY')[0].appendChild(this.action);
        var actionHeight = Element.getBorderBoxSize(this.action);
        document.getElementsByTagName('BODY')[0].removeChild(this.action);
        this.action.style.visibility = 'visible';
        
        var contentHeight = h - titleHeight.height - actionHeight.height;
        this.content = document.createElement('div');
        this.content.className = 'jxDialogContent';
        Element.setBorderBoxSize(this.content, {height: contentHeight});
        
        if (options.helpID || options.helpHTML || options.helpURL || options.help) {
            this.help = document.createElement('div');
            this.help.className = 'jxDialogHelp';
            this.help.style.display = 'none';
            this.help.isVisible = false;
            var helpOpts = {};
            helpOpts.contentID = options.helpID;
            helpOpts.content = options.help;
            helpOpts.contentURL = options.helpURL;
            helpOpts.contentHTML = options.helpHTML;
            helpOpts.onContentLoaded = this.onHelpContentLoaded.bind(this);
            this.loadContent(this.help, helpOpts);
            d2.appendChild(this.help);
        }
        
        d2.appendChild(this.content);
        
        if (options.buttons) {
            this.setButtons(options.buttons);
        }
        
        d2.appendChild(this.action);
        var contentOpts = {};
        contentOpts.contentID = options.contentID;
        contentOpts.content = options.content;
        contentOpts.contentURL = options.contentURL;
        contentOpts.contentHTML = options.contentHTML;
        contentOpts.onContentLoaded = this.onDialogContentLoaded.bind(this);
        
        this.loadContent(this.content, contentOpts);
        
        /* element must be in the page to be measured */
        d2.style.visibility = 'hidden';
        document.body.appendChild(d2);
        var boxSize = Element.getBorderBoxSize(d2);
        document.body.removeChild(d2);
        d2.style.visibility = 'visible';
        
        /* now create overall container with the correct size */
        var d = document.createElement('div');
        d.style.position = 'absolute';
        if (t != null) {
            d.style.top = (t - 6) + 'px';
        } else {
            d.style.bottom = (b - 6) + 'px';
        }
        if (l != null) {
            d.style.left = (l - 6) + 'px';
        } else {
            d.style.right = (r - 6) + 'px';
        }
        d.style.display = "none";
        d.id = options.id || options.title;
        Element.setContentBoxSize(d, {width:(boxSize.width+12), height:(boxSize.height+12)});
        
        /* drop shadows */
        /* top left */
        var img = document.createElement('img');
        img.src = Jx.baseURL + 'images/dialog_glow_tl.png';
        img.className = 'png24'; /* apply png hack for IE */
        img.width = 12;
        img.height = 12;
        img.style.position = 'absolute';
        img.style.top = '0px';
        img.style.left = '0px';
        d.appendChild(img);
        /* top right */
        img = document.createElement('img');
        img.src = Jx.baseURL + 'images/dialog_glow_tr.png';
        img.className = 'png24'; /* apply png hack for IE */
        img.width = 12;
        img.height = 12;
        img.style.position = 'absolute';
        img.style.top = '0px';
        img.style.right = '0px';
        d.appendChild(img);
        /* bottom right */
        img = document.createElement('img');
        img.src = Jx.baseURL + 'images/dialog_glow_br.png';
        img.className = 'png24'; /* apply png hack for IE */
        img.width = 12;
        img.height = 12;
        img.style.position = 'absolute';
        img.style.bottom = '0px';
        img.style.right = '0px';
        d.appendChild(img);
        /* bottom left */
        img = document.createElement('img');
        img.src = Jx.baseURL + 'images/dialog_glow_bl.png';
        img.className = 'png24'; /* apply png hack for IE */
        img.width = 12;
        img.height = 12;
        img.style.position = 'absolute';
        img.style.bottom = '0px';
        img.style.left = '0px';
        d.appendChild(img);
        /* top */
        img = document.createElement('img');
        img.src = Jx.baseURL + 'images/dialog_glow_t.png';
        img.className = 'png24'; /* apply png hack for IE */
        img.width = boxSize.width-12;
        img.height = 12;
        img.style.position = 'absolute';
        img.style.top = '0px';
        img.style.left = '12px';
        d.appendChild(img);
        this.topImg = img;
        /* bottom */
        img = document.createElement('img');
        img.src = Jx.baseURL + 'images/dialog_glow_b.png';
        img.className = 'png24'; /* apply png hack for IE */
        img.width = boxSize.width-12;
        img.height = 12;
        img.style.position = 'absolute';
        img.style.bottom = '0px';
        img.style.left = '12px';
        d.appendChild(img);
        this.bottomImg = img;
        /* left */
        img = document.createElement('img');
        img.src = Jx.baseURL + 'images/dialog_glow_l.png';
        img.className = 'png24'; /* apply png hack for IE */
        img.width = 12;
        img.height = boxSize.height-12;
        img.style.position = 'absolute';
        img.style.top = '12px';
        img.style.left = '0px';
        d.appendChild(img);
        this.leftImg = img;
        /* right */
        img = document.createElement('img');
        img.src = Jx.baseURL + 'images/dialog_glow_r.png';
        img.className = 'png24'; /* apply png hack for IE */
        img.width = 12;
        img.height = boxSize.height-12;
        img.style.position = 'absolute';
        img.style.top = '12px';
        img.style.right = '0px';
        d.appendChild(img);
        this.rightImg = img;
        d.appendChild(d2);
        
        if (options.parentObj) {
            $(options.parentObj).appendChild(d);
        } else {
            document.body.appendChild(d);            
        }
        Event.observe(d, 'mousedown', this.mouseDown.bind(this));
        Event.observe(this.title, 'mousedown', this.mouseDown.bind(this));
        this.domObj = d;
        
        if (options.resizeable) {
            this.resizeImage = document.createElement('img');
            this.resizeImage.className = 'jxDialogResize';
            this.resizeImage.style.position = 'absolute'; //required for Draggable
            this.resizeImage.style.top = (boxSize.height-15) + 'px';
            this.resizeImage.style.left = (boxSize.width-15) + 'px';
            this.resizeImage.src = Jx.baseURL + 'images/dialog_resize.png';
            this.domObj.appendChild(this.resizeImage);
            new Draggable(this.resizeImage, {starteffect: false, endeffect: false,change:this.ondrag.bind(this), zindex: 0});            
        }
        
        this.bOpen = false;
    },
    mouseDown: function() {
        for (var i=0; i<this.stack.length; i++) {
            if (this.stack[i] == this) {
                this.stack.splice(i, 1);
                this.stack.push(this);
            }
        }
        for (var i=0; i<this.stack.length; i++) {
            this.stack[i].domObj.style.zIndex = (101 + i);
        }
    },
    ondrag: function(obj) {
        this.mouseDown();
        
        var delta = obj.currentDelta();
        //delta is top/left of resize image.  Bottom/right of the dialog needs to be
        //adjusted for size of image (20x20) and for the shadow (6x6) resulting in
        //an additional 14 pixels from the top/left of the resize image.
        var deltaX = delta[0] + 15;
        var deltaY = delta[1] + 15;
        this.resize({width: deltaX, height: deltaY});
        
        /* - to be removed - moved code to resize function
        var obj = this.title.parentNode;
        Element.setBorderBoxSize(obj, {width:deltaX, height:deltaY});
        var titleSize = Element.getBorderBoxSize(this.title);
        var actionSize = Element.getBorderBoxSize(this.action);
        Element.setBorderBoxSize(this.content, {height:deltaY-titleSize.height-actionSize.height-2, width:deltaX-2});
        Element.setBorderBoxSize(this.domObj, {height:deltaY + 12, width:deltaX + 12});
        
        if (this.help) {
            Element.setBorderBoxSize(this.help, {height:deltaY - titleSize.height});
        }
        
        Element.setBorderBoxSize(this.topImg, {width:deltaX-12});
        Element.setBorderBoxSize(this.bottomImg, {width:deltaX-12});
        Element.setBorderBoxSize(this.leftImg, {height:deltaY-12});
        Element.setBorderBoxSize(this.rightImg, {height:deltaY-12});
        */
    },
    resize: function(newSize) {
        var obj = this.title.parentNode;
        var titleSize = Element.getBorderBoxSize(this.title);
        var actionSize = Element.getBorderBoxSize(this.action);
        var oldDisplay = this.domObj.style.display;
        var oldVisibility = this.domObj.style.visibility;
        if (oldDisplay == 'none') {
            this.domObj.style.visibility = 'hidden';
            this.domObj.style.display = 'block';
        }
        if (newSize.width) {
            Element.setBorderBoxSize(obj, {width:newSize.width});
            Element.setBorderBoxSize(this.topImg, {width:newSize.width-12});
            Element.setBorderBoxSize(this.bottomImg, {width:newSize.width-12});
            Element.setBorderBoxSize(this.content, {width:newSize.width-2});
            Element.setBorderBoxSize(this.domObj, {width:newSize.width + 12});
        }
        if (newSize.height) {
            Element.setBorderBoxSize(obj, {height:newSize.height});
            Element.setBorderBoxSize(this.leftImg, {height:newSize.height-12});
            Element.setBorderBoxSize(this.rightImg, {height:newSize.height-12});
            var contentH = newSize.height-titleSize.height-actionSize.height-2;
            Element.setBorderBoxSize(this.content, {height:contentH});
            Element.setBorderBoxSize(this.domObj, {height:newSize.height + 12});
            if (this.help) {
                Element.setBorderBoxSize(this.help, {height:newSize.height - titleSize.height});
            }
        }
        if (oldDisplay == 'none') {
            this.domObj.style.visibility = oldVisibility;
            this.domObj.style.display = 'none';
        }
    },
    setTitle: function( title ) {
        this.title.childNodes[0].innerHTML = title;
    },
    setButtons: function(buttons) {
        this.action.innerHTML = '';
        for (var i=0; i<buttons.length;i++) {
            var button = document.createElement('input');
            button.id = buttons[i];
            button.type = 'button';
            button.className = 'normalButton';
            button.name = buttons[i];
            button.value = buttons[i];
            button.onclick = this.buttonHandler.bind(this, button);
            this.action.appendChild(button);
            this.uniqueIdRefs[button.id] = button;
        }
    },
    processInputs : function(o) {
        for (var i=0;i<o.childNodes.length; i++) {
            var node = o.childNodes[i];
            if (node.tagName == 'INPUT' || node.tagName == 'SELECT' || node.tagName == 'TEXTAREA') {
                if (node.type == 'button') {
                    this.actions[node.id] = node;
                    node.onclick = this.buttonHandler.bind(this, node);
                } else {
                    this.values[node.id] = node;
                    if (this.onChange) {
                        node.onchange = this.onChangeHandler.bind(this, node);
                    }
                }
            } else {
                if (node.childNodes) {
                    this.processInputs(node);
                }
            }
        }
    },
    buttonHandler : function(input, event) {
        if (this.handler) {
            this.handler(input.value, this);
        }
    },
    onChangeHandler: function(input, event) {
        if (this.onChange) {
            this.onChange(input, this);
        }
    },
    getValue : function( name ) {
        var result = '';
        var input = this.values[name];
        if (input) {
            switch (input.tagName) {
                case 'INPUT': 
                    result = input.value;
                    break;
                case 'SELECT':
                    result = input.options[input.selectedIndex].value;
            }
        }
        return result;
    },
    setValue : function( name, value ) {
        if (typeof this.values[name] != 'undefined') {
            if (this.values[name].type == 'text') {
                this.values[name].value = value;
            }
        }
    },
    show : function( ) {
        this.stack.push(this);
        if (this.modal) {
            this.blanket.style.zIndex = this.zIndex[0]++;
            this.blanket.style.display = 'block';
        }
        this.domObj.style.zIndex = this.zIndex[0]++;
        Effect.Appear(this.domObj, {duration: 0.1});
        //this.domObj.style.display = 'block';
        new Draggable(this.domObj, {handle:this.title, starteffect: false, endeffect: false});
        
    },
    hide : function() {
        for (var i=0; i<this.stack.length; i++) {
            if (this.stack[i] == this) {
                this.stack.splice(i,1);
            }
        }
        this.zIndex[0]--;
        Effect.Fade(this.domObj, {duration: 0.3});
        if (this.modal) {
            this.blanket.style.display = 'none';
            this.zIndex[0]--;
        }
        
    },
    open: function() {
        if (!this.bOpen) {
            this.bOpen = true;
        }
        if (this.bContentLoaded) {
            this.show();
            if (this.onOpen) this.onOpen();
        }
    },
    close: function() {
        this.bOpen = false;
        this.hide();
        if (this.onClose) this.onClose();
    },
    onDialogContentLoaded : function() {
        this.processInputs(this.content);
        if (this.onContentLoaded) {
            this.onContentLoaded();
        }
        if (this.bOpen) {
            //may need to do this?
            //window.setTimeout(this.open.bind(this),1);
            this.open();
            this.bOpen = false;
        }
    },
    onHelpContentLoaded : function() {
        var img = document.createElement('img');
        img.className = 'jxDialogHelpCloseButton png24';
        img.src = Jx.baseURL + 'images/help_close.png';
        img.onclick = this.toggleHelp.bind(this);
        img.alt = 'Close Help';
        img.title = 'Close Help';
        this.help.appendChild(img);
    },
    toggleHelp: function() { 
        if (this.help.isVisible) {
            Effect.Fade(this.help, {duration: 0.3});
        } else {
            var actionSize = Element.getBorderBoxSize(this.action);
            var contentSize = Element.getBorderBoxSize(this.content);
            Element.setBorderBoxSize(this.help, {height:contentSize.height+actionSize.height});
            Effect.Appear(this.help, {duration: 0.3});
        }
        this.help.isVisible = !this.help.isVisible;
    }
};
Object.extend(Jx.Dialog.prototype, Jx.UniqueId.prototype);
Object.extend(Jx.Dialog.prototype, Jx.ContentLoader.prototype);