jit.widget = jit.widget || {};

jit.widget.Modal = function(cfg) {
    var url = null;

    this.cfgParam = cfg;

    if (cfg.url) {
        url = cfg.url;
        delete(cfg.url);
    }
    
    var Modal = jit.widget.Modal,
        elementOrId = Modal.modalElementId;

    if (cfg.html) {
        elementOrId = Modal.getModuleElement(cfg.html);
        delete(cfg.html);
    }
    
    Modal.superclass.constructor.call(this, elementOrId, cfg);

    Modal.close();

    if (typeof(cfg.beforeRender) == 'function') {
        cfg.beforeRender(this);
    }

    Modal.open(this);

    if (typeof(cfg.afterRender) == 'function') {
        cfg.afterRender(this);
    }

    if (cfg.autoSize) {
        this.adjustHeight();
    }

    this.hijackElements();    

    if (url) {
        this.loadUrl(url);
    }
}

YAHOO.extend(jit.widget.Modal, YAHOO.widget.Panel, {
    loadUrl: function(url) {
        var cfg = this.cfgParam;

        if (typeof cfg.autoSize == 'undefined') {
            cfg.autoSize = true;
        }

        if (!cfg.hasOwnProperty('beforeRender')) {
            cfg.beforeRender = function(modal) {
                modal.setHeader('Loading');
                modal.setBody('Please wait...');
            }
        }
        
        $.ajax({
            type: 'GET',
            url: url,
            responseType: 'html',
            data: { layout: false },
        
            success: function(html) {
                delete(cfg.beforeRender);
                cfg.html = html;
                new jit.widget.Modal(cfg);
            },
        
            error: function(xhr, textStatus, errorThrown) {
                jit.openBugReportDialog();
            }
        });
    },

    adjustHeight: function() {
        var body = $(this.body),
            heightBefore = body.height();

        body.css('height', 'auto');
        
        var heightAfter       = body.height(),
            heightDiscrepancy = heightAfter - heightBefore,
            newHeight         = window.parseInt(this.cfg.getProperty('height')) + heightDiscrepancy - window.parseInt(body.css('padding-bottom'));
        
        if (heightDiscrepancy > 0) {
            this.cfg.setProperty('height', newHeight + 'px');
        }
    },

    hijackElements: function() {
        this.hijackForms();
        this.hijackButtons();   
    },

    hijackForms: function() {
        var self = this;

        $(this.element).find('form').ajaxForm({
            beforeSubmit: function(params) {
                params.push({name: 'layout', value: 'false'});
            },
            
            success: function(html) {
                try {
                    var follow = true;
                    var postSuccess = self.cfgParam.postSuccess;
                    
                    if (postSuccess) {
                        follow = postSuccess.call(self, html);
                    }
                    
                    if (follow) {
                        var cfg = self.cfgParam;
                        cfg.html = html;

                        new jit.widget.Modal(cfg);
                    }
                } catch(e) {
                    jit.exception(e);
                }
            },
        
            error: function() {
                jit.openBugReportDialog();
            }
        });
    },
    
    hijackButtons: function() {
        if (this.footer) {
            var ft = $(this.footer);

            // if the footer has a "Close" link, move it to the header

            ft.find('.close').remove().appendTo(this.header);

            // if the footer is now empty, add a "Close" button at the bottom too

            var buttonGroup = ft.find('.button-group');

            if (buttonGroup.length == 0) {
                buttonGroup = $('<div class="button-group"/>').appendTo(ft);
            }

            if (buttonGroup.children().length == 0) {
                $('<button class="jit-button close">Close</button>').appendTo(buttonGroup);
            }
        }

        $(this.element).find('.close')
            .click(function(event) {
                event.preventDefault();

                try {
                    jit.widget.Modal.close();
                } catch(e) {
                    jit.exception(e);
                }
            });
    }
});

