
function ws_display(id, value)
{
	document.getElementById(id).style.display = value;
}

function WSCFormError(elem, hint, error)
{
	if ( hint ) alert(error + '\n\nПодсказка: ' + hint);
	else alert(error);
	elem.focus();
	return false;
}

// depricated
function ShowError(elem, hint, error)
{
	return WSCFormError(elem, hint, error);
}

function on_post(button, action)
{
	button.form.target = '_self';
	button.form.act.value = action;
}

function on_preview(button, frame_name)
{
	on_preview_ex(button, frame_name, 'preview');
}

function on_preview_ex(button, frame_name, action)
{
	var list = document.getElementsByName(frame_name);
	if ( list.length != 1 )
	{
		// don't worry, just
		button.form.target = '_self';
	}
	else
	{
		// it's ok, preview in frame
		var frame = list.item(0);
   		frame.style.display = 'block';
		button.form.target = frame.name;
		button.form.act.value = action;
	}
}

/** вернуть текст выделенный на странице */
function bbcode_get_selection()
{
	if ( window.getSelection )
	{
		return window.getSelection().toString();
	}
	else if ( document.getSelection )
	{
		return document.getSelection();
	}
	else if ( document.selection )
	{
		return document.selection.createRange().text;
	}
	return '';
}

var selection = '';

function bbcode_catch_selection()
{
	selection = bbcode_get_selection();
}

function bbcode_replace_selection(textarea, text)
{
	var start = textarea.selectionStart;
	var end = textarea.selectionEnd;
	var len = textarea.value.length;
	var scrollTop = textarea.scrollTop;
	textarea.value = textarea.value.substring(0, start) + text + textarea.value.substring(end, len);
	textarea.focus();
	textarea.selectionStart = start;
	textarea.selectionEnd = end + text.length;
	textarea.scrollTop = scrollTop;
}

/** вставить текст после выделения */
function bbcode_insert_after(textarea, text)
{
	var start = textarea.selectionStart;
	var end = textarea.selectionEnd;
	var len = textarea.value.length;
	var scrollTop = textarea.scrollTop;
	textarea.value = textarea.value.substring(0, end) + text + textarea.value.substring(end, len);
	textarea.focus();
	textarea.selectionStart = end;
	textarea.selectionEnd = end + text.length;
	textarea.scrollTop = scrollTop;
}

/** вставить тег */
function bbcode_insert_tag(txt, tag_open, tag_close)
{
	var textarea = document.getElementById(txt);
	if ( document.selection )
	{ // IE
		var range = document.selection.createRange();
		range.text = tag_open + range.text + tag_close;
		textarea.focus();
		return false;
	}
	var start = textarea.selectionStart;
	var end = textarea.selectionEnd;
	var inner = textarea.value.substring(start, end);
	var tag = tag_open + inner + tag_close;
	var len = textarea.value.length;
	var scrollTop = textarea.scrollTop;
	textarea.value = textarea.value.substring(0, start) + tag + textarea.value.substring(end, len);
	textarea.focus();
	textarea.selectionStart = start;
	textarea.selectionEnd = end + tag_open.length + tag_close.length;
	textarea.scrollTop = scrollTop;
	return false;
}

/** вставить цитату пользователя */
function bbcode_quote(txt, author)
{
	if ( selection == '' )
	{
		alert('Выделите текст');
		return;
	}
	var code = '[quote="' + author + '"]' + selection + '[/quote]';
	bbcode_insert_after(document.getElementById(txt), code);
}

function bbedit_on_preview(id)
{
	var text = document.getElementById(id).value;
	if ( ajax_post_frame(id + '_preview', ajax_prefix + 'post.php', {action: "bbedit.preview", text: text}) )
	{
		ws_display(id + '_preview', 'block');
		ws_display(id + '_area', 'none');
		ws_display(id + '_preview_btn', 'none');
		ws_display(id + '_edit_btn', 'inline');
		return true;
	}
	else
	{
		return false;
	}
}

