//lets rewrite some defaults
//
Drag.Move.implement({
	start: function(event){
		this.parent(event);
//		this.document.removeEvent(this.selection, this.bound.eventStop);
		$$('input', 'textarea').fireEvent('blur');
	},
	checkAgainst: function (el){
		el = el.getCoordinates();
		var now = this.mouse.now;
		return (now.x >= el.left && now.x <= el.right && now.y <= el.bottom && now.y >= el.top);
	}
});
//////////////////////////////////////////////////////////////////////////////////////
Sortables.SortableModified = new Class({

	Extends: Sortables,
	options: {
		cloneClass: ''
	},

	initialize: function(lists, options){
		this.parent(lists, options);
		this.options.cloneClass=options.cloneClass;
	},
	getClone: function(event, element){
		return this.parent(event, element).addClass('sortClone');
	},
	getDroppables: function(){
		var droppables = this.list.getChildren();
		if (!this.options.constrain) droppables = this.lists.concat(droppables).erase(this.list);
		return droppables.erase(this.clone);//.erase(this.element);
	},
	insert: function(dragging, element){
		this.insertOn = element;
		this.draging(dragging);
		var where = 'inside';
		if (this.lists.contains(element)){
			this.list = element;
			this.drag.droppables = this.getDroppables();
		} else {
			where = this.element.getAllPrevious().contains(element) ? 'before' : 'after';
		}
		//this.element.inject(element, where);
		this.fireEvent('sort', [this.element, this.clone]);
	},
	leave: function(dragging, element){
		this.sortHelp.setStyle('display', 'none');
		this.insertOn = null;
		this.activePart = null;
	},
	doOnpart: function(){
		var where = this.activePart==1 ? 'before' : 'after';
		this.sortHelp.inject(this.insertOn, where).setStyle('display', 'block');
	},
	doOnComplete: function(){
		if(!this.insertOn){
			return;
		}
		var where = this.activePart==1 ? 'before' : 'after';
		this.element.inject(this.insertOn, where);
		this.insertOn = null;
	},
	draging: function(element){
		if(this.insertOn){
			var dropable = this.insertOn.getCoordinates();
			var now = this.drag.mouse.now;
			var parts = 2;
			var part = Math.ceil(((now.y-dropable.top)*2)/(dropable.height)).limit(1, parts);
			if(this.activePart!=part){
				this.activePart = part;
				this.doOnpart();
			}
		}
	},
	start: function(event, element){
		this.parent(event, element);
		this.sortHelp = new Element('div', {
			'class': 'sortHelp',
			'html': '<div></div>'
		});
		this.activePart = 0;
		this.drag.addEvent('drag', this.draging.bind(this));
		this.drag.addEvent('leave', this.leave.bind(this));
	},
	end: function(){
		this.doOnComplete();
		this.parent();
	},
	reset: function(){
		this.sortHelp.destroy();
		this.parent();
	}
});