YAHOO.lang.augmentObject(jit.widget.Modal, {
    modalElementId: 'jit-modal',

    getModuleElement: function(html) {
        var tmp = $('<div/>').html(html);
        var module = tmp.find('.yui-module').attr('id', 'jit-modal');

        return module.get(0);
    },

    open: function(modal) {
        this.modal = modal;
        this.modal.render(this.getContainer());
        $(modal.element).addClass('jit-dialog');
    },

    close: function() {
        if (this.modal) {
            this.modal.destroy();
            this.modal = null;
        }
    },

    getContainer: function() {
        var cont = $('#jit-modal-container').get(0);
        
        if (cont) return cont;
        
        return $('<div/>').attr('id', 'jit-modal-container')
                          .appendTo(document.body)
                          .get(0);
    },

    centerModalConfigX: function(cfg) {
        cfg.x = Math.max(0, $('body').width() - window.parseInt(cfg.width)) / 2;
    },
    
    centerModalConfigY: function(cfg) {
        cfg.y = Math.max(0, $('body').height() - window.parseInt(cfg.height)) / 2;
    }
});

/**
 * A small panel at the top of the viewport.
 */
jit.widget.Shutter = function(cfg) {
    var defaults = {
        modal: true,
        draggable: false,
        underlay: 'shadow',
        width: '400px',
        height: '300px',
        close: false
    };

    for (var i in defaults) {
        if (!cfg.hasOwnProperty(i)) {
            cfg[i] = defaults[i];
        }
    }

    if (typeof cfg.x == 'undefined') {
        jit.widget.Modal.centerModalConfigX(cfg);
    }

    if (typeof cfg.y == 'undefined') {
        cfg.y = 0;
    }

    jit.widget.Shutter.superclass.constructor.call(this, cfg);
}

YAHOO.extend(jit.widget.Shutter, jit.widget.Modal);

/**
 * A large panel centred in the viewport.
 */
jit.widget.Dialog = function(cfg) {
    var defaults = {
        modal: true,
        draggable: false,
        underlay: 'shadow',
        width: '670px',
        height: '440px',
        close: false
    };

    for (var i in defaults) {
        if (!cfg.hasOwnProperty(i)) {
            cfg[i] = defaults[i];
        }
    }

    if (typeof cfg.x == 'undefined') {
        jit.widget.Modal.centerModalConfigX(cfg);
    }

    if (typeof cfg.y == 'undefined') {
        jit.widget.Modal.centerModalConfigY(cfg);
    }

    jit.widget.Dialog.superclass.constructor.call(this, cfg);
}

YAHOO.extend(jit.widget.Dialog, jit.widget.Modal);

/**
 * A shutter that prompts the user to confirm a single action.
 */
jit.widget.ConfirmationDialog = function(cfg) {
    var onOK = null;

    if (cfg.onOK) {
        onOK = cfg.onOK;
        delete(cfg.onOK);
    }

    var beforeRender = cfg.beforeRender;

    cfg.beforeRender = function(shutter) {
        var header      = $('<div/>'),
            body        = $('<div/>'),
            footer      = $('<div/>');

        if (cfg.hasOwnProperty('title')) {
            header.text(cfg.title);
        }

        if (cfg.hasOwnProperty('icon')) {
            $('<img class="icon"/>').attr('src', cfg.icon).appendTo(body);
        }

        if (cfg.hasOwnProperty('text')) {
            var text = $('<div class="text"/>').appendTo(body);

            if (typeof cfg.text == 'string') {
                text.text(cfg.text).appendTo(body);
            } else {
                text.append(cfg.text);
            }

            if (cfg.hasOwnProperty('icon')) {
                text.addClass('with-icon');
            }
        }

        var buttonGroup = $('<div class="button-group"/>').appendTo(footer),
            button      = $('<button/>').appendTo(buttonGroup);

        button.text(cfg.buttonText || 'OK')
              .click(function() {
                  onOK.call(shutter);
              });

        $('<a href="#" class="close">Cancel</a>').appendTo(footer);

        shutter.setHeader(header.get(0));
        shutter.setBody(body.get(0));
        shutter.setFooter(footer.get(0));

        if (typeof beforeRender == 'function') {
            beforeRender(shutter);
        }
    }

    jit.widget.ConfirmationDialog.superclass.constructor.call(this, cfg);
}

YAHOO.extend(jit.widget.ConfirmationDialog, jit.widget.Shutter);

