var dumpWindow =
{
	OPTION_PREFIX		: 'dumpWindow',
	ID					: 'dumpWindow',
	WINDOW				: null,
	STORED_DATA			: new Array(),
	ONLOAD_ASSIGNED		: false,
	BOUND				: {_x:20, _y:20, width:400, height:400},
	DRAG				: null,
	DRAG_RESIZE			: null,
	TAB_LIST			: new Array(),
	TAB_LIST_IDX		: new Object(),
	TAB_ACTIVE			: null,
	STATE				: 'normal',		// min,max,normal
	STATE_NORMAL		: new Object(),
	OPTION_EXPIRED		: 365, //days
	STORED_CONTENT_BOX	: new Array(),
	STORED_CONTENT_IDX	: new Object(),
	storedObject		: new Array(),
	globalStyle			:
	{
		windowBg	: '#333333',
		headerFont	: { color:'#FFFFFF', size:'14px' },
		headerBg	: '#0099FF',
		tabListBg	: '#333333',
		containerBg	: '#FFFFFF',
		tab			: { background:'#666666', overBackground:'#444444', font:{color:'#CCCCCC', size:'12px', weight:'normal'}, content:{ font:{ size:'12px', color:'#333333', weight:'normal' } } }
	},

	create: function()
	{
		if(this.WINDOW == null)
		{
			var body = document.getElementsByTagName('body').item(0);
			if(!isElement(body))
			{
				if(!this.ONLOAD_ASSIGNED)
					return this.addOnloadCreateEvent();
				else
					return 'waitForDocumentLoad';
			}

			var left 	= this.getOption('left', this.BOUND._x);
			var top 	= this.getOption('top', this.BOUND._y);
			var width 	= this.getOption('width', this.BOUND.width);
			var height 	= this.getOption('height', this.BOUND.height);

			var win 		= create.div(this.ID, null, null, {position:'absolute', left:left+'px', top:top+'px', height:height+'px', width:width+'px', backgroundColor:this.globalStyle.windowBg, overflow:'hidden', textAlign:'left'}, body);
			win.header		= create.div(null, 'Dump Window', null, {position:'absolute', left:'1px', top:'1px', right:'1px', padding:'5px', color:this.globalStyle.headerFont.color, fontSize:this.globalStyle.headerFont.size, backgroundColor:this.globalStyle.headerBg}, win);
			win.header.min	= create.div(null, null, null, {position:'absolute', right:'20px', top:'5px', width:'6px', height:'6px', cursor:'pointer', backgroundColor:this.globalStyle.headerBg, borderBottom:'2px solid '+this.globalStyle.headerFont.color}, win.header);
			win.header.max	= create.div(null, null, null, {position:'absolute', right:'7px', top:'5px', width:'6px', height:'5px', cursor:'pointer',backgroundColor:this.globalStyle.headerBg, border:'1px solid '+this.globalStyle.headerFont.color, borderBottom:'2px solid '+this.globalStyle.headerFont.color}, win.header);
			win.tabList		= create.div(null, null, null, {position:'absolute', left:'1px', top:win.header.offsetHeight+2+'px', width:'20px', backgroundColor:this.globalStyle.tabListBg}, win);
			win.container	= create.div(null, null, null, {position:'absolute', left:'22px', top:win.header.offsetHeight+2+'px', right:'1px', bottom:'12px', overflow:'auto', backgroundColor:this.globalStyle.containerBg, fontFamily:'monospace'}, win);
			win.footer		= create.div(null, null, null, {position:'absolute', left:'22px', right:'1px', bottom:'1px', height:'10px', backgroundColor:this.globalStyle.headerBg}, win);
			win.resize		= create.div(null, null, null, {position:'absolute', top:'0px', right:'2px', cursor:'pointer', width:'0px', height:'0px', borderTop:'8px solid '+this.globalStyle.headerBg, borderRight:'8px solid '+this.globalStyle.headerFont.color}, win.footer);

			this.STATE_NORMAL = getBounds(win);

			win.header.min.onclick = function(){ dumpWindow.minimize() };
			win.header.max.onclick = function(){ dumpWindow.maximize() };

			this.DRAG = new dragAndDrop();
			this.DRAG.noClone = true;
			this.DRAG.assign(win.header, null, win);
			this.DRAG.onDragStart = function(event)
			{
				if(dumpWindow.STATE == 'max' || dumpWindow.STATE == 'min')
					this.endDrag(event);
			}
			this.DRAG.onDragEnd = function()
			{
				var bound = getBounds(this.cloneObject);
				if(dumpWindow.STATE == 'normal')
					dumpWindow.STATE_NORMAL = bound;

				dumpWindow.setOption('left', bound._x);
				dumpWindow.setOption('top', bound._y);
			}

			this.DRAG_RESIZE = new dragAndDrop();
			this.DRAG_RESIZE.cursor.drag = 'cursor-resize-rb';
			this.DRAG_RESIZE.assign(win.resize);
			this.DRAG_RESIZE.onDragStart = function(){ this.cloneObject.style.opacity='0'; this.cloneObject.style.filter='alpha(opacity=0)';}
			this.DRAG_RESIZE.onDrag = function(){ dumpWindow.resizeBy(this.distance); };
			this.DRAG_RESIZE.onDragEnd = function()
			{
				dumpWindow.BOUND = getBounds(dumpWindow.WINDOW);
				dumpWindow.setOption('width', dumpWindow.BOUND.width);
				dumpWindow.setOption('height', dumpWindow.BOUND.height);
			};

			var ctxMenu = new ContextMenu(win.header);
			ctxMenu.onAfterShow = new CallBack(function(menu, param)
			{
				var expand = menu.getItem(0, 'expand');
				expand.setChecked(dumpWindow.getOption('expand', 'false') == 'true' ? true : false);
			});
			ctxMenu.addItem({level:0, name:'expand', type:'chkbox', content:'Expand on new data', cb:new CallBack(function(menu, param){dumpWindow.setOption('expand', menu.getItem(0,'expand').isChecked() ? 'true' : 'false')})})
			ctxMenu.addItem({level:0, name:'close', content:'Close', cb:new CallBack(function(menu, param){dumpWindow.WINDOW.del(); menu.destroy();})})

			this.WINDOW = win;
			this.BOUND = getBounds(win);

			switch(this.getOption('state', 'normal'))
			{
				case 'min':	this.minimize();	break;
				case 'max':	this.maximize();	break;
			}

			this.dumpStored();
			return 'dumpWindowCreated';
		}
		return false;
	},

	minimize: function()
	{
		if(this.WINDOW)
		{
			if(this.STATE == 'min')
			{
				this.DRAG.enableDrag		= true;
				this.WINDOW.style.left		= this.STATE_NORMAL._x + 'px';
				this.WINDOW.style.top		= this.STATE_NORMAL._y + 'px';
				this.WINDOW.style.height 	= this.STATE_NORMAL.height + 'px';
				this.WINDOW.style.width		= this.STATE_NORMAL.width + 'px';
				this.STATE = 'normal';
				this.setOption('state', 'normal');
				this.WINDOW.footer.style.display = 'block';
				return true;
			};

			this.STATE = 'min'
			this.setOption('state', 'min');

			this.DRAG.enableDrag		= false;
			this.WINDOW.style.height 	= this.WINDOW.header.offsetHeight + 2 +'px';
			this.WINDOW.style.width 	= 200 +'px';
			this.WINDOW.style.left		= getWindowWidth() - 205 + 'px';
			this.WINDOW.style.top		= '5px';
			this.WINDOW.footer.style.display = 'none';

			return true;
		}
		return false;
	},

	maximize: function()
	{
		if(this.WINDOW)
		{
			if(this.STATE == 'max')
			{
				this.DRAG.enableDrag		= true;
				this.WINDOW.style.left		= this.STATE_NORMAL._x + 'px';
				this.WINDOW.style.top		= this.STATE_NORMAL._y + 'px';
				this.WINDOW.style.height 	= this.STATE_NORMAL.height + 'px';
				this.WINDOW.style.width		= this.STATE_NORMAL.width + 'px';
				this.STATE = 'normal';
				this.setOption('state', 'normal');
				this.WINDOW.footer.style.display = 'block';
				return true;
			};

			this.STATE = 'max';

			this.setOption('state', 'max');

			this.DRAG.enableDrag		= false;
			this.WINDOW.style.left		= '0px';
			this.WINDOW.style.top		= '0px';
			this.WINDOW.style.height 	= getWindowHeight() +'px';
			this.WINDOW.style.width 	= getWindowWidth() +'px';
			this.WINDOW.footer.style.display = 'none';

			return true;
		}
		return false;
	},

	setNormal: function(state)
	{
		if(state.indexOf(this.STATE) != -1)
		{
			if(this.STATE == 'min')	this.maximize();
			if(this.STATE == 'max')	this.maximize();
		}
	},

	resizeBy: function(param)
	{
		if(this.WINDOW)
		{
			this.WINDOW.style.width 	= this.BOUND.width - param._x + 'px';
			this.WINDOW.style.height	= this.BOUND.height - param._y + 'px';
		}
	},


	/**
	 * enableStateChange = true/false
	 * name = name
	 */
	addTab: function(param)
	{
		if(this.WINDOW)
		{
			var name = param.name;
			if(this.TAB_LIST_IDX.hasOwnProperty(name)) return 'alredyExist: '+name;

			this.TAB_LIST_IDX[name] = this.TAB_LIST.length;

			var label	= name;
			var tab 	= create.div(null, label.toUpperCase().split('').join('<br />'), null, {cursor:'pointer', padding:'3px 0 3px 0', backgroundColor:this.globalStyle.tab.background, color:this.globalStyle.tab.font.color, fontSize:this.globalStyle.tab.font.size, fontWeight:this.globalStyle.tab.font.weight, textAlign:'center', borderBottom:'5px solid #CC3300'}, this.WINDOW.tabList);
			var content	= create.div(null, null, null, {padding:'5px', display:'none', fontSize:this.globalStyle.tab.content.font.size, color:this.globalStyle.tab.content.font.color, weight:this.globalStyle.tab.content.font.weight}, this.WINDOW.container, true);
			var ctxMenu	= new ContextMenu(tab);
			ctxMenu.addItem({level:0, name:'close', content:'close tab', cb:new CallBack(function(menu, tabName){dumpWindow.removeTab(tabName); menu.destroy();}, name)});

			tab.name = name;
			tab.onclick = function()
			{
				dumpWindow.setActiveTab(this.name, true);
			}

			tab.onmouseover = function()
			{
				this.style.backgroundColor = dumpWindow.globalStyle.tab.overBackground;
			}

			tab.onmouseout = function()
			{
				this.style.backgroundColor = dumpWindow.globalStyle.tab.background;
			}

			this.TAB_LIST.push({tab:tab, content:content, enableStateChange:param.enableStateChange, alwaysOnTop:param.alwaysOnTop, name:name});
			return this.TAB_LIST[this.TAB_LIST_IDX[name]];
		}
		return 'waitForWindowCreating';
	},

	getTab: function(param)
	{
		if(this.WINDOW)
		{
			var name = param.name;
			if(this.TAB_LIST_IDX.hasOwnProperty(name))
				return this.TAB_LIST[this.TAB_LIST_IDX[name]];
			else
				return this.addTab(param);
		}
		return null;
	},

	setActiveTab: function(name, dropAlwaysOnTop)
	{
		if(this.TAB_LIST[this.TAB_ACTIVE])
			this.TAB_LIST[this.TAB_ACTIVE].scrollTop = this.WINDOW.container.scrollTop;

		if(this.TAB_LIST[this.TAB_ACTIVE] && !dropAlwaysOnTop)
			if(this.TAB_LIST[this.TAB_ACTIVE].alwaysOnTop)
				return false;

		if(this.TAB_LIST_IDX.hasOwnProperty(name))
		{
			var idx = this.TAB_LIST_IDX[name];
			for(var i=0 ; i<this.TAB_LIST.length ; i++)
			{
				if(!this.TAB_LIST[i]) continue;
				if(idx == i)
				{
					this.TAB_LIST[i].content.style.display = 'block';
					this.TAB_LIST[i].tab.style.borderColor = '#FFCC00';
					if(this.TAB_LIST[i].enableStateChange && this.getOption('expand', 'false') == 'true')
						this.setNormal(['min']);
					this.TAB_ACTIVE = i;

					if(this.TAB_LIST[i].scrollTop)
						this.WINDOW.container.scrollTop = this.TAB_LIST[i].scrollTop;
					else
						this.WINDOW.container.scrollTop = 0;
				}
				else
				{
					this.TAB_LIST[i].content.style.display = 'none';
					this.TAB_LIST[i].tab.style.borderColor = '#CC3300';
				}
			}
		}
	},

	removeTab: function(name)
	{
		if(this.TAB_LIST_IDX.hasOwnProperty(name))
		{
			var idx = this.TAB_LIST_IDX[name];
			this.TAB_LIST[idx].tab.del();
			this.TAB_LIST[idx].content.del();
			delete this.TAB_LIST[idx];
			delete this.TAB_LIST_IDX[name];
			for(var i=0 ; i<this.TAB_LIST.length ; i++)
			{
				if(this.TAB_LIST[i])
				{
					this.setActiveTab(this.TAB_LIST[i].name);
					break;
				}
			}
		}
	},

	dump: function(content, tabProp, clear)
	{
		if(this.WINDOW)
		{
			var tabName = tabProp.name;
			var tab 	= this.getTab(tabProp);
			var box		= new Object();

			if(clear) tab.content.innerHTML = '';

			box.parent 			= tab.content;
			box.name			= content.name;
			box.type			= content.type;
			box.content			= new Object();
			box.content			= this.createContent(content);
			new dumpWindowContentBox(box);

			this.setActiveTab(tabName);
		}
		else
		{
			this.storeDump(content, tabProp, clear);
			this.create();
		}
	},

	createContent: function(content)
	{
		var str 	= '';
		var txt 	= content.text;
		var header 	= content.header;
		var getText	= function(param, name)
		{
			var ret = param;
			switch(typeof param)
			{
				case 'function':
					if(param.name) 	ret = '[function'+(name != param.name ? ' '+param.name : '')+']';
					else			ret = '[function]';
					var index = dumpWindow.storedObject.length;
					dumpWindow.storedObject.push({obj:param,name:'_'+name});
					ret = '<span onclick="dumpWindow.dump({text:\'<pre>\'+dumpWindow.storedObject['+index+'].obj+\'</pre>\'}, {name:dumpWindow.storedObject['+index+'].name});" style="cursor:pointer;">'+ret+'</span>';
				break;

				case 'object':
					ret = '[object]';
					if(param == null)
					{
						ret = 'null';
					}
					else
					{
						var index = dumpWindow.storedObject.length;
						dumpWindow.storedObject.push({obj:param,name:'_'+name});
						var constName = (getBrowser().ff) ? ' '+param.constructor.name : '';
						ret = '<span style="cursor:pointer;" onclick="dumpWindow.dump({text:dumpWindow.storedObject['+index+'].obj}, {name:dumpWindow.storedObject['+index+'].name});">[object'+constName+']</span>';
					}

				break;

				case 'boolean':
					ret = (param) ? 'true' : 'false';
				break;

				default:
					ret = isUndefined(param) ? 'undefined' : param;
				break;
			}
			return ret;
		};

		switch(typeof txt)
		{
			case 'object':
				if(txt != null)
				{
					if(!header)header = txt;
					if(txt.constructor)
						if(txt.constructor.name)
							header = txt.constructor.name;

					/*if(isFunction(txt.orderByKey))
						txt = txt.orderByKey();*/
					for(var k in txt)
					{
						str += '<b>'+k+'</b> => '+getText(txt[k], k)+'<br />';
					}
				}
				else
				{
					if(!header)header = 'NULL';
					str = 'NULL';
				}
			break;

			case 'boolean':
				str 	= (txt) ? 'true' : 'false';
				if(!header)header 	= null;
			break;

			case 'function':
				str = getText(txt, '[function]');
				if(!header)header 	= null;
			break;

			case 'string':
				str 	= txt;
				if(!header)header 	= null;
			break;

			case 'number':
				str 	= txt;
				if(!header)header 	= null;
			break;
		}

		return {text:str, header:header};
	},

	storeDump: function(content, tab, clear)
	{
		this.STORED_DATA.push({content:content, tab:tab, clear:clear});
	},

	dumpStored: function()
	{
		if(this.WINDOW)
		{
			for(var i=0 ; i<this.STORED_DATA.length ; i++)
			{
				this.dump(this.STORED_DATA[i].content, this.STORED_DATA[i].tab, this.STORED_DATA[i].clear);
			}
			this.STORED_DATA = new Array();
		}
	},

	setOption: function(name, value)
	{
		name = this.OPTION_PREFIX+'_'+name;
		setCookie(name, value, this.OPTION_EXPIRED);
	},

	getOption: function(name, def)
	{
		name = this.OPTION_PREFIX+'_'+name;
		var ret = getCookie(name);
		if(ret == null)
			ret = def;
		return ret;
	},

	addOnloadCreateEvent: function()
	{
		addEvent(window, 'load', this, 'create');
	}
}