//////////////////////////////////////////////////////////////////////////////////////
var UpdateStatus = new Class({
	options: {
		url:''
		,el:''
		,checkbox: true
		,idRead: ''
		,statusClass: ''
		,loading: false
		,errorShow: false
	},
	el:[],
	initialize: function(options){
		this.setOptions(this.options, options);
		this.elements = $$(this.options.el);
		this.elements.each(function(el, i){
			this.el[i]={
				before: el.get('checked') ? 0 : 1
				,loading: false
			};
			el.addEvent('mousedown', function(e){
				e.stopPropagation();
			});
			el.addEvent('click', function(e){
				if(!this.el[i].loading){
					this.el[i].loading=true;
					this.change(el, i);
				}
			}.bind(this));
		}.bind(this));
	},
	change: function(el, i){
		var val = !el.get('checked') ? 1 : 0;
		if(val==this.el[i].before&&this.options.checkbox){
			return;
		}
		var task = el.getParents(this.options.idRead).getLast();
		var id = task.get('id').split('-').getLast();
		this.options.loading.showSaving();
		new Request.JSON({
			url: this.options.url
			, method: 'post'
			, data: 's='+val+'&id='+id
			, onComplete: function(data){
				this.saveComplete(el, i, task, data, val);
			}.bind(this)
		}).send();
	},
	saveComplete: function(el, i, task, data, val){
		if(data.error){
			this.errorShow.show(data.text);
			return;
		}
		task.removeClass(this.options.statusClass+this.el[i].before);
		task.addClass(this.options.statusClass+val);
		this.options.loading.hide();
		this.el[i].before=val;
		this.el[i].loading=false;
		if(this.el[i].before==0){
			el.set('checked', 'checked');
		} else {
			el.set('checked', '');
		}
		this.fireEvent('onComplete', [data, task]);
	}
});
UpdateStatus.implement(new Events);
UpdateStatus.implement(new Options);
//
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
var InlineEditor = new Class({
	options: {
		url:''
		,el:''
		,idRead: ''
		,inputClass: 'in-box'
		,same: false
		,saveOnblur: true
		,updateAfterSave: true
		,loading: false
		,errorShow: false
	},
	el:[],
	initialize: function(options){
		this.setOptions(this.options, options);
		this.elements = $$(this.options.el);
		this.elements.each(function(el, i){
			this.el[i]={
				'before':'',
				'created':false
			};
			el.addEvent('mousedown', function(e){
				e.stopPropagation();
			});
			el.addEvent('click', function(e){
				e.stopPropagation();
				this.replace(el, i);
			}.bind(this));
		}.bind(this));
	},
	replace: function(el, i){
		if(this.el[i].created){
			//cancel events, if alredy we created input
			this.el[i].input.focus();
			return;
		}
		this.el[i].before = el.get('html').trim();
		this.el[i].created = true;
		el.set('html','');
		if(el.hasClass('textarea')){
			this.el[i].input = new Element('textarea', { 'class':this.options.inputClass, 'text':this.el[i].before.replace(/<br>/g, '\n') });
		} else {
			this.el[i].input = new Element('input', { 'class':this.options.inputClass, 'value':this.el[i].before });
		}
		//opera not add focus on select
		if(Browser.Engine.presto){
			this.el[i].input.inject(el).focus();
		} else {
			this.el[i].input.inject(el).select();
		}
		//lets save on enter button pressed, and cancel on escape pressed
		this.el[i].input.addEvent('keydown', function(e) {
			if(e.key == 'enter'&&!e.shift) {
				this.save(el, i);
			} else if(e.key == 'esc') {
				this.cancel(el, i);
			}
		}.bind(this));
		//blur
		this.el[i].input.addEvent('blur', function(e){
			if(this.options.saveOnblur){
				this.save(el, i);
			} else {
				this.cancel(el, i);
			}
		}.bind(this));
	},
	save: function(el, i, forceSame){
		var same = forceSame!=undefined ? forceSame : this.options.same;
		var val = this.el[i].input.get('value').replace(/\n/g, '<br />').trim();
		var id = el.getParent(this.options.idRead).get('id').split('-').getLast();
		if(val!=''&&(val!=this.el[i].before|same)){
			this.options.loading.showSaving();
			new Request.JSON({
		   		url: this.options.url
		   		, method: 'post'
		   		, data: 's='+val+'&id='+id
		   		, onComplete: function(data){
					this.saveComplete(el, i, data, val);
				}.bind(this)
	   		}).send();

		} else if(val!=''){
			this.updateElement(el, i);
		}
		//this.updateElement(el, i, val);
	},
	saveComplete: function(el, i, data, val){
		this.options.loading.hide();
		if(data.error){
			this.el[i].input.removeEvents('blur');
			this.errorShow.show(data.text);
			return;
		}	
//		this.onComplete(data);
		this.fireEvent('onComplete', data);
		if(this.options.updateAfterSave){
			this.updateElement(el, i, val);
		} else {
			this.updateElement(el, i);
		}
	},
	onComplete: function(data){
		
	},
	cancel: function(el, i){
		this.updateElement(el, i);
	},
	updateElement: function(el, i, val){
		val = val==undefined ? this.el[i].before : val;
		this.el[i].input.dispose();
		el.set('html', val);
		this.el[i].created = false;
	}
});
InlineEditor.implement(new Events);
InlineEditor.implement(new Options);
///////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
var Loading = new Class({
	options: {
		elLoading: '',
		loadingText: 'loading',
		savingText: 'saving'
	},
	initialize: function(options){
		this.setOptions(this.options, options);
		this.elLoading = $(this.options.elLoading);
		this.elLoading.set('styles', {
			'display':'block'
			,'opacity': 0
		});
	},
	show: function(v){
		this.elLoading.set('html', v);
		this.elLoading.fade('in');
	},
	showLoading: function(){
		this.show(this.options.loadingText);
	},
	showSaving: function(){
		this.show(this.options.savingText);
	},
	hide: function(){
		this.elLoading.fade('out');
	}
	
});
Loading.implement(new Options);
//////////////////////////////////////////////////////////////////////////////////////
var Error = new Class({
	Implements: [Options],
	options: {
		text : 'error'
	},
	initialize: function(options){
		this.setOptions(this.options, options);
	},
	show: function(v){
		v = v==undefined ? this.options.text : v;
		alert(v);
	}
});
//////////////////////////////////////////////////////////////////////////////////////












	
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
String.prototype.trim = function() {
	return this.replace(/^\s+/, '')
						 .replace(/\s+$/, '');
};
String.prototype.escape_html = function() {
	return this.replace(/&/g, "&amp;")
						 .replace(/</g, "&lt;")
						 .replace(/>/g, "&gt;")
						 .replace(/"/g, "&quot;")
						 .replace(/'/g, "&quot;");
 	};
String.prototype.create_domain = function(){
       var def='-';
       var code_set = new Array ();
       code_set[92] = def;  // \
       code_set[91] = def;  //  [
       code_set[93] = def;  //  ]
       code_set[94] = def;  // ^
       code_set[96] = def;  // `
       // Latvian 
       code_set[275] = "e";  code_set[274] = "e"; 
       code_set[363] = "u";  code_set[362] = "u"; 
       code_set[299] = "i";  code_set[298] = "i"; 
       code_set[257] = "a";  code_set[256] = "a"; 
       code_set[353] = "s";  code_set[352] = "s"; 
       code_set[291] = "g";  code_set[290] = "g"; 
       code_set[311] = "k";  code_set[310] = "k"; 
       code_set[316] = "l";  code_set[315] = "l"; 
       code_set[382] = "z";  code_set[381] = "z"; 
       code_set[269] = "c";  code_set[268] = "c"; 
       code_set[326] = "n";  code_set[325] = "n"; 
       // Russian
       code_set[1081] = "i";  code_set[1049] = "I";
       code_set[1094] = "c";  code_set[1062] = "C";
       code_set[1091] = "u";  code_set[1059] = "U";
       code_set[1082] = "k";  code_set[1050] = "K";
       code_set[1077] = "e";  code_set[1045] = "E";
       code_set[1085] = "n";  code_set[1053] = "N";
       code_set[1075] = "g";  code_set[1043] = "G";
       code_set[1096] = "s";  code_set[1064] = "S";
       code_set[1097] = "s";  code_set[1065] = "S";
       code_set[1079] = "z";  code_set[1047] = "Z";
       code_set[1093] = "h";  code_set[1061] = "H";
       code_set[1098] = "";   code_set[1066] = "";
       code_set[1092] = "f";  code_set[1060] = "F";
       code_set[1099] = "i";  code_set[1067] = "I";
       code_set[1074] = "v";  code_set[1042] = "V";
       code_set[1072] = "a";  code_set[1040] = "A";
       code_set[1087] = "p";  code_set[1055] = "P";
       code_set[1088] = "r";  code_set[1056] = "R";
       code_set[1086] = "o";  code_set[1054] = "O";
       code_set[1083] = "l";  code_set[1051] = "L";
       code_set[1076] = "d";  code_set[1044] = "D";
       code_set[1078] = "z";  code_set[1046] = "Z";
       code_set[1101] = "e";  code_set[1069] = "E";
       code_set[1103] = "a";  code_set[1071] = "A";
       code_set[1095] = "c";  code_set[1063] = "C";
       code_set[1089] = "s";  code_set[1057] = "S";
       code_set[1084] = "m";  code_set[1052] = "M";
       code_set[1080] = "i";  code_set[1048] = "I";
       code_set[1090] = "t";  code_set[1058] = "T";
       code_set[1100] = "";   code_set[1068] = "";
       code_set[1073] = "b";  code_set[1041] = "B";
       code_set[1102] = "u";  code_set[1070] = "U";
       newName='';
       var s='';
       var sp='';
       var c=0;
       for (i=0;i<this.length;i++){
           c=this.charCodeAt(i);
           if (code_set[c]){
               s=code_set[c];
           } else {
               if (c<48 || (c>57 && c<65) || c>122) {
                   s=def;
               } else {
                   s=this.charAt(i)
               }
           }
           if(s!==''&&!((sp==def | sp=='')&&s==def)){
               sp=s;
               newName+=s;
           }
       }
       return newName.toLowerCase();
   }