var last_pid = 0;

function Toolbar(container, poster) {
	container = $(container);
	if(!container)
		return;
	var insert = false;
	var styleAttr = $H({b:'font-weight',i:'font-style',u:'text-decoration',font:'font-family',color:'color',size:'font-size'})
	var label = $H({b: 'bold', i:'italic', u:'underline'});
	var option = $H({font: ['Arial','Verdana','Courier new','Trebuchet ms'], 
					color: ['Violet','Aqua','Blue','Green','Yellow','Orange','Red'],
					size: ['xx-small','x-small','small','medium','large','x-large','xx-large'],
					code: ['C++','Java','Pascal','PHP','HTML']});
	var text = container.innerHTML;
	var tags = text.split(',');
	var imgInput;
	container.update('');
	tags.each(addButton);

	function ImageInput(button) {
		button = $(button);
		var fname = 'x_'+Math.floor(Math.random()*1000);
		var box = $( Builder.node('form',
			{className: 'poster layer', enctype: 'multipart/form-data', target: fname, method: 'post', 
			action: 'upload.xml.php', onsubmit: 'return false;', style: 'display:none'}) );
		box.update('<span class="x_text"><label>ใส่ URL: <input type="text" class="itext" name="url" value="http://"/></label><br/>'
			+'หรือ <a href="#">อัพโหลด...</a><br/><br/><button class="x_ok">ตกลง</button></span>'
			+'<span class="x_upload" style="display:none"><label>ไฟล์: <input type="file" name="upl_image"/></label><br/>'
			+'<a href="#">ใส่ URL...</a><br/><span class="x_status"></span><br/>'
			+'<button class="x_upload">อัพโหลด</button></span>'
			+'<button class="x_cancel">ยกเลิก</button>'
			+'<iframe name="'+fname+'" src=""></iframe>');
		
		document.body.appendChild(box);

		var uploading = false;
		var ub = box.select('button.x_upload')[0],
			ob = box.select('button.x_ok')[0],
			cb = box.select('button.x_cancel')[0],
			text = box.select('span.x_text')[0],
			upload = box.select('span.x_upload')[0],
			status = box.select('span.x_status')[0],
			frame = box.select('iframe')[0],
			buttons = box.select('button');

		box.select('a').each(function(a) {
			a.onclick = function() {toggleMode(); return false;};
		});

		frame.observe('load',loaded);
		ub.observe('click',doUpload);
		ob.observe('click', function() {
			poster.coverTag('img',false,$F(box['url']));
			hide();
		});
		cb.observe('click',hide);
		
		setHover(buttons);
		
		this.show = show;

		function setStatus(s) {
			status.update(s);
			//poster.setStatus(s);
		}
		function loaded() {
			var body = $(frame.contentWindow.document.body);
			if(uploading) {
				uploading = false;
				var response = Prototype.Browser.IE ? body.innerText : body.textContent;
				var s = response.substring(0,2), url;
				frame.src='';
				if(s=='ok') {
					url = response.substring(3);
					poster.coverTag('img',false,url);
					setStatus('');
					hide();
				} else {
					setStatus('<font color="red">'+response+'</font>');
				}
				
				//box.enable();
				//poster.enable();
				
			} else {
				//
			}
		}

		function doUpload() {
			var params = box.serialize();
			
			if(!$(box['upl_image']).present()) {
				setStatus('<font color="red">เลือกรูปภาพที่ต้องการอัพโหลด</font>');//DEBUG
				return;
			}
			uploading = true;
			box.submit();
			setStatus('กำลังอัพโหลด <img src="/pictures/loading_16x16.gif"/>');
			//poster.disable();
			//box.disable();
		}
		function toggleMode() {
			text.toggle();
			upload.toggle();
			box.focusFirstElement();
		}
		function reset() {
			box.reset();
			setStatus('');
			box['url'].value = 'http://';
			if(upload.visible())
				toggleMode();
		}
		function show() {
			var offset = button.cumulativeOffset();
			x = offset.left;
			y = offset.top + button.getHeight();
			box.setStyle({left: x+'px', top: y+'px'});
			box.show();
			box.focusFirstElement();
		}
		function hide() {
			reset();
			box.hide();
		}
	}
	function addButton(cmd) {
		var b;
		cmd = cmd.toLowerCase();
		if(cmd=='|') {
			b = Builder.node('br');
		}
		else if(['font','size','color','code'].indexOf(cmd)!=-1) {
			b = $(Builder.node('select'));
			var list = option.get(cmd);
			var content = '<option selected>'+cmd+'</option>\n';
			list.each(function(s) {
				content += '<option value="'+s+'"'
					+(styleAttr.get(cmd) ? ' style="'+styleAttr.get(cmd)+':'+s+'">':'>') 
					+ s + '</option>\n';
			});
			b.onchange = function() {
				poster.coverTag(cmd, b.options[b.selectedIndex].value);
				b.selectedIndex = 0;
			};
			b.update(content);
		} else {
			b = $(Builder.node('button',{style: label.get(cmd) ? (styleAttr.get(cmd)+':'+label.get(cmd)) : ''}, cmd));
			if(cmd == 'img') {
				imgInput = new ImageInput(b);
			}
			b.observe('click', function(event) {
				if(poster.isNoSelection()) {
					if(cmd=='img') {
						imgInput.show();
					} else if(cmd=='url') {
						var arg;
						poster.coverTag(cmd,arg = prompt('ใส่ URL','http://'),prompt('ใส่ข้อความลิงค์',arg));
					} else if(cmd.substring(0,4)=='list') {
						var t, s = '';
						while(t = prompt('ใส่รายการ (เว้นว่างหรือคลิ้ก Cancel เพื่อสิ้นสุดการทำรายการ)','')) {
							s += '[*]'+t+'\n';
						}
						poster.coverTag(cmd.substring(0,4),cmd.substring(5),s);
					} else {
						var open = cmd, close = '/'+cmd;
						if(b.innerHTML.charAt(0)=='/') {
							b.update(open);
							poster.insertTag('['+close+']');
						} else {
							b.update(close);
							poster.insertTag('['+open+']');
						}
					}
				} else {
					applyTag(cmd); 
				}
			});
		}
		container.appendChild(b);
	}
	function applyTag(cmd) {
		if(['b','i','u','img','quote'].indexOf(cmd)!=-1) {
			poster.coverTag(cmd);
		} else if(cmd=='url') {
			poster.coverTag(cmd,prompt('ใส่ URL','http://'));
		} else if(cmd.substring(0,4)=='list') {
			poster.coverTag(cmd.substring(0,4),cmd.substring(5),false,function(s) {
				return s.gsub(/^(?!(\[(\*|list(=[1ai]?)?|\/list)\]|$)).+$/im,'[*]#{0}');
			});
		} else {
			poster.coverTag(cmd);
		}
	}
}

