/**
 * @author:		Angelo Dini
 * @copyright	CORESHOCK - coreshock.ch
 * @requires	MooTools Core, Element.Forms
 */

var WYSIWYG = new Class({
	
	Implements: [Options, Events],
	
	options: {
		preset: 'all',
		actions: 'bold italic underline | orderedlist unorderedlist | indent outdent | textalignleft textaligncenter textalignright textalignjustify | link color | image imgalignleft imgaligncenter imgalignright | upload quote code | table tablerow tablecol | smilies reset',
		trans: {
			smaller: 'Make window smaller',
			bigger: 'Make window bigger',
			list: 'Define list items. Press "Cancel" when finished.',
			linktext: 'Text (optional)',
			imgpath: 'Image path',
			imgpotions: 'Align',
			imgealign: 'Please select image range from [img] to [/img]',
			rows: 'How many ROWS do you need?',
			cols: 'How many COLUMNS do you need?',
			confirm: 'confirm',
			upload: 'Upload',
			assistant: 'Do you want to use the assistant?',
			align: 'none',
			left: 'Left',
			center: 'Center',
			right: 'Right'
		},
		resize: 50,
		greyscale: ['000000', '333333', '808080', '999999', 'c0c0c0', 'ffffff'],
		colorscale: ['ffff99', 'ffff00', 'ffcc00', 'ff9900', 'ff6600', 'ff0000 ', '339966', '00ff00', 'ccffcc', '00ffff', '00ccff', '99ccff', '3366ff', '990099', '993366', 'cc99ff', 'ff99cc', 'ff00ff'],
		smilies: ['smilie', 'wink', 'razz', 'cool', 'eek', 'crying', 'grin', 'lol', 'yell', 'red', 'neutral', 'roll', 'surprised', 'confused', 'sad', 'mad', 'devil', 'twist', 'fat', 'thin', 'small', 'drawing', 'mr-green', 'thumb-up', 'thumb-down']
	},
	
	initialize: function (el, options) {
		this.container = $(el);
		this.setOptions(options);
		
		this.textarea = this.container.getElement('textarea');
		this.bbcodes = new Hash(WYSIWYG.Codes);
		
		// render toolbar
		this.render();
		// attach events to buttons
		this.events();
	},
	
	render: function () {
		// render resize
		var sizeContainer = new Element('div', { 'class': 'size' });
			new Element('a', { 'href': '#', 'class': 'smaller', 'html': this.options.trans.smaller }).inject(sizeContainer);
			new Element('a', { 'href': '#', 'class': 'bigger', 'html': this.options.trans.bigger }).inject(sizeContainer);
		sizeContainer.inject(this.textarea, 'before');
		
		// render toolbar
		var toolbar = new Element('ul', { 'class': 'toolbar' });
		toolbar.inject(this.textarea, 'before');
		
		// load presets
		this.presets();
		
		// render buttons
		this.presets = this.actions.clean().split(' ');
		this.presets.each(function (item, index) {
			if(item == '|') {
				new Element('li', { 'class': 'break' }).inject(toolbar);
			} else {
				if(item == 'reset') {
					var li = new Element('li', { 'style': 'float:right !important; margin-right:16px;' });
				} else {
					var li = new Element('li');
				}
				var a = new Element('a', { 
					'href': '#', 
					'class': item,
					'style': 'background-image:url("http://www.squarejunkies.com/gfx/wysiwyg/buttons/' + item + '.png");',
					'title': this.bbcodes.get(item).title,
					'html': this.bbcodes.get(item).title
				});
				// inject
				li.adopt(a).inject(toolbar);
			}
			
		}, this);
	},
	
	presets: function () {
		switch (this.options.preset) {
			case 'site':
				this.actions = 'bold italic underline | textalignleft textaligncenter | link | image | upload | smilies reset';
				break;
			case 'reply':
				this.actions = 'bold italic underline | orderedlist unorderedlist | textalignleft textaligncenter textalignright | link color | image | upload quote code | smilies reset';
				break;
			default:
				this.actions = this.options.actions;
		}
	},
	
	events: function () {
		this.toolbar = this.container.getElement('.toolbar');
		
		// buttons
		this.buttons = this.toolbar.getElements('a');
		this.buttons.each(function (item, index) {
			item.addEvent('click', this.allocate.bindWithEvent(this, item));
		}, this);
		
		// resize
		this.height = this.textarea.getSize().y;
		var triggers = this.container.getElements('.size a');
		triggers[0].addEvent('click', this.resize.bindWithEvent(this, true));
		triggers[1].addEvent('click', this.resize.bindWithEvent(this, false));
	},
	
	allocate: function (event, anchor) {
		event.stop();
		this.rel = anchor.get('class');
		this.codeArray = this.bbcodes.get(this.rel).code.split('::');
		
		switch (this.rel) {
			case 'orderedlist':
				this.implementList();
				break;
			case 'unorderedlist':
				this.implementList();
				break;
			case 'color':
				this.implementColor();
				break;
			case 'link':
				this.implementLink();
				break;
			case 'image':
				this.implementImage();
				break;
			case 'imgalignleft':
				this.implementImageAlign('left');
				break;
			case 'imgaligncenter':
				this.implementImageAlign('center');
				break;
			case 'imgalignright':
				this.implementImageAlign('right');
				break;
			case 'upload':
				this.implementUpload();
				break;
			case 'smilies':
				this.implementSmilies();
				break;
			case 'table':
				this.implementTable();
				break;
			case 'reset':
				this.dispose();
				break;
			default:
				this.implement();
		}
	},
	
	implement: function () {
		// inject
		this.selection = this.textarea.getSelectedText();
		if(this.selection != '') {
			this.textarea.insertAroundCursor({
				before: this.codeArray[0],
				after: this.codeArray[1]
			});
		} else {
			this.textarea.insertAtCursor(this.codeArray[0] + this.codeArray[1]);
		}
		
		// set focus back to textarea
		this.focus();
	},
	
	implementList: function () {
		var list, tmp;
		var items = [];
		do {
			tmp = prompt(this.options.trans.list, '');
			if(tmp != '' && tmp != null) items.push(tmp);
		} while (tmp != null);
		
		// create list
		list = this.codeArray[0] + '\n';
		items.each(function (item) {
			list += '\t[*]' + item + '\n';
		});
		list += this.codeArray[1] + '\n';
		
		// inject
		this.textarea.insertAtCursor(list);
		
		// set focus back to textarea
		this.focus();
	},
	
	implementLink: function () {
		// prevent multiple infobars
		this.dispose();
		
		// define content
		var html = '';
		html += '<span>http://</span>';
		html += '<input type="text" class="editor-href" />';
		html += '<span>&nbsp;</span><span>' + this.options.trans.linktext + ':</span>';
		html += '<input type="text" class="editor-text" />';
		html += '<span>&nbsp;</span><a href="#">' + this.options.trans.confirm + '</a>';
		
		// show bar
		this.infobar(html);
		
		// set focus when opening
		var container = this.container.getElement('.infobar');
		container.getElement('.editor-href').focus();
		
		// add event functionality
		container.getElement('a').addEvent('click', function () {
			var href = container.getElement('.editor-href').get('value');
			var text = 	container.getElement('.editor-text').get('value');
			var tmp = '';
			
			(text != '') ? (tmp += this.codeArray[0]) : (tmp += this.codeArray[0].replace('=', ''));
			if(text != '') tmp += ('http://' + href);
			tmp += this.codeArray[1];
			(text != '') ? (tmp += text) : (tmp += ('http://' + href));
			tmp += this.codeArray[2];
			
			// inject
			this.textarea.insertAtCursor(tmp);
			
			// close element
			this.dispose();
			
			// set focus back to textarea
			this.focus();
			
			return false
		}.bind(this));
	},
	
	implementColor: function () {
		// prevent multiple infobars
		this.dispose();
		
		// define colors
		var greyscale = this.options.greyscale;
		var colorscale = this.options.colorscale;
		
		// define content
		var html = '';
		greyscale.each(function (item) {
			html += '<a href="#" class="color"><span style="background:#' + item + ';">&nbsp;</span></a>';
		});
		html += '<span style="float:left; padding:0 10px;">&nbsp;</span>';
		colorscale.each(function (item) {
			html += '<a href="#" class="color"><span style="background:#' + item + ';">&nbsp;</span></a>';
		});
		
		// show bar
		this.infobar(html);

		// add event functionality
		this.container.getElement('.infobar').getElements('.color').each(function (item) {
			item.addEvent('click', function () {
				var color = item.getElement('span').getStyle('background-color');
				color = color.replace('#', '');
				
				var tmp = '';
				tmp += this.codeArray[0];
				tmp += color;
				tmp += this.codeArray[1];

				// inject
				this.textarea.insertAroundCursor({
					before: tmp,
					after: this.codeArray[2]
				});
				
				// close element
				this.dispose();
				
				return false;
			}.bind(this));
		}, this);

	},
	
	implementImage: function () {
		// prevent multiple infobars
		this.dispose();
		
		// define content
		var html = '';
		html += '<span>' + this.options.trans.imgpath + ':</span>';
		html += '<input type="text" class="editor-img" />';
		html += '<span>&nbsp;</span><span>' + this.options.trans.imgpotions + ':</span>';
		html += '<select name="">';
		html += '<option value="">' + this.options.trans.align + '</option>';
		html += '<option value="left">' + this.options.trans.left + '</option>';
		html += '<option value="center">' + this.options.trans.center + '</option>';
		html += '<option value="right">' + this.options.trans.right + '</option>';
		html += '</select>';
		html += '<span>&nbsp;</span><a href="#">' + this.options.trans.confirm + '</a>';
		
		// show bar
		this.infobar(html);
		
		// set focus when opening
		var container = this.container.getElement('.infobar');
		container.getElement('.editor-img').focus();

		// add event functionality
		container.getElement('a').addEvent('click', function () {
			var path = container.getElement('.editor-img').get('value');
			var option = container.getElement('select').getSelected().get('value');
			var tmp = '';
			
			(option != '') ? (tmp += this.codeArray[0]) : (tmp += this.codeArray[0].replace(' align=', ''));
			if(option != '') tmp += option;
			tmp += this.codeArray[1];
			tmp += path;
			tmp += this.codeArray[2];
			
			// inject
			this.textarea.insertAtCursor(tmp);
			
			// close element
			this.dispose();
			
			// set focus back to textarea
			this.focus();
			
			return false;
		}.bind(this));
	},
	
	implementImageAlign: function (type) {
		var text = this.textarea.getSelectedText();
		if(text == '') {
			alert(this.options.trans.imgealign);
		} else {
			text = text.replace(' align=left', '');
			text = text.replace(' align=center', '');
			text = text.replace(' align=right', '');
			text = text.replace('[img]', '[img align=' + type + ']');
			
			// inject
			this.textarea.insertAtCursor(text);
			
			// set focus back to textarea
			this.focus();
		}
	},
	
	implementSmilies: function () {
		// prevent multiple infobars
		this.dispose();

		// define colors
		var smilies = this.options.smilies;
		
		// define content
		var html = '';
		smilies.each(function (item) {
			html += '<a href="#" class="smilie"><img src="' + '/media/smilies/' + item + '.gif' + '" alt="" title="' + item + '"></a>';
		}, this);
		
		// show bar
		this.infobar(html);
		
		// add event functionality
		this.container.getElement('.infobar').getElements('.smilie').each(function (item) {
			item.addEvent('click', function () {
				var smilie = item.getElement('img').get('title');
				var tmp = ':' + smilie + ':';

				// inject
				this.textarea.insertAtCursor(tmp);
				
				// close element
				this.dispose();
				
				return false;
			}.bind(this));
		}, this);
	},
	
	implementTable: function () {
		var assistant = confirm(this.options.trans.assistant);
		if(assistant) {
			// define rows
			var rows = prompt(this.options.trans.rows);
			if(rows == null || rows == '') rows = '';
			// define cols
			var cols = prompt(this.options.trans.cols);
			if(cols == null || cols == '') cols = '';
			
			// define content
			var tmp = '';
			tmp += this.codeArray[0] + '\n'; // table start
			for(var i = 0; i < rows; i++) {
				tmp += '\t[row]\n';
				for(var x = 0; x < cols; x++) {
					tmp += '\t\t[col][/col]\n';
				}
				tmp += '\t[/row]\n';
			}
			tmp += this.codeArray[1] + '\n'; // table end

			// inject
			this.textarea.insertAtCursor(tmp);
		} else {
			// forward to default
			this.implement();
		}
	},
	
	implementUpload: function (input) {
		// close element
		this.dispose();
		
		var html = '&nbsp;&nbsp;<a href="#" id="attach-trigger" style="position:relative; left:0; top:2px;">Attach a file</a>';
		html += '<a href="#" id="attach-trigger-2" style="display: none; position:relative; left:0; top:2px;">Attach another file</a>';
		
		// show bar
		this.infobar(html);
		// inject list
		new Element('ul', { 'id': 'attachbar', 'html': input }).inject(this.container);

		var up = new FancyUpload3.Attach('attachbar', '#attach-trigger, #attach-trigger-2', {
			path: '/js/Swiff.Uploader.swf',
			url: '/ajax/upload/images/news/',
			fileSizeMax: 100 * 1024 * 1024,
			
			verbose: true,
			
			onSelectFail: function(files) {
				files.each(function(file) {
					new Element('li', {
						'class': 'file-invalid',
						events: {
							click: function() {
								this.destroy();
							}
						}
					}).adopt(
						new Element('span', {html: file.validationErrorMessage || file.validationError})
					).inject(this.list, 'bottom');
				}, this);	
			},
			
			onFileSuccess: function(file) {
				new Element('input', {type: 'checkbox', 'checked': true}).inject(file.ui.element, 'top');
				file.ui.element.highlight('#e6efc2');
			},
			
			onFileError: function(file) {
				file.ui.cancel.set('html', 'Retry').removeEvents().addEvent('click', function() {
					file.requeue();
					return false;
				});
				
				new Element('span', {
					html: file.errorMessage,
					'class': 'file-error'
				}).inject(file.ui.cancel, 'after');
			},
			
			onFileRequeue: function(file) {
				file.ui.element.getElement('.file-error').destroy();
				
				file.ui.cancel.set('html', 'Cancel').removeEvents().addEvent('click', function() {
					file.remove();
					return false;
				});
				
				this.start();
			}
			
		});		
		

		// inject upload field
		
		/*
		upload_field.inject($E('.infobar'));
		
		var container = this.container.getElement('.infobar');
		container.getElement('a').addEvent('click', function () {
			// save value
			var value = container.getElement('input').get('value');
			
			if(value != '') {
				//$('upload_field').set('value', value);
				
				console.log($('upload_field'));
				
				
				
				
				new Request({
					method: 'post',
					url: '/ajax/upload/images/news/',
					headers: {'Content-Type': 'multipart/form-data'},
					onRequest: function () {
						container.set('html', '<span>loading...</span>');
					},
					onCancel: function () {
						html += '<span>&nbsp;</span><span style="color:#f00;">loading failed</span>';
						this.dispose();
						alert('Upload Failed!');
					},
					onComplete: function () {
						container.set('html', '<span><strong>loading complete</strong></span>');
						this.loadAttachments(value);
					}
				}).send('image=' + $('upload_field').value);
			}
			
			// loading
			*/
			
			/*
			container.set('html', '<span>loading...</span>');
			
			// do request
			(value == '') ? (request = false) : (request = true);
			
			(function () {
				if(request) {
					container.set('html', '<span><strong>loading complete</strong></span>');
					this.loadAttachments(value);
				} else {
					html += '<span>&nbsp;</span><span style="color:#f00;">loading failed</span>';
					this.dispose();
					alert('Upload Failed!');
				}
			}).bind(this).delay(1000);
			*/
			
			//return false;
		//}.bind(this));
		
		// inject
		//this.textarea.insertAtCursor(tmp);
	},
	
	infobar: function (html) {
		new Element('div', {
			'class': 'infobar',
			'html': html
		}).inject(this.toolbar, 'after');
	},
	
	dispose: function () {
		if(this.container.getElement('.infobar')) this.container.getElement('.infobar').dispose();
		if(this.container.getElement('#attachbar')) this.container.getElement('#attachbar').dispose();
	},
	
	focus: function () {
		this.textarea.focus();
	},
	
	resize: function (event, state) {
		event.stop();
		var size = this.textarea.getSize().y;
		if(state) {
			if(size > this.height) this.textarea.setStyle('height', (size - this.options.resize));
		} else {
			this.textarea.setStyle('height', (size + this.options.resize));
		}
	}
	
});

