/*
Script: AlertBox.js
    http://www.coders.me/web-js-html/javascript/sexy-alert-box

Version:
    1.1

Author:
    Eduardo D. Sada
    http://www.coders.me

License:
    MIT license.

Based on <PBBAcpBox> (Pokemon_JOJO, <http://www.mibhouse.org/pokemon_jojo>)

Features:
    Mootools 1.2 100% Compatible
    Chain Implemented (Cola de mensajes)
    More styles (info, error, alert, prompt, confirm)
*/

/*
Class: AlertBox

Clone class of original javascript function : 'alert', 'confirm' and 'prompt'

Arguments:
    options - see Options below

Options:
    name - name of the box for use different style
    zIndex - integer, zindex of the box
    onReturn - return value when box is closed. defaults to false
    onReturnFunction - a function to fire when return box value
    BoxStyles - stylesheets of the box
    OverlayStyles - stylesheets of overlay
    showDuration - duration of the box transition when showing (defaults to 200 ms)
    showEffect - transitions, to be used when showing
    closeDuration - Duration of the box transition when closing (defaults to 100 ms)
    closeEffect - transitions, to be used when closing
    onShowStart - a function to fire when box start to showing
    onCloseStart - a function to fire when box start to closing
    onShowComplete - a function to fire when box done showing
    onCloseComplete - a function to fire when box done closing
*/
var AlertBox = new Class({
    Implements: [Chain],
    getOptions: function(){
        return {
            name                : 'AlertBox',
            zIndex              : 65555,
            onReturn            : false,
            onReturnFunction    : $empty,
            BoxStyles           : {
                                    'width' : 500
                                  },
            OverlayStyles       : {
                                    'background-color'  : '#123',
                                    'opacity'           : 0.7
                                  },
            showDuration        : 200,
            showEffect          : Fx.Transitions.linear,
            closeDuration       : 100,
            closeEffect         : Fx.Transitions.linear,
            moveDuration        : 500,
            moveEffect          : Fx.Transitions.Back.easeOut,
            onShowStart         : $empty,
            onShowComplete      : $empty,
            onCloseStart        : $empty,
            onCloseComplete     : function(properties) {
                                        this.options.onReturnFunction(this.options.onReturn);
                                  }.bind(this)
        };
    },
    initialize: function(options){
        this.i=0;
        this.setOptions(this.getOptions(), options);
        this.Overlay = new Element('div', {
            'id'    : 'BoxOverlay',
            'styles': {
                        'display'           : 'none',
                        'z-index'           : this.options.zIndex,
                        'position'          : 'absolute',
                        'top'               : '0',
                        'left'              : '0',
                        'background-color'  : this.options.OverlayStyles['background-color'],
                        'opacity'           : 0,
                        'height'            : window.getScrollHeight() + 'px',
                        'width'             : window.getScrollWidth() + 'px'
                      }
        });
        this.Content = new Element('div', {
            'id': this.options.name + '-BoxContenedor'
        });
        this.Contenedor = new Element('div', {
            'id': this.options.name + '-BoxContent'
        }).adopt(this.Content);
        this.InBox = new Element('div', {
            'id': this.options.name + '-InBox'
        }).adopt(this.Contenedor);;
        this.Box = new Element('div', {
            'id': this.options.name + '-Box',
            'styles': {
                        'display'   : 'none',
                        'z-index'   : this.options.zIndex + 2,
                        'position'  : 'absolute',
                        'top'       : '0px',
                        'left'      : '0',
                        'width'     :  this.options.BoxStyles['width'] + 'px'
                      }
        }).adopt(this.InBox);
        this.Overlay.injectInside(document.body);
        this.Box.injectInside(document.body);
        this.preloadImages();
        window.addEvent('resize', function() {
            if(this.options.display == 1) {
                this.Overlay.setStyles({
                    'height'    : window.getScrollHeight() + 'px',
                    'width'     : window.getScrollWidth() + 'px'
                });
                this.replaceBox();
            }
        }.bind(this));
        window.addEvent('scroll', this.replaceBox.bind(this));
    },
    preloadImages: function() {
        var img = new Array(2);
        img[0] = new Image();img[1] = new Image();img[2] = new Image();
//         img[0].src = this.Box.getStyle('background-image').replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1");
//         img[1].src = this.InBox.getStyle('background-image').replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1");
//         img[2].src = this.Contenedor.getStyle('background-image').replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1");
    },
    /*
    Method: display
    Show or close box
    Argument:
    option - integer, 1 to Show box and 0 to close box (with a transition).
    */
    display: function(option){
        if(this.Transition)
            this.Transition.cancel();
        // Show Box
        if(this.options.display == 0 && option != 0 || option == 1) {
            if(Browser.Engine.trident4)
                $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'hidden' });
                this.Overlay.setStyle('display', 'block');
                this.options.display = 1;
                this.fireEvent('onShowStart', [this.Overlay]);
                this.Transition = new Fx.Tween(this.Overlay, {
                    property    : 'opacity',
                    duration    : this.options.showDuration,
                    transition  : this.options.showEffect,
                    onComplete  : function() {
                                    sizes       = window.getSize();
                                    scrollito   = window.getScroll();
                                    this.Box.setStyles({
                                        'display'   : 'block',
                                        'left'      : (scrollito.x + (sizes.x - this.options.BoxStyles['width']) / 2).toInt()
                                    });
                                    this.replaceBox();
                                    this.fireEvent('onShowComplete', [this.Overlay]);
                                  }.bind(this)
                }).start(this.options.OverlayStyles['opacity']);
        }
        // Close Box
        else {
            if(Browser.Engine.trident4)
                $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'visible' });
                this.queue.delay(500,this);
                this.Box.setStyles({
                    'display'   : 'none',
                    'top'       : 0
                });
                this.Content.empty();
                this.options.display = 0;
                this.fireEvent('onCloseStart', [this.Overlay]);
                if(this.i==1) {
                    this.Transition = new Fx.Tween(this.Overlay, {
                        property    : 'opacity',
                        duration    : this.options.closeDuration,
                        transition  : this.options.closeEffect,
                        onComplete  : function() {
                                        this.fireEvent('onCloseComplete', [this.Overlay]);
                                      }.bind(this)
                    }).start(0);
                }
        }
    },
    /*
    Method: replaceBox
    Move Box in screen center when brower is resize or scroll
    */
    replaceBox: function() {
        if(this.options.display == 1) {
            sizes       = window.getSize();
            scrollito   = window.getScroll();
            if(this.MoveBox)
                this.MoveBox.cancel();
                this.MoveBox = new Fx.Morph(this.Box, {
                    duration    : this.options.moveDuration,
                    transition  : this.options.moveEffect
                }).start({
                    'left'  : (scrollito.x + (sizes.x - this.options.BoxStyles['width']) / 2).toInt(),
                    'top'   : (scrollito.y + (sizes.y - this.Box.offsetHeight) / 2).toInt()
                });
        }
    },
    queue: function() {
        this.i--;
        this.callChain();
    },
    /*
    Method: messageBox
    Core system for show all type of box
    Argument:
    type - string, 'alert' or 'confirm' or 'prompt'
    message - text to show in the box
    properties - see Options below
    input - text value of default 'input' when prompt
    Options:
    onComplete - a function to fire when return box value
    */
    messageBox: function(type, message, properties, input) {
        this.chain(function () {
            properties = $extend({
                'textBoxInputPrompt'    : null,
                'password'              : false,
                'onComplete'            : $empty
            }, properties || {});
            this.options.onReturnFunction = properties.onComplete;
            this.ContenedorBotones = new Element('div', {
                'id'    : this.options.name + '-Buttons'
            });
            if(type == 'alert' || type == 'info' || type == 'error') {
                this.AlertBtnOk = new Element('input', {
                    'id'    : 'BoxAlertBtnOk',
                    'type'  : 'image',
                    'src'   : 'libraries/javascript/alertbox/images/accept.jpg'
                });
                this.AlertBtnOk.addEvent('click', function() {
                    this.options.onReturn = true;
                    this.display(0);
                }.bind(this));
                if(type == 'alert')
                    this.clase = 'BoxAlert';
                else if(type == 'error')
                    this.clase = 'BoxError';
                else if(type == 'info')
                    this.clase = 'BoxInfo';
                this.Content.setProperty('class',this.clase).set('html',message);
                this.AlertBtnOk.injectInside(this.ContenedorBotones);
                this.ContenedorBotones.injectInside(this.Content);
                this.display(1);
            }
            else if(type == 'confirm') {
                this.ConfirmBtnOk = new Element('input', {
                    'id'    : 'BoxConfirmBtnOk',
                    'type'  : 'image',
                    'src'   : 'libraries/javascript/alertbox/images/accept.jpg'
                });
                this.ConfirmBtnCancel = new Element('input', {
                    'id'    : 'BoxConfirmBtnCancel',
                    'type'  : 'image',
                    'src'   : 'libraries/javascript/alertbox/images/cancel.jpg'
                });
                this.ConfirmBtnOk.addEvent('click', function() {
                    this.options.onReturn = true;
                    this.display(0);
                }.bind(this));
                this.ConfirmBtnCancel.addEvent('click', function() {
                    this.options.onReturn = false;
                    this.display(0);
                }.bind(this));
                this.Content.setProperty('class','BoxConfirm').set('html',message);
                this.ConfirmBtnOk.injectInside(this.ContenedorBotones);
                this.ConfirmBtnCancel.injectInside(this.ContenedorBotones);
                this.ContenedorBotones.injectInside(this.Content);
                this.display(1);
            }
            else if(type == 'prompt') {
                this.PromptBtnOk = new Element('input', {
                    'id'    : 'BoxPromptBtnOk',
                    'type'  : 'image',
                    'src'   : 'libraries/javascript/alertbox/images/accept.jpg'
                });
                this.PromptBtnCancel = new Element('input', {
                    'id'    : 'BoxPromptBtnCancel',
                    'type'  : 'image',
                    'src'   : 'libraries/javascript/alertbox/images/cancel.jpg'
                });
                type = properties.password ? 'password' : 'text';
                this.PromptInput = new Element('input', {
                    'id'    : 'BoxPromptInput',
                    'type'  : type,
                    'value' : input
                });
                this.PromptBtnOk.addEvent('click', function() {
                    this.options.onReturn = this.PromptInput.value;
                    this.display(0);
                }.bind(this));
                this.PromptBtnCancel.addEvent('click', function() {
                    this.options.onReturn = false;
                    this.display(0);
                }.bind(this));
                this.Content.setProperty('class','BoxPrompt').set('html',message + '<br />');
                this.PromptInput.injectInside(this.Content);
                new Element('br').injectInside(this.Content);
                this.PromptBtnOk.injectInside(this.ContenedorBotones);
                this.PromptBtnCancel.injectInside(this.ContenedorBotones);
                this.ContenedorBotones.injectInside(this.Content);
                this.display(1);
            } else {
                this.options.onReturn = false;
                this.display(0);
            }
        });
        this.i++;
        if(this.i==1) this.callChain();
    },
    /*
    Method: alert
    Shortcut for alert
    Argument:
    properties - see Options in messageBox
    */
    alert: function(message, properties){
        this.messageBox('alert', message, properties);
    },
    /*
    Method: info
    Shortcut for alert info
    Argument:
    properties - see Options in messageBox
    */
    info: function(message, properties){
        this.messageBox('info', message, properties);
    },
    /*
    Method: error
    Shortcut for alert error
    Argument:
    properties - see Options in messageBox
    */
    error: function(message, properties){
        this.messageBox('error', message, properties);
    },
    /*
    Method: confirm
    Shortcut for confirm
    Argument:
    properties - see Options in messageBox
    */
    confirm: function(message, properties){
        this.messageBox('confirm', message, properties);
    },
    /*
    Method: prompt
    Shortcut for prompt
    Argument:
    properties - see Options in messageBox
    */
    prompt: function(message, input, properties){
        this.messageBox('prompt', message, properties, input);
    }
});
AlertBox.implement(new Events, new Options);
window.addEvent("domready", function () {
    AlertBox = new AlertBox();
});