function bbedit_on_edit(id)
{
	frame_clear(id + '_preview');
	ws_display(id + '_preview', 'none');
	ws_display(id + '_area', 'block');
	ws_display(id + '_preview_btn', 'inline');
	ws_display(id + '_edit_btn', 'none');
}

var ctrl = false;

function bbedit_onkeydown(editorID, event)
{
	var editor = document.getElementById(editorID);
	if ( event.which == 17 ) ctrl = true;
	if ( ctrl )
	{
		switch (event.which)
		{
		case 13:
			//alert(event.which);
			editor.form.submit();
			if ( event.preventDefault ) event.preventDefault();
			return false;
//		case 80:
//			bbedit_on_preview(editorID);
//			event.preventDefault();
//			return false;
		}
	}
	return true;
}

function bbedit_onkeyup(editorID, event)
{
	if ( event.which == 17 ) ctrl = false;
}

function ajax_request()
{
	try { return new XMLHttpRequest(); } catch (e) {}
	try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) {}
	try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) {}
	return false;
}

function sync_get_xml(url)
{
	var request = ajax_request();
	if ( request === false ) return false;
	request.open('GET', url, false);
	request.send(null);
	return request.responseXML;
}

function async_raw_get(url, onload, data)
{
	var request = ajax_request();
	if ( request === false ) return false;
	request.open('GET', url, true);
	request.onreadystatechange = function() {
		if ( request.readyState == 4 ) {
			onload(request, data);
			if ( request.onreadystatechanage ) request.onreadystatechanage = null;
		}
	}
	request.send(null);
	return true;
}

function async_raw_post(url, content, onload, data)
{
	var request = ajax_request();
	if ( request === false ) return false;
	request.open("POST", url, true);
	request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	request.onreadystatechange = function() {
		if ( request.readyState == 4 ) {
			onload(request, data);
		}
	}
	request.send(content);
	return true;
}

function on_load_frame(request, frame)
{
	frame.innerHTML = request.responseText;
}

function ajax_frame(id, url)
{
	var frame = document.getElementById(id);
	var result = async_raw_get(url, on_load_frame, frame);
	if ( result === false ) return false;
	frame.innerHTML = '<div class="ajax_loading"></div>';
	return true;
}

function ajax_post_frame(id, url, args)
{
	var frame = document.getElementById(id);
	var params = new Array();
	for(var arg in args)
	{
		try
		{
			var val = args[arg];
			params[params.length] = encodeURIComponent(arg) + '=' + encodeURIComponent(val);
		} catch (e) { }
	}
	var result = async_raw_post(url, params.join('&'), on_load_frame, frame);
	if ( result === false ) return false;
	frame.innerHTML = '<div class="ajax_loading">Loading</div>';
	return true;
}

function post(frameID, action, args)
{
	var frame = document.getElementById(frameID);
	var query = 'ajax=on&action=' + encodeURIComponent(action);
	for(var name in args) {
		try {
			query += '&' + encodeURIComponent(name) + '=' + encodeURIComponent(args[name]);
		} catch (e) { }
	}
	var request = ajax_request();
	if ( request === false ) return false;
	request.open("POST", ajax_prefix + 'post.php', true);
	request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	request.onreadystatechange = function() {
		if ( request.readyState == 4 ) {
			frame.innerHTML = request.responseText;
			request.onreadystatechanage = null;
		}
	}
	request.send(query);
	frame.innerHTML = '<div class="ajax_loading"></div>';
	return true;
}

function frame_clear(id)
{
	document.getElementById(id).innerHTML = '';
}

function goback(obj)
{
	if ( history.length > 0 )
	{
		history.back();
		return true;
	}
	return false;
}

function search_same_report(obj, prj_name)
{
	if ( obj.wsp_old_value !== obj.value )
		if ( post('same_reports', 'project.reports.search_same', {summary: obj.value, prj: prj_name}) )
			{ obj.wsp_old_value = obj.value; return true; }
	return false;
}

// вернуть размеры видимой области окна
function getScreenSize() {
	return {
	w: (window.innerWidth ? window.innerWidth : (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.offsetWidth)),
	h: (window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.offsetHeight))
	};
}

