/**
 *  jQuery Windows Engine Plugin
 *@requires jQuery v1.2.6
 *  http://www.socialembedded.com/labs
 *
 *  Copyright (c)  Hernan Amiune (hernan.amiune.com)
 *  Dual licensed under the MIT and GPL licenses:
 *  http://www.opensource.org/licenses/mit-license.php
 *  http://www.gnu.org/licenses/gpl.html
 * 
 *  Version: 0.6.1
 *
 * Modified by Arrviasto <arrviasto@gmail.com>
 * Modified by XOMBO <xombo.com>
 *
 */

var winNextSpawnX = 100;
var winNextSpawnY = 100;

(function($){ 

/**
 * @option string windowTitle, the tile to display on the window
 * @option HTML content, the content to display on the window
 * @option string ajaxURL, URL address to load the content, this has priority over content
 * @option int width, the initial width of the window
 * @option int height, the initial height of the window
 * @option int posx, the initial x position of the window
 * @option int posy, the initial y position of the window
 * @option function onDragBegin: onDragBegin callback function,
 * @option function onDragEnd: onDragEnd callback function,
 * @option function onResizeBegin: onResizeBegin callback function,
 * @option function onResizeEnd: onResizeEnd callback function,
 * @option function onAjaxContentLoaded: onAjaxContentLoaded callback function,
 * @option boolean statusBar, enable or disable the window status bar
 * @option boolean minimizeButton, enable or disable the window minimize button
 * @option HTML minimizeIcon, an html text to display as the minize icon
 * @option boolean maximizeButton, enable or disable the window maximize button
 * @option HTML maximizeIcon, an html text to display as the maximize icon
 * @option boolean closeButton, enable or disable the window close button
 * @option HTML closeIcon, an html text to display as the close icon
 * @option boolean draggable, enable or disable the window dragging
 * @option boolean resizable, enable or disable the window resize button
 * @option HTML resizeIcon, an html text to display as the resize icon
 * @option string windowType, a string "normal", "video", or "iframe"
 *
 * @type jQuery
 *
 * @name jqWindowsEngine
 * @cat Plugins/Windows
 * @author Hernan Amiune (amiune@gmail.com)
 */ 

$.fn.newWindow = function(options){

    var lastMouseX = 0;
    var lastMouseY = 0;

    var defaults = {
    	view: "null",
        windowTitle : "",
        windowIcon : "",
		content: "",
		ajaxURL: "",
        width: 550,
        height: 450,
        minwidth: 350,
        minheight: 300,
        posx: -1,
        posy: -1,
        minTop: $("#taskbar").height (),
		onDragBegin: null,
		onDragEnd: null,
		onResizeBegin: null,
		onResizeEnd: null,
		onAjaxContentLoaded: null,
		onOpen: null,
		onClose: null,
        statusBar: true,
		minimizeButton: true,
		minimizeIcon: "",
		maximizeButton: true,
		maximizeIcon: "",
		dashboardButton: true,
		dashboardIcon: "",
		dashboardStatus: false,
		dashboardClass: "",
		closeButton: true,
		closeIcon: "",
		draggable: true,
		resizable: true,
		resizeIcon: "",
		windowType: "standard",
		eventOpen: 'click',
		standalone: false,
		state: "normal",
		titleClick: false,
    };
  
    var options = $.extend(defaults, options);
    
    if (options.resizable == false) options.maximizeButton = false;
    
	if ( options.windowType == "iframe" ) {
		options.content = '<iframe src="' + options.content + '" width="100%" height="100%" frameborder="0"></iframe>';
	}
    
    $windowContainer = $('<div class="window-container"></div>');
    $windowTitleBar = $('<div class="window-titleBar"></div>');
    $windowDashboardButton = $('<div class="window-dashboardButton"></div>');
    $windowMinimizeButton = $('<div class="window-minimizeButton"></div>');
	$windowMaximizeButton = $('<div class="window-maximizeButton"></div>');
	$windowCloseButton = $('<div class="window-closeButton"></div>');
	$windowContent = $('<div class="window-content"></div>');
	$windowStatusBar = $('<div class="window-statusBar"></div>');
	$windowResizeIcon = $('<div class="window-resizeIcon"></div>');
	
	if(options.windowType=="video" || options.windowType=="iframe")
	  $windowContent.css("overflow","hidden");
	if (options.windowIcon!="") {
		$windowTitleBar.css ("background-repeat", "no-repeat");
		$windowTitleBar.css ("background-image", "url(" + options.windowIcon + ")");
		$windowTitleBar.css ("background-position", "7px 1px");
	}
	if (options.dashboardStatus) {
		$windowDashboardButton.css ("background-image", "url(/themes/compress.php?file=default/icons/dashboard-docked.png)");
	}
	
	var setFocus = function($obj){
	    $obj.maxZIndex ({ inc: 1});
	    if (options.posx <= 0 || options.posy < options.minTop) {
			options.posx = winNextSpawnX;
			options.posy = winNextSpawnY;
			move ($obj, winNextSpawnX, winNextSpawnY);
		}
	    setSpawn ($obj);
	}
	
	var setSpawn = function ($obj) {
		winNextSpawnX = parseInt($obj.css ("left")) + 50;
	   	winNextSpawnY = parseInt($obj.css ("top")) + 50;
	    if (winNextSpawnX + options.width > parseInt($(window).width ())) {
	    	winNextSpawnX = 100;
	    }
	    if (winNextSpawnY + options.height > parseInt($(window).height ())) {
	    	winNextSpawnY = 100;
	    }
	    if (winNextSpawnX < 0) {
	    	winNextSpawnX = 100;
	    }
	    if (winNextSpawnY < options.minTop) {
	    	winNextSpawnY = 100;
	    }
	}
	
	var resize = function($obj, width, height){
	    
		width = parseInt(width);
		height = parseInt(height);
		
		$obj.attr("lastWidth",width)
		    .attr("lastHeight",height);
		
		width = width+"px";
		height = height+"px";
		
		$obj.css("width", width)
	        .css("height", height);
		
		if(options.windowType=="video"){
		  $obj.children(".window-content").children("embed").css("width", width)
	               .css("height", height);
		  $obj.children(".window-content").children("object").css("width", width)
	               .css("height", height);
		  $obj.children(".window-content").children().children("embed").css("width", width)
	               .css("height", height);
		  $obj.children(".window-content").children().children("object").css("width", width)
	               .css("height", height);
		}
		
        resizeIFRAME ($obj, width, height);
	}
	
	var resizeIFRAME = function ($obj, width, height) {
	    if(options.windowType=="iframe")		
			$obj.children(".window-content").children("iframe").css("width", width).css("height", height);
		return;
	}
	
	var move = function($obj, x, y){
	    
		x = parseInt(x);
		y = parseInt(y);
		$obj.attr("lastX",x)
		    .attr("lastY",y);
		
		if (x > $(window).width () - 10) {
			return;
		}
		if (y > $(window).height () - 10) {
			return;
		}
		if (x + $obj.width () < 10) {
			return;
		}
		if (y + $obj.width () < 10) {
			return;
		}
		
        x = x+"px";
		y = y+"px";
			
		$obj.css("left", x)
	        .css("top", y);
	    setSpawn ($obj);
	}

	var dragging = function(e, $obj){
	    if(options.draggable){
			e = e ? e : window.event;
			var newx = parseInt($obj.css("left")) + (e.clientX - lastMouseX);
			var newy = parseInt($obj.css("top")) + (e.clientY - lastMouseY);
			lastMouseX = e.clientX;
			lastMouseY = e.clientY;
			if (newy < options.minTop) {
				move($obj,newx, options.minTop);
			} else {
			    move($obj,newx,newy);
			}
			if ($(window).scrollTop () > 0) {
				$(window).scrollTop (0);
			}
			if ($(window).scrollLeft () > 0) {
				$(window).scrollLeft (0);
			}
		}
	};
	
	var resizing = function(e, $obj){
	  
	  e = e ? e : window.event;
	  var w = parseInt($obj.css("width"));
	  var h = parseInt($obj.css("height"));
	  w = w<100 ? 100 : w;
	  h = h<50 ? 50 : h;
	  var neww = w + (e.clientX - lastMouseX);
      var newh = h + (e.clientY - lastMouseY);
	  lastMouseX = e.clientX;
	  lastMouseY = e.clientY;
	  if (neww > $(window).width () - parseInt($obj.css("left")) - 10) {
	  	neww = $(window).width () - parseInt($obj.css("left")) - 10;
	  }
	  if (newh > $(window).height() - parseInt($obj.css("top")) - 50) {
	  	newh = $(window).height() - parseInt($obj.css("top")) - 50;
	  }
	  if (neww < options.minwidth) {
	  	neww = options.minwidth;
	  }
	  if (newh < options.minheight) {
	  	newh = options.minheight;
	  }
	  resize($obj, neww, newh);
	};
	
	$windowTitleBar.bind('mousedown', function(e){
		is_chrome = /chrome/.test( navigator.userAgent.toLowerCase() );
	    $obj = $(e.currentTarget).parent();
		setFocus($obj);
		if (options.windowType == "iframe" && (is_chrome || options.titleClick)) {
				$(".window-content iframe").each (function () { $(this).hide (); });
		}
	    if(options.state == "normal"){
	        e = e ? e : window.event;
		    lastMouseX = e.clientX;
		    lastMouseY = e.clientY;
		    
		    $(document).bind('mousemove', function(e){
			    dragging(e, $obj);
		    });
		    
			
		    $(document).bind('mouseup', function(e){
		    	if (is_chrome || options.titleClick) {
		    		$(".window-content iframe").each (function () { $(this).show (); });
		    	}
				if(options.onDragEnd != null)options.onDragEnd();
				$(document).unbind('mousemove');
				$(document).unbind('mouseup');
				if ($(window).scrollTop () > 0) {
					$(window).scrollTop (0);
				}
				if ($(window).scrollLeft () > 0) {
					$(window).scrollLeft (0);
				}
				options.titleClick = false;
		    });
			
			if(options.onDragBegin != null)options.onDragBegin();
	    }
    });
	$windowDashboardButton.bind ('click', function (e) {
		options.dashboardStatus = !options.dashboardStatus;
		if (options.dashboardStatus) {
			$(e.target).css ("background-image", "url(/themes/compress.php?file=default/icons/dashboard-docked.png)");
		} else {
			$(e.target).css ("background-image", "url(/themes/compress.php?file=default/icons/dashboard-undocked.png)");		
		}
	});
	$windowDashboardButton.bind ('mousedown', function (e) {
		return false;
	});
	$windowResizeIcon.bind('mousedown', function(e){
		is_chrome = /chrome/.test( navigator.userAgent.toLowerCase() );
		is_mozilla = /mozilla/.test( navigator.userAgent.toLowerCase() );
		$obj = $(e.target).parent().parent();
		setFocus($obj);
		if (is_chrome || is_mozilla) {
			$(".window-container").find ("iframe").each (function () {
				$(this).hide ();
			});
		}
		if(options.state == "normal"){
			e = e ? e : window.event;
			lastMouseX = e.clientX;
			lastMouseY = e.clientY;

			$(document).bind('mousemove', function(e){
				resizing(e, $obj);
			});

			$(document).bind('mouseup', function(e){
				if(options.onResizeEnd != null)options.onResizeEnd();
				$(document).unbind('mousemove');
				$(document).unbind('mouseup');
				if (is_chrome || is_mozilla) {
					$(".window-container").find ("iframe").each (function () {
						$(this).show ();
					});
				}
			});
			
			if(options.onResizeBegin != null)options.onResizeBegin();
		}
		
    });
	$windowMinimizeButton.bind('click', function(e){
	    $obj = $(e.target).parent().parent();
		setFocus($obj);
	    $obj.fadeOut ();
    });
    $windowMinimizeButton.bind('mousedown', function(e){
    	return false;
    });
	$windowMaximizeButton.bind('click', function(e){
	  $obj = $(e.target).parent().parent();
	  setFocus($obj);
	  if(options.state == "normal"){
	  	$obj.find (".window-maximizeButton").css ("background-image", "url(/themes/compress.php?file=default/icons/window-restore.png)");
		  if(options.windowType=="standard"){
		    $obj.animate({
		      top: 5 + options.minTop,
			  left: 5,
			  width: $(window).width()-10,
			  height: $(window).height()-55-options.minTop
		    },"slow");
		  }
		  else{
			tmpx = $obj.attr("lastX");
		    tmpy = $obj.attr("lastY");
			tmpwidth = $obj.attr("lastWidth");
		    tmpheight = $obj.attr("lastHeight");
			move($obj, 5, 5 + options.minTop);
		    resize($obj,$(window).width()-10,$(window).height()-55-options.minTop);
			$obj.attr("lastX",tmpx);
		    $obj.attr("lastY",tmpy);
			$obj.attr("lastWidth",tmpwidth);
		    $obj.attr("lastHeight",tmpheight);
		  }
		  options.state = "maximized";
		  $obj.attr ("state", "maximized");
	  }
	  else if(options.state == "maximized"){
	  	$obj.find(".window-maximizeButton").css ("background-image", "url(/themes/compress.php?file=default/icons/window-maximize.png)");
	    if(options.windowType=="standard"){ 
		  $obj.animate({
		    top: $obj.attr("lastY"),
			left: $obj.attr("lastX"),
			width: $obj.attr("lastWidth"),
			height: $obj.attr("lastHeight")
		  },"slow");
		}
		else{
		  resize($obj,$obj.attr("lastWidth"),$obj.attr("lastHeight"));
		  move($obj,$obj.attr("lastX"),$obj.attr("lastY"));
		}
		options.state = "normal";
		$obj.attr ("state", "normal");
	  }
    });
    $windowMaximizeButton.bind('mousedown', function (e) {
    	return false;
    });
	$windowCloseButton.bind('click', function(e){
	  $(e.target).parent().parent().fadeOut();
	  $(e.target).parent().parent().children(".window-content").html("");
	  winNextSpawnX = 100;
	  winNextSpawnY = 100;
	  if (options.onClose != null) options.onClose (options.view);
    });
    $windowCloseButton.bind('mousedown', function (e) {
    	return false;
    });
	$windowContent.click(function(e){
      setFocus($(e.target).parent());
    });
	$windowStatusBar.click(function(e){
      setFocus($(e.target).parent());
    });

	move($windowContainer,options.posx,options.posy);
	resize($windowContainer,options.width,options.height);
	$title = $("<span>" + options.windowTitle + "</span>").bind ("mousedown", function (e) {
		options.titleClick = true;
		return true;
	});
	$windowTitleBar.append ($title);
	
	if(options.minimizeButton)
	    $windowTitleBar.append($windowMinimizeButton)
	if(options.maximizeButton)
	    $windowTitleBar.append($windowMaximizeButton)
	if(options.closeButton)  
	    $windowTitleBar.append($windowCloseButton);
	if(options.dashboardButton)
		$windowTitleBar.append($windowDashboardButton);
	
	if(options.resizable)
	    $windowStatusBar.append($windowResizeIcon);
	
	$windowContainer.append($windowTitleBar)
	$windowContainer.append($windowContent)
	
	if(options.statusBar)
	    $windowContainer.append($windowStatusBar);
	
	$windowContainer.css("display","none");
	
	return this.each(function(index) {
		var $this = $(this);      	
		
		$windowMinimizeButton.html(options.minimizeIcon);
		$windowMaximizeButton.html(options.maximizeIcon);
		$windowDashboardButton.html(options.dashboardIcon);
		$windowCloseButton.html(options.closeIcon);
		$windowResizeIcon.html(options.resizeIcon);
		
		$this.data("window",$windowContainer);
		$('body').append($windowContainer);

		if ( options.standalone ){
			$window = $this.data("window")
			if(options.ajaxURL != ""){ 

				 $.ajax({
				   type: "GET",
				   url: options.ajaxURL,
				   dataType: "html",
				   //data: "header=variable",
				   success: function(data){
					 $window.children(".window-content").html(data);
					 if(options.onAjaxContentLoaded != null) options.onAjaxContentLoaded(); 
				   }
				 });

			}
			else $window.children(".window-content").html(options.content);
			if(!options.draggable)
				$window.children(".window-titleBar").css("cursor","default");
			setFocus($window);
			$window.attr ("view", options.view);
			$window.fadeIn();
		}
		else
		{
		$this.bind(
			options.eventOpen,
			function(event){
			event.preventDefault();   
			$window = $this.data("window")
			if(options.ajaxURL != ""){ 

				 $.ajax({
				   type: "GET",
				   url: options.ajaxURL,
				   dataType: "html",
				   //data: "header=variable",
				   success: function(data){
				 	$window.children(".window-content").html(data);
					if(options.onAjaxContentLoaded != null) options.onAjaxContentLoaded(); 
				   }
				 });
		    
			} else {
				if ($window.children(".window-content").html() == "") {
					$window.children(".window-content").html(options.content);
					if(options.onOpen != null)options.onOpen (options.windowIcon, options.view);
				}
			}
			if(!options.draggable)
			    $window.children(".window-titleBar").css("cursor","default");
			setFocus($window);
			$window.attr ("view", options.view);
            $window.fadeIn();			
		});
		}
	});
  
}})(jQuery);

/* via: http://www.west-wind.com/weblog/posts/876332.aspx */
$.maxZIndex = $.fn.maxZIndex = function(opt) {
    /// <summary>
    /// Returns the max zOrder in the document (no parameter)
    /// Sets max zOrder by passing a non-zero number
    /// which gets added to the highest zOrder.
    /// </summary>    
    /// <param name="opt" type="object">
    /// inc: increment value, 
    /// group: selector for zIndex elements to find max for
    /// </param>
    /// <returns type="jQuery" />
    var def = { inc: 10, group: "*" };
    $.extend(def, opt);    
    var zmax = 0;
    $(def.group).each(function() {
        var cur = parseInt($(this).css('z-index'));
        zmax = cur > zmax ? cur : zmax;
    });
    if (!this.jquery)
        return zmax;

    return this.each(function() {
        zmax += def.inc;
        $(this).css("z-index", zmax);
    });
}
