/*Dependencies Jquery/UI/position*/

(function ($) {
    $.fn.BalloonBox = function (o) {
        return this.each(function () {
            return new $.BalloonBox(this, o);
        });
    };

    var defaults = {
        
        eventType: 'click', //click, blur, change, dblclick, error, focus, load, mousedown, mouseout, mouseup etc..
         
        minWidth: 440, //integer
        maxWidth: "auto", //auto or integer     
        
        minHeight: 130, //integer                 //not implemented yet
        maxHeight: "auto", //auto or integer    //not implemented yet 
        
        //showHeader:true,
        
        data: '', //url or data /ajax/Partners-references-countries
        ajax: '',
        type: 'div', //ajax, div
        
        parentBox: 'form', // (body, form, .Page > .Container > .Content)
        
        refreshData: false,
        boxClass: 'BalloonBox',
        ajaxErrorText: "The requested content cannot be loaded.<br />Please try again later.",
        loadingText: "Loading..."          
        
    },
        boxCount = 0, 

        DEBUG = false,
        
        BOX_HEADER_SUFFIX = "Header",
        BOX_CONTENT_SUFFIX = "Content",
        BOX_CONTAINER_SUFFIX = "Container",
        BOX_CLOSE_SUFFIX = "Close",
        BOX_LOADING_SUFFIX = "Loading";
        BOX_ERROR_SUFFIX = "Error";

    $.BalloonBox = function (btn, o) {

        if (btn == undefined) return;

        var self = this;
        
        self.o = $.extend({}, defaults, o || {});
        self.$btn = $(btn);
        self.boxCount = boxCount++;        
        self.ajaxLoader = null;
        
        self.id = '.' + self.o.boxClass + '' + self.boxCount;     
                    

        if (self.o.eventType) {
            $(btn).bind(self.o.eventType, function (e) {
                run();
                /* e.stopPropagation();*/
                return false;
            });
        }
                
         $(window).resize(function() {
             if (self.$box != undefined && self.$box !=null && self.$box.length > 0 && self.$box.is(':visible')) {
                          
                       showBox();
             }
        
         });  
         
       /*  $(document).click(function(e) {
         
          hideBox();  
         });*/
         
        /*$(document).click(function(event) {
        
        if($(event.target).is(self.$btn.selector)||$(event.target).parents(self.$box.selector).length>0)  
        {
        
        }
        else
        {
            hideBox();  
            return false;         
        }   
            
        });*/
        
        /*$(self.$box).click(function(e) {
               e.stopPropagation();
        });                        */

        var run = function () {

            if ($(self.id).length > 0) {
                  
                  if ($(self.id).is(':visible'))
                  {
                        hideBox();
                  }
                  else
                  {
                  if(self.o.refreshData || (self.o.type=='ajax' && self.ajaxLoader!=null && (self.ajaxLoader.readyState!= 4 || self.ajaxLoader.status!= 200 ) ) )
                  {  
                        loadingData();
                  }
                  else
                  {
                        showBox();
                  }
                  }
                  
                 
                
            } else {
                initContainer();
                loadingData();              
            }
        };

        var loadingData = function () {

            switch (self.o.type) {
            case 'ajax':
                {
                    ajaxProcess();
                    break;
                }
            case 'div':
            default:
                {
                    self.$boxContent.html(self.o.data);
                    showBox();
                    break;
                }
            }

        };

        var ajaxProcess = function () {
            self.o.ajax.win = self.o.ajax.success;
            self.ajaxLoader = $.ajax($.extend({}, self.o.ajax, {
                url: self.o.data,
                data: self.o.ajax.data || {},
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    if (XMLHttpRequest.status > 0) {
                        showError();
                    }
                },
                beforeSend: function () {
                    showLoading();                                        
                },
                success: function (data, textStatus, XMLHttpRequest) {
                    var o = typeof XMLHttpRequest == 'object' ? XMLHttpRequest : self.ajaxLoader;
                    if (o.status == 200) {
                        if (typeof self.o.ajax.win == 'function') {
                            ret = self.o.ajax.win(href, data, textStatus, XMLHttpRequest);

                            if (ret === false) {
                                $('.'+ self.o.boxClass + BOX_LOADING_SUFFIX).remove();
                                return;
                            } else if (typeof ret == 'string' || typeof ret == 'object') {
                                data = ret;
                            }
                        }

                        self.$boxContent.html(data);
                        showBox();
                        
                    }
                }
            }));

           
        };
        
        var showLoading = function(){
            self.$boxLoading=self.$boxContent.html($('<div class="'+self.o.boxClass + BOX_LOADING_SUFFIX + '" >'+self.o.loadingText+'</div>'));
            
            showBox();
            self.$boxContent.css({"text-align":"center"});
        };                
        
        var showError = function(){
            self.$boxError = self.$boxContent.html('<div class="'+self.o.boxClass + BOX_ERROR_SUFFIX + '">'+self.o.ajaxErrorText+'</div>' );
            showBox();
        };
        
        var hideBox = function() {
            
            
            if (self.ajaxLoader) {
		    self.ajaxLoader.abort();		    
		}
            self.$box.hide();
            
            
        };

        var showBox = function() {            
            
            
            hideOtherBoxes();
            
            self.$box.show();            
            self.$box.css({width:'auto'});
            self.$box.css({height:'auto'});
            self.$box.css({top:'0px'});
            self.$box.css({left:'0px'});
            self.$boxContent.css({"text-align":"left"});
            
            var tmpBoxWidth = 0;
                         
            if (self.o.maxWidth=="auto")
            {                
                tmpBoxWidth = self.$box.outerWidth() < self.o.minWidth ? self.o.minWidth : self.$box.outerWidth();
                tmpBoxWidth = tmpBoxWidth < $(self.$btn).outerWidth() ? $(self.$btn).outerWidth() : tmpBoxWidth;
                tmpBoxWidth = tmpBoxWidth > $(self.o.parentBox).outerWidth()? $(self.o.parentBox).outerWidth(): tmpBoxWidth;                                    
            }
            else
            {                
                tmpBoxWidth = self.$box.outerWidth() < self.o.minWidth ? self.o.minWidth : $box.outerWidth();                
                tmpBoxWidth = tmpBoxWidth > self.o.maxWidth ? self.o.maxWidth : tmpBoxWidth;
                tmpBoxWidth = tmpBoxWidth < self.$btn.outerWidth() ? $(self.$btn).outerWidth() : tmpBoxWidth;
                tmpBoxWidth = tmpBoxWidth > $(self.o.parentBox).outerWidth()? $(self.o.parentBox).outerWidth(): tmpBoxWidth;                                                       
            }
            var tmpBoxHeight = 0;
            if (self.o.maxHeight=="auto")
            {                
                tmpBoxHeight = self.$box.outerHeight() < self.o.minHeight ? self.o.minHeight : self.$box.outerHeight();                                                                    
            }
            else
            {                
                tmpBoxHeight = self.$box.outerHeight() < self.o.minHeight ? self.o.minHeight : $box.outerHeight();                
                tmpBoxHeight = tmpBoxHeight > self.o.maxHeight ? self.o.maxHeight : tmpBoxHeight;                                                                       
            }
            //IE9 fix
            tmpBoxWidth = tmpBoxWidth + 1; 
            self.$box.css({width:tmpBoxWidth+'px'});
            self.$box.css({height:tmpBoxHeight+'px'});
            
            /*self.$box.css({width:self.$boxContainer.outerWidth()+'px'});
            self.$box.css({height:self.$boxContainer.outerHeight()+'px'});*/
            
            var tmpOffsetTop = self.$boxHeader.innerHeight();
            
            self.$boxHeader.css({"width":$(self.$btn).innerWidth()+"px"});                         
              
            self.$box.position({
                my: "center top",
                at: "center bottom",
                offset: "0px "+tmpOffsetTop+"px",
                collision: "none none",
                of: self.$btn
            });
            
            
             
              self.$boxHeader.position({
                my: "center top",
                at: "center bottom",
                offset: "0 0",
                collision: "none none",
                of: self.$btn
            }); 
            
            
            
                       
            
            
            var tmpParentLeft=/*Math.round*/($(self.o.parentBox).offset().left);
            var tmpParentWidth=/*Math.round*/($(self.o.parentBox).innerWidth());
            var tmpParentOffsetLeft = /*Math.round*/(parseFloat($(self.o.parentBox).css('padding-left'),10));
            var tmpParentOffsetRight = /*Math.round*/(parseFloat($(self.o.parentBox).css('padding-right'),10));
            var tmpBoxLeft =  /*Math.round*/(self.$box.offset().left);
            var tmpBoxWidth = /*Math.round*/(self.$box.innerWidth());
                                                             
            var tmpBoxLeftCorrect = (((tmpBoxLeft + tmpBoxWidth) > (tmpParentLeft + tmpParentWidth - tmpParentOffsetRight)) ? (tmpParentLeft + tmpParentWidth - (tmpBoxLeft + tmpBoxWidth) - tmpParentOffsetRight) : 0);
                tmpBoxLeftCorrect = tmpBoxLeft+tmpBoxLeftCorrect < tmpParentLeft+tmpParentOffsetLeft ? tmpParentLeft-tmpBoxLeft+tmpParentOffsetLeft : tmpBoxLeftCorrect;
            
            self.$box.css({left:(parseFloat(self.$box.css("left"),10)+(tmpBoxLeftCorrect))+'px'})
            self.$boxHeader.css({left:(parseFloat(self.$boxHeader.css("left"),10)-(tmpBoxLeftCorrect))+'px'})
            
            var tmpCorrect = self.$btn.offset().left-self.$boxHeader.offset().left;
                                     
               self.$box.css({left:(parseFloat(self.$box.css("left"),10)+(tmpCorrect))+'px'});
              
           
            
          
         
                        
        };
        
        var hideOtherBoxes = function()
        {
            $('.'+self.o.boxClass+':not(.'+self.o.boxClass+self.boxCount+')').hide();
        };
        
        var hideAllBoxes  = function()
        {
            $('.'+self.o.boxClass).hide();
        };

        var initContainer = function () {
            
            self.$boxHeader = $('<div class="'+self.o.boxClass + BOX_HEADER_SUFFIX+'" ></div>');
            self.$boxClose = $('<div class="'+self.o.boxClass + BOX_CLOSE_SUFFIX+'"></div>').click(function(){ 
                  hideBox();
            });
            self.$boxContainer = $('<div class="ClearFix '+self.o.boxClass + BOX_CONTAINER_SUFFIX+'"></div>'); 
            self.$boxContent = $('<div class="ClearFix '+self.o.boxClass + BOX_CONTENT_SUFFIX+'"></div>');
            
            self.$boxContainer.append(self.$boxContent);
            
            self.$box = $('<div class="ClearFix '+self.o.boxClass+' '+self.o.boxClass+''+self.boxCount+'"></div>').hide()
                .append(self.$boxHeader).append(self.$boxClose).append(self.$boxContainer);
            
            $(self.o.parentBox).append(self.$box);


        };

    };

    $.BalloonBox.fn = $.BalloonBox.prototype = {};

    $.BalloonBox.fn.extend = $.BalloonBox.extend = $.extend;

    $.BalloonBox.fn.extend({
      //public method
    })
        

})(jQuery);
