
	var locales =
	{
		en:
		{
			closeWindow: 'Close window',
			minimizeWindow: 'Minimize window',
			maximizeWindow: 'Maximize window'
		},
		ru:
		{
			closeWindow: 'Закрыть окно',
			minimizeWindow: 'Свернуть окно',
			maximizeWindow: 'Распахнуть окно'
		}
	}

	var i18n = locales[document.documentElement.lang];

	// mode = {'standard', 'transparent'}
	var winOptions =
	{
		title: '',
		mode: 'standard',
		closeButton: true,
		minmaxButton: true,
		grid: 10
	}

	function win(options)
	{
		if(options == undefined) options = winOptions;
		for(var option in winOptions)
			if(options[option] == undefined) options[option] = winOptions[option];

		this.options = options;

		do{
			if(win.counter == undefined) win.counter = 0;
			else win.counter++;

			this.id = 'window_' + win.counter;
		}while($('body > div.window#' + this.id).length)
		

		$("body").append('<div id="' + this.id + '" class="window"><div class="titleBar"><span class="title"/><span class="buttons"/></div><div class="body"/></div>');

		var element = $('body > div.window#' + this.id).get(0);

		win.parentClass.constructor.call(this, element);

		$(this.element).find(".titleBar .buttons")
			.append('<a class="minimize" title="'+ i18n['minimizeWindow'] +'" />')
			.append('<a class="maximize" title="'+ i18n['maximizeWindow'] +'" />')
			.append('<a class="close" title="'+ i18n['closeWindow'] +'" />')

		this.captionContainer = $(this.element).find(".titleBar .title").get(0);
		this.contentContainer = $(this.element).find(".body").get(0);

		this.setTitle(options.title);

		this.bindEvents();

		this.bodyHeightDiff = $(this.element).height() - $(this.element).find('.body').height();
		this.titleWidthDiff = $(this.element).find('.titleBar .buttons').width() + 20;

		this.element.fading = new fading(this.element);
		this.element.fading.value = 0;

		this.bringOnTop();
	}

	extend(win, control);

	/*
	win.prototype.destroy = function()
	{
		this.element.win = undefined;
		this.element.parentNode.removeChild(this.element);
		win.parentClass.destroy.apply(this, arguments);
	}
	*/

	win.prototype.savePosition = function()
	{
		return {
			left: $(this.element).offset().left - $(document).scrollLeft(),
			top: $(this.element).offset().top - $(document).scrollTop(),
			width: $(this.element).width(),
			height: $(this.element).height()
		};		
	}

	win.prototype.restorePosition = function(position, duration)
	{
		if(duration == undefined) duration = 'fast';

		var pos = {
			left: $(document).scrollLeft() + position.left,
			top: $(document).scrollTop() + position.top,
			width: position.width,
			height: position.height
		}

		this.resize(pos, {duration: duration});
	}

	win.prototype.resizeOptions = {
		duration: undefined
	}

	win.prototype.resize = function(position, options)
	{
		if(options == undefined) options = this.resizeOptions;
		for(var option in this.resizeOptions)
			if(options[option] == undefined) options[option] = this.resizeOptions[option];
		
		if(options.duration == undefined)
		{
			if(position.left != undefined) $(this.element).css('left', position.left + 'px')
			if(position.top != undefined) $(this.element).css('top', position.top + 'px')
			if(position.width != undefined)
			{
				$(this.element).width(position.width);
				$(this.element).find('.titleBar .title').width(position.width - this.titleWidthDiff);
			}
			if(position.height != undefined)
			{
				$(this.element).height(position.height);
				$(this.element).find('.body').height(position.height - this.bodyHeightDiff);
			}

			this.fixate();
		}
		else
		{
			var animation = {};
			if(position.left != undefined) animation.left = position.left;
			if(position.top != undefined) animation.top = position.top;
			if(position.width != undefined) animation.width = position.width;
			if(position.height != undefined) animation.height = position.height;

			var winObject = this;
			$(this.element).stop().animate(animation, {duration: options.duration, complete: function() {winObject.fixate()} });
			
			if(position.width != undefined) $(this.element).find('.titleBar .title').stop().animate({width: position.width - this.titleWidthDiff}, {queue: false, duration: options.duration});
//			if(position.height != undefined) $(this.element).find('.body').stop().animate({height: position.height - this.bodyHeightDiff}, {queue: false, duration: options.duration});
		}
	}

	win.prototype.fixate = function()
	{
		if($(this.element).is('.minimized')) this.minimizedPosition = this.savePosition();
		else if(!$(this.element).is('.maximized')) this.normalPosition = this.savePosition();
	}

	win.prototype.getMinimizedPlace = function()
	{
		var margin = this.options.grid;
		
		var position = {};
		position.width = 200;
		position.height = $(this.element).find('.titleBar').height() - 3;
		position.left = margin;
		position.top = Math.round(($(document).scrollTop() + $(window).height() - position.height) / margin) * margin - margin;

		var otherWindows = $('body > div.window.minimized').get();
		var virtual = [];
		for(var i = 0; i < otherWindows.length; i++)
		{
			var offset = $(otherWindows[i]).offset();
			if(offset.top + $(otherWindows[i]).height() >= position.top)
			{
				var l = Math.floor(offset.left / margin);
				var r = Math.ceil((0.0 + offset.left + $(otherWindows[i]).width()) / margin);
				for(var x = l; x <= r; x++)
					virtual[x] = i + 1;
			}
		}

		var max = Math.ceil($(window).width() / margin);
		var w = Math.ceil(position.width / margin) + 1;

		for(var x = 0; x <= max; x++)
			if(virtual[x] == undefined)
			{
				for(var x2 = x + 1; x2 <= x + w; x2++)
					if(virtual[x2] != undefined)
					{
						x = x2;
						break;
					}

				if(x2 > x)
				{
					position.left = (x + 1) * margin;
					break;
				}
			}
			
		return position;
	}

	win.prototype.minimize = function()
	{
		var winObject = this;

		if($(this.element).is('.maximized')) this.restore();
		else this.fixate();
		
		if(!$(this.element).is('.minimized'))
		{
			$(this.element).addClass('minimized').find('.body').hide()
			this.resize(this.getMinimizedPlace(), {duration: 'normal'});
		}
		else this.restore();
	}

	win.prototype.maximize = function()
	{
		var winObject = this;

		if($(this.element).is('.minimized')) this.restore();
		else this.fixate();
		
		if(!$(this.element).is('.maximized'))
		{
			$(this.element).addClass('maximized')

			var position = {
					width: $(window).width(),
					height: $(window).height(),
					left: $(document).scrollLeft(),
					top: $(document).scrollTop()
				}

			this.resize(position, {duration: 'fast'});
		}
		else this.restore();
	}

	win.prototype.restore = function()
	{
		$(this.element)
			.removeClass('minimized')
			.removeClass('maximized')
			.find('.body').show()
				
		this.restorePosition(this.normalPosition);
	}

	win.prototype.bindEvents = function()
	{
		var winObject = this;

		var moveFunction = function(event)
		{
			var grid = winObject.options.grid;
			
			if(winObject.moving)
			{
				var mouse = {x: event.pageX, y: event.pageY};
				var newOffset = {top: mouse.y - winObject.moving.y, left: mouse.x - winObject.moving.x};

				if(newOffset.top < 0) newOffset.top = 0;
				if(newOffset.left < 0) newOffset.left = 0;
				if(newOffset.left + $(winObject.element).width() >= $(document).width() - 10)
					newOffset.left = $(document).width() - 10 - $(winObject.element).width();

				if($(winObject.element).is('.minimized'))
				{
					newOffset.left = Math.round(newOffset.left / grid) * grid;
					newOffset.top = Math.round(newOffset.top / grid) * grid;
				}

				winObject.resize(newOffset)

				event.stopPropagation();
			}
		}

		var moveEndFunction = function(event)
		{
			winObject.moving = undefined;
			$(document).unbind('mousemove', moveFunction);
			$(document).unbind('mouseup', moveEndFunction);
			$(winObject.element).removeClass('moving');
		}

		var moveStartFunction = function(event)
		{
			if(!$(winObject.element).is('.maximized') && !$(winObject.element).is('.resize'))
			{
				var offset = $(winObject.element).offset();
				winObject.moving = {x: event.pageX - offset.left, y: event.pageY - offset.top};
				$(winObject.element).addClass('moving');

				$(document).bind('mousemove', moveFunction);
				$(document).bind('mouseup', moveEndFunction);
				event.preventDefault();
			}
		}
		
		var resizeStartFunction = function(event)
		{
			var options = {}
			if($(this).hasClass('resize-e'))	options.horizontal = true;
			if($(this).hasClass('resize-s'))	options.vertical = true;
			if($(this).hasClass('resize-w'))	options.left = true;
			if($(this).hasClass('resize-n'))	options.top = true;

			options.resize = function(element, w, h, l, t) {winObject.resize({width: w, height: h, left: l ,top: t})};
			resizeElement(event, this, options)
		}

		var resizeCheckFunction = function(event)
		{
			if(!$(this).is('.resizing'))
			{
				var borderSize = 2;
				$(this).removeClass('resize resize-e resize-n resize-w resize-s resize-ne resize-nw resize-se resize-sw')

				if(!$(this).is('.maximized') && !$(this).is('.minimized') && !$(this).is('.moving'))
				{
					var offset = $(this).offset();
					var left = event.pageX <= offset.left + borderSize;
					var top = event.pageY <= offset.top + borderSize;
					var right = event.pageX >= offset.left + $(this).width() - borderSize;
					var bottom = event.pageY >= offset.top + $(this).height() - borderSize;

					if(left) $(this).addClass('resize-w');
					if(top) $(this).addClass('resize-n');
					if(right) $(this).addClass('resize-e');
					if(bottom) $(this).addClass('resize-s');
					if(top && left) $(this).addClass('resize-nw');
					if(top && right) $(this).addClass('resize-ne');
					if(bottom && left) $(this).addClass('resize-sw');
					if(bottom && right) $(this).addClass('resize-se');

					if(left || right || top || bottom)
					{
						$(this).addClass('resize');
						$(this).mousedown(resizeStartFunction);
					}
					else $(this).unbind('mousedown', resizeStartFunction);
				}
			}
		}

		$(this.element).find(".titleBar").dblclick(function() {winObject.maximize(); })
		$(this.element).find(".titleBar a.minimize").click(function() {winObject.minimize();})
		$(this.element).find(".titleBar a.restore").click(function() {winObject.restore();})
		$(this.element).find(".titleBar a.maximize").click(function() {winObject.maximize();})
		$(this.element).find(".titleBar a.close").click(function() {winObject.close();})
		$(this.element).find(".titleBar").mousedown(moveStartFunction)
		$(this.element).find(".titleBar a").mousedown(function(event) { $(this).addClass('pressed'); event.stopPropagation();})
		$(this.element).find(".titleBar a").mouseup(function(event) { $(this).removeClass('pressed'); event.stopPropagation();})
		$(this.element).mousemove(resizeCheckFunction);

		$(this.element).mousedown(function() {winObject.bringOnTop()})

		$(window).scroll(function()
		{
			if($(winObject.element).is('.minimized'))
				winObject.restorePosition(winObject.minimizedPosition);
		})
	}

	win.prototype.getType = function()
	{
		return 'win';
	}

	win.prototype.caption;
	win.prototype.closeButton;
	win.prototype.contentContainer;
	win.prototype.autoDestroy = false;

	// content - DOMFragment
	win.prototype.setContent = function(content)
	{
		$(this.contentContainer).empty().append(content);
		//$(content).dialog();
	}

	win.prototype.setTitle = function(title)
	{
		$(this.element).find('.titleBar .title').text(title)
	}

	win.prototype.open = function(left, top)
	{
		document.eventer.forceEvent('onDialogOpen', {win: this})

		if(top == undefined) top = $(document).scrollTop() + 60;
		if(left == undefined) left = ($(document).width() - $(this.element).width()) / 2;

		var position = {left: left, top: top, width: $(this.element).width(), height: $(this.element).height};
		this.resize(position);
		
		/* $(this.element).fadeIn('normal'); */
		this.show();
	}

	win.prototype.isOpen = function()
	{
		return !this.isHidden();
	}

	win.prototype.close = function()
	{
		//var win = this;
		//var autoDestroy = function() { if(win.autoDestroy) win.destroy(); }
		this.hide();
	}

	// $('div.managementPanel').slideUp('slow'); >> onfocus
