// panel

var activePanel;

(function(undefined){
	var Panel 			= function(){ 
		
		if(typeof(Template) === 'undefined'){
			throw('panel.js requires template.js!');
		}
		
		var that = this;
		
		var panelActive = false;
		
		var setPanelWidth = 800;
		
		var left = (320 > ($(window).width() - setPanelWidth)) ? 320 : ($(window).width() - setPanelWidth);
		
		var panelContentOffset = 26;
		
		var viewStack = [];
		
		var inDock = false;     //this is true when panel has had a slide out
		
		var settings = {
			slideDelay: 1000
		};
		
        that.template 		= new Template("panelTemplate");
        
        var fn = that.template;
        var bodyClickCloseFunction;
        
        // publicly accessible functions
        fn.show =  function(){
            
            //check if there is a active panel we should close
            if(activePanel){
                activePanel.close();
            }
            activePanel = this;
            
            // add event handler to close button			
            that.template.element('btnClose').click(function(){
                fn.close();
            });
            
            // add event handler to handle
            that.template.element('panelHandle').addClass('panelHandleOpen'); // change symbol on button
            that.template.element('panelHandle').click(function(){
                fn.slideOut();
            });
            
            
            // move to right of screen
            that.template.self().css('left', $(window).width() + 'px');
            
            //attach listener to change the height when the window changes height
            $(window).resize(fn.setHeight);
            
            // slide in
            that.template.self().appendTo($('body')).animate({'left':left+'px'}, settings.slideDelay, "swing", function(){
                bodyClickCloseFunction = function(){
                    if(!inDock){
                        fn.close();
                    }
                };
                
                // add event to body that closes this panel
                $('#body').click(bodyClickCloseFunction);
                
                // stop propagation of events on panel
                $(that.template.self()).click(function(event){
                    event.stopPropagation();
                });
            });
            
            panelActive = true;

            fn.setHeight();            
            
        };
        
        fn.setHeight = function(){
            
            //get the screen height
            var panelHeight = parseInt(that.template.element('contentHolder').css('height'));
            
            //get the panel margins
            var topMargin = parseInt(that.template.self().css('marginTop'));
            var bottomMargin = parseInt(that.template.self().css('marginBottom'));
            
            //get the contentHolder paddings
            var topPadding = parseInt(that.template.element('contentHolder').css('paddingTop'));
            var bottomPadding = parseInt(that.template.element('contentHolder').css('paddingBottom'));
            
            //calculate the height
            var panelContentHeight = panelHeight - bottomPadding - topPadding - panelContentOffset;
            
            that.template.element('contents').height(panelContentHeight);
            
            
            //calculate the windows width
            var screenWidth = $(window).width();
            
            //get the contentHolder paddings
            var leftPadding = parseInt(that.template.element('contentHolder').css('paddingLeft'));
            var rightPadding = parseInt(that.template.element('contentHolder').css('paddingRight'));
            
            panelWitdh = screenWidth - left - leftPadding - rightPadding;
            
            that.template.element('contents').width(panelWitdh);
        };
        
        fn.close = fn.hide = function(){
            //release all views
            if(viewStack.length){
                for(var i=viewStack.length - 1; i>=0;i--){
                    fn.releaseView(viewStack[i]);
                }
            }else{
                fn.showClosing();
            }
            
            $('#body').unbind('click', bodyClickCloseFunction);
            $(window).unbind('resize', fn.setHeight);
        };
		
		fn.setTitle = function(title){
			 that.template.element('title').text(title);
		};
        
        fn.showClosing = function(){
            activePanel = null;
            panelActive = false;
            
            if(that.template){
                that.template.self().animate({'left': $(window).width() + 'px'}, settings.slideDelay, "swing", function(){
                    that.template.self().remove();
                    that.template = null;
                    
                    windowStack.release(this);
                });
            }
        };
        
        fn.slideIn = function(){
            inDock = false;
            that.template.self().animate({'left':left+'px'}, settings.slideDelay, "swing", function(){
                that.template.element('panelHandle').addClass('panelHandleOpen'); // change symbol on button
                that.template.element('panelHandle').removeClass('panelHandleClose'); // change symbol on button
                that.template.element('panelHandle').unbind('click');
                that.template.element('panelHandle').click(function(){
                    fn.slideOut();
                });
            });
        };
        
        fn.slideOut = function(){
            inDock = true;
            that.template.self().animate({'left': $(window).width() + 'px'}, settings.slideDelay, "swing", function(){
                that.template.element('panelHandle').removeClass('panelHandleOpen'); // change symbol on button
                that.template.element('panelHandle').addClass('panelHandleClose'); // change symbol on button
                that.template.element('panelHandle').unbind('click');
                that.template.element('panelHandle').click(function(){
                    fn.slideIn();
                });
            });
        };
        
        
        fn.showView = function(template){
            
            var templateInList = false;
        
            for(i in viewStack){
                if(viewStack[i] !== template){
                    viewStack[i].self().remove();
                }else{
                    templateInList = true;
                }
            }
            
            viewStack = [template];
            
            if(!templateInList){
                template.self().appendTo(that.template.element('contents'));
            }
            
            //execute a showView function if present
            if(typeof(template.showView) === 'function'){
                template.showView();
            }
            
            template.self().show();
            
        };
        
        fn.pushView = function(template){
            for(i in viewStack){
                viewStack[i].self().hide();
            }
        
            viewStack.push(template);
            template.self().appendTo(that.template.element('contents'));
            
            //execute a showView function if present
            if(typeof(template.showView) === 'function'){
                template.showView();
            }
            
            template.self().show();
            
        };
        
        fn.releaseView = function(template){
            if(viewStack[viewStack.length - 1] !== template){
                throw("Given template is not the top view. Cannot release!");
            }
            
            viewStack.pop();
            template.self().remove();
            
            //if this was the last view, close
            if(!viewStack.length){
                fn.showClosing();
            }else{
                //execute a showView function if present
                if(typeof(viewStack[viewStack.length - 1].showView) === 'function'){
                    viewStack[viewStack.length - 1].showView();
                }
            
                viewStack[viewStack.length - 1].self().show();
            }
            
            //check if the template has a viewReleased function
            if(typeof template.viewReleased == 'function'){
                template.viewReleased();
            }
        };
        
        fn.forceTemporaryShowView = function(template){
            //see if this view is shown
            if(viewStack[viewStack.length - 1] !== template){
                //no
                template.previousState = 'hidden';
                
                //hide current view
                viewStack[viewStack.length - 1].self().hide();
            }else{
                template.previousState = 'shown';
            }
            
            template.self().show();
        };
        
        fn.restorePreviousStateView = function(template){
            if(template.previousState == 'hidden'){
                template.self().hide();
                
                viewStack[viewStack.length - 1].self().show();
            }
        };
        
        fn.isPanelActive = function(){
            return(panelActive);
        };
        
        
        fn.inDock = function(){
            return(inDock);
        };
        
        return(fn);
		
	};
	
	// share the Window object with the rest of the world
    window.Panel     = Panel;
	
	
}());