WYSIWYG.Codes = {
	"bold": { title: "Bold", code: "[b]::[/b]", tag: "<strong>::</strong>" },
	"italic": { title: "Italic", code: "[i]::[/i]", tag: "<em>::</em>" },
	"underline": { title: "Underline", code: "[u]::[/u]", tag: "<span class=\"underline\">::</span>" },
	
	"orderedlist": { title: "Insert Ordered List", code: "[ol]::[/ol]", tag: "<ol>::</ol>" },
	"unorderedlist": { title: "Insert Unordered List", code: "[ul]::[/ul]", tag: "<ul>::</ul>" },

	"indent": { title: "Indent", code: "[indent]::[/indent]", tag: "<span class=\"indent\">::</span>" },
	"outdent": { title: "Outdent", code: "[outdent]::[/outdent]", tag: "<span class=\"outdent\">::</span>" },

	"textalignleft": { title: "Align Left", code: "[text=left]::[/text]", tag: "<p class=\"align-left\">::</p>" },
	"textaligncenter": { title: "Alight Center", code: "[text=center]::[/text]", tag: "<p class=\"align-center\">::</p>" },
	"textalignright": { title: "Align Right", code: "[text=right]::[/text]", tag: "<p class=\"align-right\">::</p>" },
	"textalignjustify": { title: "Align Justify", code: "[text=justify]::[/text]", tag: "<p class=\"align-justify\">::</p>" },
	
	"link": { title: "Insert Link", code: "[url=::]::[/url]", tag: "<a href=\"::\">::</a>" },
	"color": { title: "Insert Color", code: "[color=::]::[/color]", tag: "<span style=\"::\">::</span>" },

	"image": { title: "Insert Image", code: "[img align=::]::[/img]", tag: "<img src=\"::\" alt=\"::\" /></span>" },
	"imgalignleft": { title: "", code: "[img align=left]::[/img]", tag: "<img src=\"::\" alt=\"::\" class=\"img-left\" /></span>" },
	"imgaligncenter": { title: "", code: "[img align=center]::[/img]", tag: "<img src=\"::\" alt=\"::\" class=\"img-center\" /></span>" },
	"imgalignright": { title: "", code: "[img align=right]::[/img]", tag: "<img src=\"::\" alt=\"::\" class=\"img-right\" /></span>" },
	
	"upload": { title: "", code: "::", tag: "::" },
	"quote": { title: "", code: "[quote]::[/quote]", tag: "<blockquote>::</blockquote>" },
	"code": { title: "", code: "[code]::[/code]", tag: "<code>::</code>" },

	"table": { title: "Create Table", code: "[table]::[/table]", tag: "<table border=\"0\" width=\"100%\">::</table>" },
	"tablerow": { title: "Insert Row", code: "[row]::[/row]", tag: "<tr>::</tr>" },
	"tablecol": { title: "Insert Col", code: "[col]::[/col]", tag: "<td>::</td>" },

	"smilies": { title: "Insert Smilie", code: "::", tag: "::" },
	
	"reset": { title: "Close all open editor tasks.", code: "::", tag: "::" }
};
