//    Copyright © Matt Vogel DBA Portland Web Development,
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
var Selecto = new Class({
	Implements: [Options, Events],
	options: {
		size:72
	},
	initialize: function(options){
		this.setOptions(options);
		this.targetDiv.inject(document.body);
		var newLine = new Element('div', {
			styles:{
				'clear':'left',
				height: this.options.size +'px',
				'white-space':'nowrap'
			},
			'class':'line'
		});
		this.size = this.options.size;
		newLine.inject(this.targetDiv);
		this.cursor.inject(newLine);
		this.cursor.animate()
	    .morph({'background-color':'#000','width':'10px','height':this.options.size + 'px','border':'3px dotted magenta'})
	    .delay(100)
	    .morph({'background-color':'#F0F','width':'1px','height':'10px','border':'0px solid black'})
	    .repeat().start();
		this.letterMeasurer.style.fontSize = this.options.size + 'px';
		this.letterMeasurer.inject($('textarea'));
	},
	selector: new Element('div', {
		id: 'selector',
		styles: {
			'border':'2px solid black',
			'height':this.size + 'px',
			'float':'left'
		}
	}),
	cursor: new Element('div', {
		id: 'cur',
		styles: {
			'border':'0px solid black',
			'width':'1px',
			'height':this.size + 'px',
			'float':'left'

		}
	}),
	letterMeasurer: new Element('span', {
		styles: {
			'font-size': this.size + 'px',
			'visibility':'hidden'
		}
	}),
	setMouseUp: function(el){

		return;
		mouseupel = el;
		this.selector.wraps(el.getNext());
		mouseupel = 0; 
		mousedownel = 0;
	},
	setMouseDown: function(el){
		if(this.selector.length>0){
			this.selector.inject($('selector').getChildren(),'after');
		}
		mousedownel = el;

	},
	text: {'line':[{'char':[]}]},
	html: {'line':[{'charHTML':[{'hotArea':{'left':'','right':''},'char':'','width':''}]}]},
	mouseupel: '',
	mousedownel: '',
	curLine: 0,
	curChar: 0,
	size: 72,
	targetDiv: new Element('div',{'id':'textarea'}),
	newLine: function(){
		
		
		
		if(this.cursor.getAllNext(".letter").length>0) {
			itemsToInject = this.cursor.getAllNext();
			this.cursor.inject(this.html.line[this.curLine].container);
			itemsToInject.inject(this.cursor,"after");
		}else{
			this.cursor.inject(this.html.line[this.curLine].container);
		}
		
		
		return;
	},
	newLine: function() {
		new Element('div', {
			styles:{
				'clear':'left',
				height: this.size +'px',
				'white-space':'nowrap'
			},
			events : {
				'click': function(e){
					if(this.cursor.getParent('div.line').getChildren('span.letter').length >0)return;
					this.cursor.inject(e.target);
				}.bind(this)
			},
			'class':'line'
		}).inject(this.cursor.getParent("div.line"),'after');
		
		this.cursor.getParent('div.line').getNext('div.line').adopt(this.cursor.getAllNext());
		this.cursor.inject(this.cursor.getParent('div.line').getNext('div.line'),'top');
	},
	doKeyDown: function(e){
		e.stop();

		if(e.key=='enter'){
			this.newLine();

		}else if(e.key=='backspace'){
			
			if(!$chk(this.cursor.getPrevious('span'))){
				if(!$chk(this.cursor.getParent('div.line').getPrevious('div.line')))return;
				if(!$chk(this.cursor.getParent('div.line').getPrevious('div.line').getFirst("span"))){this.cursor.getParent('div.line').getPrevious('div.line').dispose();return;}
			}
			if(!$chk(this.cursor.getPrevious())){
				
				this.cursor.inject(this.cursor.getParent("div.line").getPrevious("div.line"),'bottom');
				this.cursor.getParent('div.line').adopt(this.cursor.getParent('div.line').getNext('div.line').getChildren());
				return;
			}
			//delete char
			this.cursor.getPrevious("span").dispose();
			if(this.cursor.getPrevious("div").className=='line'){
				this.cursor.getPrevious("div").dispose();
			}else{
				this.cursor.getPrevious("div").dispose();
				this.cursor.getPrevious("div").dispose();
			}
		}else if(e.key=='delete'){
			if(!$chk(this.cursor.getNext('span.letter'))){
				if(!$chk(this.cursor.getParent('div.line').getNext('div.line'))){
					return;
				}else{
					if(this.cursor.getParent('div.line').getNext('div.line').getChildren('span.letter').length==0){
						this.cursor.getParent('div.line').getNext('div.line').dispose();
						return;
					}else{
						this.cursor.getParent('div.line').adopt(this.cursor.getParent('div.line').getNext('div.line').getChildren('span.letter'));
						this.cursor.getParent('div.line').getNext('div.line').dispose();
						return;
					}
				}
				
			}else{
				this.cursor.getNext("span").dispose();
				if(this.cursor.getNext("div").className=='line'){
					this.cursor.getNext("div").dispose();
				}else{ 
					this.cursor.getNext("div").dispose();
					this.cursor.getNext("div").dispose();
				}
			}
			
		}else if(e.key=='up'){
			this.cursor.inject(
					$chk(this.cursor
						.getParent('div.line')
						.getPrevious("div.line")
						.getChildren('span.letter')[this.cursor.getAllPrevious("span.letter").length]) ? 
								this.cursor
								.getParent('div.line')
								.getPrevious('div.line')
								.getChildren('span.letter')[this.cursor.getAllPrevious("span.letter").length] :
								this.cursor
								.getParent('div.line')
								.getPrevious('div.line')
					,$chk(this.cursor
							.getParent('div.line')
							.getPrevious("div.line")
							.getChildren('span.letter')[this.cursor.getAllPrevious("span.letter").length]) ? 'before' : 'bottom');
		}else if(e.key=='down'){
			this.cursor.inject(
					$chk(this.cursor
						.getParent('div.line')
						.getNext("div.line")
						.getChildren('span.letter')[this.cursor.getAllPrevious("span.letter").length]) ? 
								this.cursor
								.getParent('div.line')
								.getNext('div.line')
								.getChildren('span.letter')[this.cursor.getAllPrevious("span.letter").length] :
								this.cursor
								.getParent('div.line')
								.getNext('div.line')
					,$chk(this.cursor
							.getParent('div.line')
							.getNext("div.line")
							.getChildren('span.letter')[this.cursor.getAllPrevious("span.letter").length]) ? 'before' : 'bottom');
		}else if(e.key=='right'){
			this.cursor.inject(this.cursor.getNext("div .left"),'after');
		}else if(e.key=='left'){
			this.cursor.inject(this.cursor.getPrevious("span"),'before');
		}else if(e.alt){

		}else if (e.code==35){
			this.cursor.inject(this.cursor.getParent('div.line'),'bottom');
		}else if (e.code==36){
			this.cursor.inject(this.cursor.getParent('div.line'),'top');
		}else if (e.code==116){
			window.location.href = unescape(window.location.pathname);
		}else{
			
	        var key = {
	        	9:'&nbsp;&nbsp;&nbsp;&nbsp;',
	        	188:'&#44;',
	        	222:'&#39;',
	        	190:'&#46;'
	        	
	        };
	        e.key = $chk(key[e.code]) ? key[e.code] : e.key; 
			if(e.key=='space')e.key = '&nbsp;';
			if(e.code==188)e.key = ',';
			if(e.code != 16){
				
				this.letterMeasurer.innerHTML = e.key;
				i=0;
				$each(this.cursor.getParent('div.line').getChildren("span.letter"), function(value, index) {
					i=i+value.offsetWidth;
				});
				if((i +200) > this.cursor.getParent('div.line').offsetWidth){
					this.newLine();
				}
				
				new Element('span', {
					styles:{
						'border':'0px solid black',
						'float':'left',
						'font-size': this.size
					},
					'class':'letter',
					'html':e.shift ? e.key.toUpperCase() : e.key
				}).inject(this.cursor,'before');
				new Element('div', {
					styles : {
						'width': (this.cursor.getPrevious('span').offsetWidth / 2) + 'px',
						'border': '0px solid black',
						'height': this.size + 'px',
						'float':'left',
						'cursor':'text',
						'margin-left': '-' + this.cursor.getPrevious('span').offsetWidth + 'px'
					},
					events : {
						'click': function(e){
							this.notify(e.target);
						}.bind(this),
						'mousedown': function(e){
							e.stop();
							this.setMouseDown(e.target);
							return false;
						}.bind(this),
						'mouseup': function(e){
							e.stop();
							this.setMouseUp(e.target);
							return false;
						}.bind(this)
					},'class':'right'
				}).inject(this.cursor,'before');
				new Element('div', {
					styles : {
						'width': (this.cursor.getPrevious('span').offsetWidth / 2) + 'px',
						'border': '0px solid black',
						'height': this.size + 'px',
						'float':'left',
						'cursor':'text',
						'margin-left': '-' + (this.cursor.getPrevious('span').offsetWidth / 2) + 'px'
					},
					events : {
						'click': function(e){
							this.notify(e.target);
						}.bind(this),
						'mousedown': function(e){
							e.stop();
							this.setMouseDown(e.target);
							return false;
						}.bind(this),
						'mouseup': function(e){
							e.stop();
							this.setMouseUp(e.target);
							return false;
						}.bind(this)
					},'class':'left'
				}).inject(this.cursor,'before');
			}
		}
	},
	notify: function(el) {
		
	
		
		el.className == 'left' ? this.cursor.inject(el,'after') : 
			el.className == 'right' ? this.cursor.inject(el.getPrevious("span.letter"),'before') :
					this.cursor.inject(el,'before');

		
	},
	makeStatic: function() {
		$each($('textarea').getChildren('div.line'),function(value, index){
	
			$each(value.getChildren('div'),function(el,ind){
				el.dispose();
			});
	
		});
	},
	makeEditable: function() {
		$each($('textarea').getChildren('div.line'),function(value, index){
		
			$each(value.getChildren('span.letter'),function(el,ind){
				

				new Element('div', {
					styles : {
						'width': (el.offsetWidth / 2) + 'px',
						'border': '0px solid black',
						'height': this.size + 'px',
						'float':'left',
						'cursor':'text',
						'margin-left': '-' + (el.offsetWidth / 2) + 'px'
					},
					events : {
						'click': function(e){
							this.notify(e.target);
						}.bind(this),
						'mousedown': function(e){
							e.stop();
							this.setMouseDown(e.target);
							return false;
						}.bind(this),
						'mouseup': function(e){
							e.stop();
							this.setMouseUp(e.target);
							return false;
						}.bind(this)
					},'class':'left'
				}).inject(el,'after');
				new Element('div', {
					styles : {
						'width': (el.offsetWidth / 2) + 'px',
						'border': '0px solid black',
						'height': this.size + 'px',
						'float':'left',
						'cursor':'text',
						'margin-left': '-' + el.offsetWidth + 'px'
					},
					events : {
						'click': function(e){
							this.notify(e.target);
						}.bind(this),
						'mousedown': function(e){
							e.stop();
							this.setMouseDown(e.target);
							return false;
						}.bind(this),
						'mouseup': function(e){
							e.stop();
							this.setMouseUp(e.target);
							return false;
						}.bind(this)
					},'class':'right'
				}).inject(el,'after');
			}.bind(this));
		
		}.bind(this));
	}
});