
function IsAlph(chr) { return (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z'); }

function BBCode(params) {
	if (!params) params = {}; // if empty mast by defined late
	this.editor = params['editor'];
	this.preview = params['preview'];
	this.msg = params['msg'] ? params['msg'] : {
		text_enter_url 		: "Введите полный путь ссылки",
		text_enter_url_name : "Введите название",
		text_enter_image 	: "Введите полный путь изображения",
		text_enter_email 	: "Введите e-mail адресс",
		error_no_url 		: "Вы должны ввести ссылку",
		error_no_title 		: "Вы должны ввести название",
		error_no_email 		: "Вы должны ввести e-mail адресс",
		prompt_start 		: "Введите текст",
		list_prompt 		: "Введите строку списка. Для завершения, нажмите 'отменить' или оставте следующее поле пустым"
	};

	this.opened = {B:0, I:0, U:0};
	this.bbtags = [];
	
	this.doScan = function (text) {
		var new_text = '';
		var st = 0;
		var tag = '';
		var rt = 0;
		var a = [];
		var c = text.charAt(0);
		for(var i=0; i<text.length; i++, c=text.charAt(i)) {
			new_text+=c;
			switch (st) {
				case 0: if (c=='[') st=1; break;
				case 1: if (c=='/') st=3; else if (IsAlph(c)) { st = 2; tag += c; } else st=0; break;
				case 2: if (c==']') st=5; else if (IsAlph(c)) tag+=c; else st=7; break;
				case 3: if (IsAlph(c)) {st=4; tag+=c;} else st=0; break;
				case 4: if (IsAlph(c)) tag+=c; else if (c==']') st=6; else {st=0;tag="";} break; 
				case 7: if (c==']') st=5; break;
				default: if (c=='[') st=1; else st=0;
			}
			if (st==5) {
				if (rt==0) a.push(tag);
				tag=""; st=0;
			} else if (st==6) {
				if (rt==0)
					while ((t = a.pop()) && t.toLowerCase() != tag.toLowerCase())
						new_text = new_text.substring(0, new_text.length - tag.length - 1)+t+"][/"+tag+"]";
				tag="";st=0;
			}
		}
		while (tag = a.pop()) new_text += "[/"+tag+"]";
		return new_text;
		return text;
	}

	this.doInsert = function (tag, endTag, isSingle) {
		var isClose = false;
		if (document.selection) {
			this.editor.focus();
			var sel = document.selection;
			var rng = sel.createRange();
			rng.colapse;
			if ((sel.type == "Text" || sel.type == "None") && rng != null){
				if (endTag != "" && rng.text.length > 0) 
					tag += rng.text + endTag;
				else if (isSingle) 
					isClose = true;
				rng.text = tag;
			}
		} else if (this.editor.selectionStart || this.editor.selectionStart == '0') {
			if (endTag != "" && this.editor.selectionStart != this.editor.selectionEnd) 
				tag += this.editor.value.substring(this.editor.selectionStart, this.editor.selectionEnd) + endTag;
			else if (isSingle) 
				isClose = true;

			this.editor.value = 
				this.editor.value.substring(0, this.editor.selectionStart) + tag + 
				this.editor.value.substring(this.editor.selectionEnd, this.editor.value.length);
		} else {
			if(isSingle) isClose = true;
			this.editor.value += tag;
		}
		this.editor.focus();
		return isClose;
	}
	
	this.doSimpleTag = function(btn, tag) {
		if (this.opened[tag]) {
			for (var i = this.bbtags.length - 1; i >= 0 ; i-- )
				if (this.bbtags[i] == tag ) {
					while(this.bbtags[i]) {
						tag = this.bbtags.pop();
						this.doInsert("[/"+tag+"]", "", false);
						if (this.opened[tag]) {
							this.doBtnUp(this.opened[tag]);
							this.opened[tag] = 0;
						}
					}
					break;
				}			
		} else {
			if (this.doInsert("[" + tag + "]", "[/" + tag + "]", true)) {
				this.bbtags.push(tag);
				this.doBtnDown(this.opened[tag] = btn);
			} else
				this.doBtnUp(btn);
		}
	}
	
	this.doBtnUp = function(btn) {
		btn.src = btn.src.replace(/_p\.gif$/, "_n.gif");
	}

	this.doBtnDown = function(btn) {
		btn.src = btn.src.replace(/_n\.gif$/, "_p.gif");
	}
	
	// public
	this.B = function(btn) {
		this.doSimpleTag(btn, 'B');
	}
	
	this.I = function(btn) {
		this.doSimpleTag(btn, 'I');
	}
	
	this.U = function(btn) {
		this.doSimpleTag(btn, 'U');
	}
	
	this.Color = function(btn, color) {
		if (this.doInsert("[COLOR="+color+"]", "[/COLOR]", true))
			this.bbtags.push('COLOR');
		if (btn.tagName == 'SELECT') btn.selectedIndex = 0;
	}
	
	this.Href = function(btn) {
		var errors = '';
	    var url    = prompt(this.msg.text_enter_url, "http://");
	    var title  = prompt(this.msg.text_enter_url_name, url);
		if (!url) errors += "\n" + this.msg.error_no_url;
	    if (!title) errors += "\n" + this.msg.error_no_title;
	    if (!errors) this.doInsert("[URL="+url+"]"+title+"[/URL]", "", false);	
		else alert("Error!" + this.msg.error_no_url);
	}
	
	this.Img = function(btn) {
	    var url = prompt(this.msg.text_enter_image, "http://");
		if (url) this.doInsert("[IMG]"+url+"[/IMG]", "", false);
		else alert("Error!\n"+this.msg.error_no_url);
	}
	
	this.Email = function(btn) {
		var email = prompt(this.msg.text_enter_email, "");
		if (email) this.doInsert("[EMAIL]" + email + "[/EMAIL]", "", false);
		else alert("Error!\n"+this.msg.error_no_email);
	}
	
	this.List = function(btn, num) {
		var listvalue = "init";
		var thelist = "";
		while ((listvalue != "") && (listvalue != null)) {
			listvalue = prompt(this.msg.list_prompt, "");
			if ((listvalue != "") && (listvalue != null))
				thelist = thelist + "[*]" + listvalue + "\n";
		}
		if (thelist != "")
			this.doInsert( "[LIST"+( num ? "=1" : "" )+"]\n" + thelist + "[/LIST]\n", "", false);
	}
	
	this.CloseAll = function(btn) {
		while (this.bbtags[0]) {
			tag = this.bbtags.pop();
			this.editor.value += '[/' + tag + ']';
			if (this.opened[tag]) {
				this.doBtnUp(this.opened[tag]);
				this.opened[tag] = 0;
			}
		}
		this.editor.value = this.doScan(this.editor.value);
	}
}

function bbmOver(obj) {obj.style.background = '#D8D8D8';}
function bbmOut(obj) {obj.style.background = '';}