function getElementSize(elem) {
	if ( elem.getBoundingClientRect ) return {
		w: elem.getBoundingClientRect().right - elem.getBoundingClientRect().left - 1,
		h: elem.getBoundingClientRect().bottom - elem.getBoundingClientRect().top - 1
		}
	else return {
		w: elem.offsetWidth,
		h: elem.offsetHeight
	}
}

function ws_get_scroll() {
	var scrollX, scrollY;
	if(typeof window.pageYOffset == 'number') {
		scrollX = window.pageXOffset;
		scrollY = window.pageYOffset;
	} else if(document.body && (document.body.scrollTop || document.body.scrollLeft)) {
		scrollX = document.body.scrollLeft;
		scrollY = document.body.scrollTop;
	} else if(document.documentElement && (document.documentElement.scrollTop || document.documentElement.scrollLeft)) {
		scrollY = document.documentElement.scrollTop;
		scrollX = document.documentElement.scrollLeft;
	} else {
		scrollX = 0;
		scrollY = 0;
	}
	return {X: scrollX, Y: scrollY};
}

// создать тег
function mktag(tagName, props, styles) {
	var obj = document.createElement(tagName);
	if ( props ) {
		for (var Name in props) {
			obj.setAttribute(Name, props[Name]) || eval('obj.'+Name+'=props[Name];');
		}
	}
	if ( styles ) {
		for (var Name in styles) {
			try { obj.style[Name] = styles[Name] }
			catch (e) { if ( obj.currentStyle ) obj.currentStyle[Name] = styles[Name]; }
		}
	}
	return obj;
}

function jframe_encode_form(form)
{
	var params = new Array();
	for(var i = 0; i < form.elements.length; i++)
	{
		try
		{
			var val = form.elements[i].value;
			var arg = form.elements[i].name;
			params[params.length] = encodeURIComponent(arg) + '=' + encodeURIComponent(val);
		} catch (e) { }
	}
	return params.join('&');
}

function jframe_decode_form(form, data)
{
	var params = data.split('&');
	for(var i = 0; i < params.length; i++)
	{
		var param = params[i].split('=');
		try {
			var name = decodeURIComponent(param[0]);
			var value = decodeURIComponent(param[1]);
			form.elements[name].value = value;
		} catch (e) {}
	}
}

function jframe_encode_checks(form)
{
	var params = new Array();
	for(var i = 0; i < form.elements.length; i++)
	{
		try
		{
			var val = form.elements[i].value;
			var chk = form.elements[i].checked ? 1 : 0;
			params[params.length] = encodeURIComponent(arg) + '=' + encodeURIComponent(chk);
		} catch (e) { }
	}
	return params.join('&');
}

function jframe_decode_checks(form, data)
{
	var params = data.split('&');
	for(var i = 0; i < params.length; i++)
	{
		var param = params[i].split('=');
		try {
			var name = decodeURIComponent(param[0]);
			var chk = decodeURIComponent(param[1]) ? true : false;
			form.elements[name].checked = chk;
		} catch (e) {}
	}
}

// сериализовать HTML-тег
// (innerHTML не поля форм, а нам нужно чтобы сохранялись)
function jframe_serialize(tag)
{
	var forms = tag.getElementsByTagName('form');
	for(var i = 0; i < forms.length; i++) {
		var form = jframe_encode_form(forms[i]);
		forms[i].setAttribute('jframe-values', form);
	}
	return tag.innerHTML;
}

// десериализовать HTML-тег
// (innerHTML не поля форм, а нам нужно чтобы сохранялись)
function jframe_unserialize(tag, data)
{
	tag.innerHTML = data;
	var forms = tag.getElementsByTagName('form');
	for(var i = 0; i < forms.length; i++) {
		jframe_decode_form(forms[i], forms[i].getAttribute('jframe-values'));
	}
}

