/**
 * Whirlpool Threadwatch Improved
 *
 * LICENSE
 *
 * Copyright (c) 2009 Happy Noodle Boy (http://forums.whirlpool.net.au/user/65488)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * @copyright Copyright (c) 2009 Phil Brown (http://morecowbell.net.au/)
 * @license   http://www.opensource.org/licenses/mit-license.php The MIT License
 * @version   1.3
 */

(function($){
    $.fn.extend({
        boxen: function(url, options){
            switch (typeof url) {
                case 'object' :
                    options = url;
                    break;
                case 'string' :
                    options = $.extend({}, {
                        url: url,
                        urlAttribute: null
                    }, options);
                    break;
            }
            return this.click(function(e){
                $.Boxen.open(this, options);
                return false;
            });
        }
    });
    
    $.Boxen = {
        defaults: {
            urlParams: {},
            showTitleBar: true,
            showCloseButton: true,
            title: null,
            titleAttribute: 'title',
            closeButtonText: null,
            width: 600,
            height: 500,
            url: null,
            urlAttribute: 'href',
            overlayOpacity: 0.8,
            modal: false,
            postOpen: function(contentAreaElement) {},
            postClose: function() {}
        },
        bigIFrame: null,
        overlay: null,
        container: null,
        options: null,
        titleBar: null,
        closeButton: null,
        contentWindow: null,
        contentArea: null,
        ie6: false,
        setOptions: function(options){
            this.options = $.extend({}, this.defaults, options || {});
            return this;
        },
        getFullUrl: function(){
            var url = this.options.url;
            url += url.indexOf('?') == -1 ? '?' : '&';
            return url += $.param(this.options.urlParams);
        },
        init: function(){
            _this = this;
            this.isIE6 = $.browser.msie && parseInt($.browser.version) < 7;
            if ($.browser.opera) {
                 $.support.opacity = true;
            }
            
            $('#boxen_overlay, #boxen_container').remove();

            this.overlay = $('<div>').attr('id', 'boxen_overlay').css({
                opacity: this.options.overlayOpacity
            });
            
            if (!this.options.modal) {
                this.overlay.click(function(e){
                    $.Boxen.close();
                    return false;
                });
            }
            
            this.container = $('<div>')
                .attr('id', 'boxen_container')
                .width(this.options.width)
                .height(this.options.height)
                .css({
                    marginLeft: Math.round(this.options.width / -2) + 'px',
                    marginTop: Math.round(this.options.height / -2) + 'px'
                });
            
            if (this.isIE6) {
                this.bigIFrame = $('<iframe>').attr('id', 'boxen_big_iframe')
                    .css({
                        zIndex: 9999,
                        position: 'absolute',
                        top: 0,
                        left: 0,
                        opacity: 0
                    }).appendTo('body');
                    
                this._sizeOverlay();
                this._centreContent();
                $(window).bind('scroll.Boxen', function(e){
                    _this._centreContent();
                }).bind('resize.Boxen', function(e){
                    _this._sizeOverlay();
                    _this._centreContent();
                });
            } else {
                this.overlay.css({
                    position: 'fixed',
                    width: '100%',
                    height: '100%'
                });
                this.container.css('position', 'fixed');
            }
            
            this.overlay.appendTo('body');
            this.container.appendTo('body');
            
            this.contentWindow = $('<div>').attr('id', 'boxen_content').appendTo(this.container);
            
            if (this.options.showTitleBar) {
                this.titleBar = $('<div>').attr('id', 'boxen_titlebar').append(
                    $('<span>').attr('id', 'boxen_title').html(this.options.title)
                ).appendTo(this.contentWindow);
            } else {
                this.titleBar = null;
            }
            
            if (this.options.showCloseButton) {
                this.closeButton = $('<a>').attr({
                    href: '#',
                    id: 'boxen_close_button'
                }).click(function(e){
                    $.Boxen.close();
                    return false;
                }).appendTo(this.contentWindow);
                
                if (this.options.closeButtonText) {
                    this.closeButton.append(
                        $('<span>').html(this.options.closeButtonText)
                    );
                }
            } else {
                this.closeButton = null;
            }
            
            this.contentArea = $('<div>').attr('id', 'boxen_content_area')
                                         .appendTo(this.contentWindow);
            return this;
        },
        show: function(callback){
            this.overlay.fadeIn('fast');
            this.container.fadeIn('fast', function(){
                var _this = $.Boxen;
                if (null !== _this.options.url) {
                    var iFrame = $('<iframe>').attr({
                        id: 'boxen_iframe_content_' + new Date().getTime(),
                        width: _this.getContentAreaWidth(),
                        height: _this.getContentAreaHeight(),
                        frameBorder: 0,
                        src: _this.getFullUrl()
                    }).appendTo(_this.contentArea);
                } else {
                    _this.contentArea.width(_this.getContentAreaWidth()).height(_this.getContentAreaHeight());
                }
                _this.options.postOpen(_this.getContentAreaElement());
            });
            return this;
        },
        close: function(){
            try {
                if (this.isIE6) {
                    $(window).unbind('scroll.Boxen').unbind('resize.Boxen');
                    throw 'IE6';
                }
                this.container.fadeOut('fast', function(){
                    $(this).remove();
                });
                this.overlay.fadeOut('fast', function(){
                    $(this).remove();
                });
            } 
            catch (e) {
                $('#boxen_big_iframe, #boxen_overlay, #boxen_container').remove();
            }
            this.options.postClose();
            return this;
        },
        open: function(domElement, options){
            this.setOptions(options);
            if (domElement) {
                this.options.title = this.options.titleAttribute && $(domElement).attr(this.options.titleAttribute) || this.options.title;
                this.options.url = this.options.urlAttribute && $(domElement).attr(this.options.urlAttribute) || this.options.url;
            }
            this.init().show();
            return this;
        },
        _centreContent: function() {
            if (this.options.height < $(window).height()) {
                var topMargin = Math.round(this.options.height / -2) + $(document).scrollTop();
                this.container.css({
                    marginTop: topMargin + 'px'
                });
            }
        },
        _sizeOverlay: function() {
            this.bigIFrame.css({
                width: ($(document).width() - 21) + 'px',
                height: ($(document).height() - 4) + 'px'
            });
            this.overlay.css({
                width: ($(document).width() - 21) + 'px',
                height: ($(document).height() - 4) + 'px'
            });
        },
        getContentAreaElement: function() {
            return this.contentArea.get(0);
        },
        getContentAreaHeight: function() {
            return this.titleBar ? this.options.height - this.titleBar.outerHeight() : this.options.height;
        },
        getContentAreaWidth: function() {
            return this.options.width;
        }
    };
})(jQuery);