/**
 * type: normal / box / error
 * refreshAble: true / false
 * name: ha refreshable
 * parent: szülő objektum
 * content: tartalom
 */
function dumpWindowContentBox(param)
{
	this.refreshAble	= !param.name ? false : true;
	this.name			= !param.name ? null : param.name;
	this.parent			= !param.parent ? null : param.parent;
	this.content		= isUndefined(param.content) ? {} : param.content;
	this.type			= !param.type ? (this.name || this.content.header ? 'box' : 'normal') : param.type;

	var box = this.get(this.name);
	box.content.innerHTML = this.content.text;
	if(box.header)	box.header.innerHTML = (this.name) ? this.name : this.content.header;
}

dumpWindowContentBox.prototype.get = function(name)
{
	if(!name) return this.create();
	if(name)
	{
		if(dumpWindow.STORED_CONTENT_IDX.hasOwnProperty(name) && this.refreshAble)
			return dumpWindow.STORED_CONTENT_BOX[dumpWindow.STORED_CONTENT_IDX[name]];
		else
			return this.create();
	}
	return null;
}

dumpWindowContentBox.prototype.create = function()
{
	var ret 	= new Object();
	ret.name	= this.name;
	switch(this.type)
	{
		case 'normal':
			ret.content = create.div(null, null, null, {padding:'0 0 3px 0', marginBottom:'5px', borderBottom:'1px solid #333333'}, this.parent);
		break;

		case 'error':
			ret.container 	= create.div(null, null, null, {marginBottom:'5px'}, this.parent);
			ret.header		= create.div(null, null, null, {padding:'3px', backgroundColor:'#CC3300', color:dumpWindow.globalStyle.headerFont.color}, ret.container);
			ret.content		= create.div(null, null, null, {padding:'3px', border:'1px solid #CC3300'}, ret.container);
		break;

		case 'box':
			ret.container 	= create.div(null, null, null, {marginBottom:'5px'}, this.parent);
			ret.header		= create.div(null, null, null, {padding:'3px', backgroundColor:dumpWindow.globalStyle.headerBg, color:dumpWindow.globalStyle.headerFont.color}, ret.container);
			ret.content		= create.div(null, null, null, {padding:'3px', border:'1px solid '+dumpWindow.globalStyle.headerBg}, ret.container);
		break;
	}
	if(this.name)
	{
		dumpWindow.STORED_CONTENT_IDX[this.name] = dumpWindow.STORED_CONTENT_BOX.length;
		dumpWindow.STORED_CONTENT_BOX.push(ret);
	}
	if(ret.header)
	{
		var ctx = new ContextMenu(ret.header);
		var removeCB = new CallBack(function(menu, param)
		{
			var elm = param.elm;
			if(elm.name)
			{
				if(dumpWindow.STORED_CONTENT_IDX.hasOwnProperty(elm.name))
				{
					var idx = dumpWindow.STORED_CONTENT_IDX[elm.name];
					dumpWindow.STORED_CONTENT_BOX[idx].container.del();
					delete dumpWindow.STORED_CONTENT_BOX[idx];
					delete dumpWindow.STORED_CONTENT_IDX[elm.name];
				}
			}
			else
			{
				elm.container.del();
			}
			menu.destroy();

		},{obj:this, elm:ret});
		ctx.addItem({level:0, content:'remove this box', cb:removeCB});
	}
	return ret;
}