/**
* Регулярное выражения для парсинга URL-ов
*/
var jframe_url_regexp = /^(https?):\/\/([^\/]+)(:(\d+))?(\/[^\?]*)?(\?[^#]*)?(#.*)?$/;

// создать js-фрейм
function jframe_create()
{
	var frame = {left: 0, top: 0, onclose: false};
	frame.root = mktag('table', {className: 'jframe'}, {position: 'absolute', left: '0px', top: '0px'});
	frame.ws = frame;
	frame.root.ws = frame;
	frame.history = new Array ();
	frame.forward = new Array ();
	frame.isPosted = false;
	frame.markLoading = function () {
		var div = mktag('div', {className: 'ajax_loading'});
		div.style.width = '20em';
		div.style.height = '10em';
		frame.body.innerHTML = '';
		frame.body.appendChild(div);
	};
	frame.prepare = function () {
		var links = frame.body.getElementsByTagName('a');
		for(var i = 0; i < links.length; i++) {
			var m = jframe_url_regexp.exec(links[i].href);
			if ( m && m[2] === document.domain ) switch (links[i].getAttribute('jframe-target')) {
			case '_blank':
				links[i].onclick = function (e) { return jframe_open(this, jframe_setmode(this.href), e); };
				break;
			default:
				links[i].onclick = prevented(frame.navigate, links[i]);
			}
			else { links[i].target = '_blank'; }
		}
		
		var forms = frame.body.getElementsByTagName('form');
		for(var i = 0; i < forms.length; i++) {
			var m = jframe_url_regexp.exec(forms[i].action);
			if ( ! forms[i].action.match(/^https?:\/\//) || m && m[2] === document.domain ) switch (forms[i].getAttribute('jframe-target')) {
			case '_blank': break;
			default:
				forms[i].onsubmit = prevented(frame.post, forms[i]);
			}
		}
		
	};
	frame.serialize = function () {
		var forms = frame.body.getElementsByTagName('form');
		for(var i = 0; i < forms.length; i++) {
			var form = forms[i];
			form.setAttribute('jframe-values', jframe_encode_form(form));
			form.setAttribute('jframe-checks', jframe_encode_checks(form));
		}
		return {
		link: frame.altLink,
		title: frame.title.innerHTML,
		isPosted: frame.isPosted,
		body: frame.body.innerHTML
		};
	};
	frame.unserialize = function (page) {
		frame.altLink = page.link;
		frame.title.innerHTML = page.title;
		frame.isPosted = page.isPosted;
		frame.body.innerHTML = page.body;
		var forms = frame.body.getElementsByTagName('form');
		for(var i = 0; i < forms.length; i++) {
			var form = forms[i];
			jframe_decode_form(form, form.getAttribute('jframe-values'));
			jframe_decode_checks(form, form.getAttribute('jframe-checks'));
		}
		frame.prepare();
		frame.refresh.link.href = page.link;
		if ( frame.history.length == 0 )
		{
			frame.prev.link.href = '#';
			frame.prev.img.src = url('img/jframe/prev-grey.png');
		}
		if ( frame.forward.length == 0 )
		{
			frame.next.link.href = '#';
			frame.next.img.src = url('img/jframe/next-grey.png');
		}
	};
	frame.onload = function (request) {
		frame.body.innerHTML = request.responseText;
		var h = frame.body.getElementsByTagName('h1');
		if ( h.length > 0 ) {
			frame.title.innerHTML = h[0].innerHTML;
			h[0].style.display = 'none';
		}
		frame.prepare();
	};
	frame.onFirstLoad = function (request) {
		frame.onload(request);
		jframe_centerize(frame);
	};
	frame.navigate = function (tag) {
		frame.history.push(frame.serialize());
		frame.forward = new Array ();
		frame.next.img.src = url('img/jframe/next-grey.png');
		frame.next.link.href = '#';
		frame.prev.img.src = url('img/jframe/prev.png');
		frame.prev.link.href = frame.altLink;
		frame.title.innerHTML = tag.innerHTML;
		frame.altLink = tag.href;
		frame.refresh.link.href = tag.href;
		frame.isPosted = false;
		frame.markLoading();
		if ( ! async_raw_get(jframe_setmode(tag.href), frame.onload, frame) )
		{
			window.location.href = tag.href;
			return false;
		}
		return true;
	};
	frame.goBack = function () {
		if ( frame.history.length == 0 ) return true;
		frame.forward.push(frame.serialize());
		frame.next.img.src = url('img/jframe/next.png');
		frame.next.link.href = frame.altLink;
		frame.unserialize( frame.history.pop() );
		return true;
	};
	frame.goNext = function () {
		if ( frame.forward.length == 0 ) return true;
		frame.history.push(frame.serialize());
		frame.prev.img.src = url('img/jframe/prev.png');
		frame.prev.link.href = frame.altLink;
		frame.unserialize( frame.forward.pop() );
		return true;
	};
	frame.refresh = function () {
		if ( frame.isPosted ) {
			if ( ! confirm('Отправить форму повторно?') ) return true;
		}
		frame.markLoading();
		if ( frame.isPosted ) {
			if ( ! async_raw_post(frame.postAction, frame.postData, frame.onload, frame) )
			{
				// TODO something
				return false;
			}
			return true;
		}
		if ( ! async_raw_get(jframe_setmode(frame.altLink), frame.onload, frame) )
		{
			window.location.href = tag.href;
			return false;
		}
		return true;
	};
	frame.post = function (form) {
		frame.history.push(frame.serialize());
		frame.forward = new Array ();
		frame.next.img.src = url('img/jframe/next-grey.png');
		frame.next.link.href = '#';
		frame.prev.img.src = url('img/jframe/prev.png');
		frame.prev.link.href = frame.altLink;
		frame.altLink = form.action;
		frame.isPosted = true;
		frame.refresh.link.href = form.href;
		frame.postData = jframe_encode_form(form);
		frame.postAction = jframe_setmode(form.action)
		frame.markLoading();
		if ( ! async_raw_post(frame.postAction, frame.postData, frame.onload, frame) )
		{
			// TODO something
			return false;
		}
		return true;
	};
	frame.close = function () {
		if ( frame.onclose ) frame.onclose(frame);
		document.body.removeChild(frame.root);
		return true;
	};
	
	var tbody = mktag('tbody');
	var tr = mktag('tr');
	var td = mktag('td', {}, {border: '0px none'});
	var border = mktag('div', {className: 'jframe_border'});
	
	var caption = mktag('div', {className: 'jframe_caption'}, {cursor: 'default'});
	caption.onmousedown = function (e) { return prevent(ws_start_drag(frame.root, e), e); };
	caption.appendChild(mktag('img', {src: url('img/jframe/close.png'), alt: 'X', title: 'Закрыть', align: 'right', width: 16, height: 16, onclick: prevented(frame.close)}, {marginLeft: '8px'}));
	
	frame.prev = {
		img: mktag('img', {src: url('img/jframe/prev-grey.png'), alt: '<', title: 'Назад', align: 'right', width: 16, height: 16}, {marginLeft: '5px'}),
		link: mktag('a', {href: '#', onclick: prevented(frame.goBack)})
	};
	frame.prev.link.appendChild(frame.prev.img);
	
	frame.next = {
		img: mktag('img', {src: url('img/jframe/next-grey.png'), alt: '>', title: 'Вперёд', align: 'right', width: 16, height: 16}, {marginLeft: '5px'}),
		link: mktag('a', {href: '#', onclick: prevented(frame.goNext)})
	};
	frame.next.link.appendChild(frame.next.img);
	
	frame.refresh = {
		img: mktag('img', {src: url('img/jframe/refresh.png'), alt: 'R', title: 'Обновить', align: 'right', width: 16, height: 16}, {marginLeft: '8px'}),
		link: mktag('a', {href: '#', onclick: prevented(frame.refresh)})
	};
	frame.refresh.link.appendChild(frame.refresh.img);
	
	caption.appendChild(frame.refresh.link);
	caption.appendChild(frame.next.link);
	caption.appendChild(frame.prev.link);
	
	frame.title = mktag('span');
	frame.title.appendChild(document.createTextNode('jframe'));
	caption.appendChild(frame.title);
	
	border.appendChild(caption);
	var body = frame.body = mktag('div', {className: 'jframe_container'});
	
	body.appendChild(document.createTextNode('Hello world'));
	border.appendChild(body);
	td.appendChild(border);
	tr.appendChild(td);
	tbody.appendChild(tr);
	frame.root.appendChild(tbody);
	
	return frame;
}

function jframe_open(tag, link, e)
{
	var frame = jframe_create('Loading...');
	frame.title.innerHTML = tag.innerHTML;
	frame.altLink = tag.href;
	frame.markLoading();
	frame.refresh.link.href = tag.href;
	//frame.refresh.link.alt = tag.alt;
	//frame.refresh.link.title = tag.title;
	document.body.appendChild(frame.root);
	jframe_centerize(frame);
	if ( ! async_raw_get(link, frame.onFirstLoad) )
	{
		window.location.href = tag.href;
		return false;
	}
	return prevent(true, e);
}

/**
* Разбить строку на две
*/
function split2(str, sep)
{
	var offset = str.indexOf(sep);
	return offset < 0 ? [str, ""] : [str.substr(0, offset), str.substr(offset)];
}

function jframe_setmode(link)
{
	var a = split2(link, '#');
	var b = split2(a[0], '?');
	var args = b[1] != '' ? b[1] + '&mode=ajax' : '?mode=ajax';
	return b[0] + args + a[1];
}

// центрировать фрейм в видимой области окна
function jframe_centerize(frame)
{
	var screenSize = getScreenSize();
	var frameSize = getElementSize(frame.root);
	var scroll = ws_get_scroll();
	frame.left = Math.floor( (screenSize.w - frameSize.w) / 2 ) + scroll.X;
	frame.top = Math.floor( (screenSize.h - frameSize.h) / 2 ) + scroll.Y;
	frame.root.style.left = Math.max(frame.left, scroll.X, 0) + 'px';
	frame.root.style.top = Math.max(frame.top, scroll.Y, 0) + 'px';
}

// предотватить действие по умолчанию
function prevent(Status, e)
{
	if ( Status )
	{
		if ( !e ) e = window.event;
		else {
			if ( e.stopPropagation ) e.stopPropagation(); else e.cancelBubble = true;
			if ( e.preventDefault ) e.preventDefault(); else e.returnValue = false;
		}
		return false;
	}
	return true;
}

// создать обработчик события, который предотващает действие по-умолчанию
function prevented(Action) {
	var args = new Array ();
	for(var i = 1; i < arguments.length; i++) args[i-1] = arguments[i];
	return function (e) { return prevent(Action.apply(Action, args), e); };
}

// Вернуть объект по ID
function obj(id) { return document.getElementById(id); }

// вернуть полный URL
function url(s) { return ajax_prefix + s; }

var ws_drag = false;

// начать перетаскивание фрейма
function ws_start_drag(frame, evnt) {
	var e = ! window.event ? evnt : window.event;
	ws_drag = frame;
	frame.ws.startX = e.screenX;
	frame.ws.startY = e.screenY;
	return true;
}

// завершить перетаскивание фрейма
function ws_stop_drag() {
	if ( ! ws_drag ) return false;
	ws_drag = false;
	return true;
}

// обработчик перетаскивания фреймов
document.onmousemove = function (evnt) {
	if ( ! ws_drag ) return false;
	var e = ! window.event ? evnt : window.event;
	ws_drag.ws.left += e.screenX - ws_drag.ws.startX;
	ws_drag.ws.top += e.screenY - ws_drag.ws.startY;
	ws_drag.ws.startX = e.screenX;
	ws_drag.ws.startY = e.screenY;
	ws_drag.style.left = ws_drag.ws.left + 'px';
	ws_drag.style.top = ws_drag.ws.top + 'px';
	return prevent(true, evnt);
};

// завершить перетаскивание объекта
document.onmouseup = prevented(ws_stop_drag);