function Poster(container, action, f, lbl) {
	container = $(container);
	if(!container)
		return;
	var pid = ++last_pid;
	var inplace = container.hasClassName('inplace');
	var label = $H({show: 'ตั้งกระทู้', hide: 'ซ่อน', resume: 'เขียนต่อ'});
	var tb = container.select('.togglebutton')[0],
		sb = container.select('.submit')[0],
		rb = container.select('.reset')[0],
		status = container.select('.status')[0],
		data = container.select('.formdata')[0],
		msg = data.select('textarea')[0];
	var bar = new Toolbar(container.select('.toolbar')[0], this);
	var buttons = container.select('button');
	var preview = container.select('.preview')[0];
	var tagBar = container.select('.tagger')[0];
	var tagList = [];

	//prevent submission by enter key
	data.insert({top: Builder.node('button',{className: 'ignore', style: 'display: none'})});

	if(lbl)
		label.update(lbl);
	if(!inplace) {
		tb.update(label.get('show'));
		tb.setStyle({margin: '0px'});
	}
	data.onsubmit = function() {return false;}; //to override default action
	tb.observe('click',toggleForm);
	sb.observe('click',doPost);
	rb.observe('click',resetForm);

	if(preview) {
		var buffer = $(Builder.node('div',{style: 'display:none'}));
		container.appendChild(buffer);
		new Form.Element.Observer(msg,0.3,function(el, value) {
			buffer.update(bbcode(value, pid));
			dp.SyntaxHighlighter.HighlightAll('pcode'+pid);
			preview.update();
			$A(buffer.childNodes).each(function(o) {preview.appendChild(o);});
		});
	}

	if(tagBar) {
		var tags = tagBar.innerHTML.split(',');
		tagBar.update('<label>เลือก tag:</label> ');
		tags.each(function(tag) {
			var tagLink = $(Builder.node('span',{className: 'tag'},tag));
			tagBar.insert(tagLink);
			tagBar.insert(' ');
			tagLink.observe('click',function() { 
				if(tagLink.hasClassName('selected')) {
					tagLink.removeClassName('selected');
					removeTag(tag);
				} else {
					tagLink.addClassName('selected');
					addTag(tag);
				}
			});
		});
		var custom, ab, cList;
		tagBar.insert(cList = $(Builder.node('span')));
		tagBar.insert('<br />');
		tagBar.insert(Builder.node('label',['หรือเพิ่ม tag: ',
			custom = $(Builder.node('input', {className:'itext ignore suggest', type: 'text', name: 'custom', autocomplete:'off'}))
		]));
		tagBar.insert(ab = $(Builder.node('img', {src: 'img/tag_add.gif', title: 'เพิ่ม', alt: 'เพิ่ม', className: 'tag', style: 'vertical-align: middle'})));

		var cTags = [];
		ab.tabIndex = 0;
		ab.observe('click',addCustomTag);
		custom.observe('keydown',function(e) {
			var key = Prototype.Browser.IE ? event.keyCode : e.keyCode;
			if(key==Event.KEY_RETURN) {
				addCustomTag();
			}
		});
		//tag suggestion
		var sg = new Suggestion(custom,'tag.xml.php','<small>#{count} กระทู้</small><span class="value">#{title}</span>'
		,{item:'tag', title:'name'},addCustomTag,'a-z0-9ก-๙\-_ ');
	}

	setHover(buttons);

	//make the method public
	this.setStatus = setStatus;
	this.resetForm = resetForm;
	this.toggleForm = toggleForm;
	this.show = show;
	this.hide = hide;
	this.enable = enable;
	this.disable = disable;
	this.toString = function () {
		return container.inspect();
	};
	this.coverTag = function(tag, arg, arg2, f) {
		if(arg === null || arg2 === null) //prevent undefined == null
			return;
		f = f?f:Prototype.K;
		//format [tag=arg]f(arg2)[/tag]
		var open = '['+tag+(arg?'='+arg:'')+']', close='[/'+tag+']';
		if(Prototype.Browser.IE) {
			msg.focus();
			var r = document.selection.createRange();
			var r2 = r.duplicate();
			var text = f(arg2 ? arg2 : r.htmlText);
			if(text!=null)
				r.text = open + f(text) + close;
			
			r2.setEndPoint('EndToEnd',r);
			r2.select();
		} else {
			var start = msg.selectionStart;
			var end = msg.selectionEnd;
			var text = f(arg2 ? arg2 : msg.value.substring(start,end));
			
			if(text!=null) {
				msg.value = msg.value.substring(0,start) + open + text + close 
					+ msg.value.substring(end,msg.value.length);
				end = start + open.length + text.length + close.length;
			}

			msg.setSelectionRange(start,end);
			msg.focus();
		}
	};
	this.insertTag = function(tag) {
		if(Prototype.Browser.IE) {
			msg.focus();
			var r = document.selection.createRange();
			r.collapse(false);
			r.text = r.htmlText+tag;
			r.collapse(false);
			r.select();		
		} else {
			var end = msg.selectionEnd;
			msg.value = msg.value.substring(0,end) 
				+ tag
				+ msg.value.substring(end,msg.value.length);
			var endAfter = end + (tag).length;
			msg.setSelectionRange(endAfter,endAfter);
			msg.focus();
		}
	};
	this.isNoSelection = function() {
		if(Prototype.Browser.IE) {
			msg.focus();
			return document.selection.createRange().htmlText.length=='';
		} else {
			return msg.selectionStart == msg.selectionEnd;
		}
	};
	this.addToggleButton = function(button) {
		button = $(button);
		button.update(label.get('show'));
		button.observe('click',function() {
			setStatus('');
			if(!data.visible()){
				data.show();
				tb.update(label.get('hide'));
				data.focusFirstElement();
			}
			tb.scrollTo();
		});
		setHover([button]);
	};
	function doPost() {
		var params = data.serialize();
		disable();
		if(!validate()) {
			setStatus('กรุณากรอกข้อความให้่ครบ');
			enable();
			return;
		}
		setStatus('');
		new Ajax.Request(action, {
				onComplete: function(output) {
					f(output);
					enable();
				},
				parameters: params+'&tag='+tagList.join(',')
			});
	}
	function validate() {
		return data.select('input[type="text"]:not(.ignore)').concat(msg).invoke('present').all();
	}
	function disable() {
		buttons.each(function(b) {
			b.disabled = true;
		});
		buttons.invoke('addClassName','dis');
		data.disable();
	}
	function enable() {
		buttons.invoke('removeClassName','dis');
		buttons.each(function(b) {
			b.disabled = false;
		});
		data.enable();
	}
	function resetForm() {
		data.reset();
		setStatus('');
		if(tagBar) {
			cTags.clear();
			tagList.clear();
			tagBar.select('span.tag').invoke('removeClassName','selected');
			cList.update();
			sg.clear();
		}
	}
	function setStatus(s) {
		if(s=='')
			status.hide();
		else {
			status.update(s);
			status.show();
		}
	}
	function show() {
		setStatus('');
		data.show();
		if(inplace) {
			container.scrollTo();
		} else {
			tb.update(label.get('hide'));
			tb.scrollTo();
		}
		data.focusFirstElement();
	}
	function hide() {
		setStatus('');
		data.hide();
		if(msg.present()) {
			setStatus('ยังมีข้อความค้างอยู่ ต้องการลบทิ้งหรือไม่? <button class = "tmp">ใช่</button>');
			var tmp = container.select('.tmp')[0];
			setHover([tmp]);
			tmp.onclick = function() {tb.update(label.get('show')); resetForm()};
			tb.update(label.get('resume'));
		} else {
			tb.update(label.get('show'));
		}
	}
	function toggleForm() {
		data.visible()?hide():show();
	}
	//tag (not bbcode)
	function addTag(tag) {
		tagList.push(tag);
	}
	function removeTag(tag) {
		tagList = tagList.without(tag);
	}
	function addCustomTag() {
		var tag = custom.value.strip().toLowerCase().gsub(' ','-').gsub(/[^a-z0-9ก-๙\-_]/,'');
		custom.clear();

		if(tags.include(tag) || cTags.include(tag) || tag.empty())
			return;
		cTags.push(tag);

		var tmp = $(Builder.node('span',{className: 'tag selected'},tag));
		cList.insert(tmp);
		tmp.observe('click',function() { cTags = cTags.without(tag); removeTag(tag); tmp.remove();	});
		addTag(tag);
	}
}