/*
for(var i=0 ; i<20 ; i++)
	dumpWindow.dump({text:'test '+i, name:'mouse'}, {name:'js', enableStateChange:true, alwaysOnTop:true});

for(var i=0 ; i<20 ; i++)
	dumpWindow.dump({text:'test_ '+i, name:'mouse2'}, {name:'js'});

dumpWindow.dump({text:'test_ '}, {name:'js'});

dumpWindow.dump({text:create.div(), type:'error', header:'test'}, {name:'error'});*/

/*dumpWindow.dump({text:'String', header:'String'}, {name:'js'});
dumpWindow.dump({text:12323, header:'Number'}, {name:'js'});
dumpWindow.dump({text:new Object(), header:'Object'}, {name:'js'});
dumpWindow.dump({text:new Array(), header:'Array'}, {name:'js'});
dumpWindow.dump({text:create.div(), header:'DIV'}, {name:'js'});
dumpWindow.dump({text:new dragAndDrop(), header:'String'}, {name:'js'});
dumpWindow.dump({text:null, header:'null Object'}, {name:'js'});
dumpWindow.dump({text:true, header:'Shit'}, {name:'js'});
dumpWindow.dump({text:dumpWindow, header:'Shit'}, {name:'js'});*/


/*addEvent(document, 'mousemove', null, function(e)
{
	var mouse = getMouseCoords(e);
	dump('X: '+mouse._x+', Y: '+mouse._y, 'mouseCoord');
});*/

