/* ============================[ Plugins ]============================= */
/* ===[ Shift Select ]=== */
jQuery.fn.shiftSelect = function(){
    var checkboxes = this;
    var lastSelected;
    jQuery(this).click( function(event) {
        if (!lastSelected) {
            lastSelected = this;
            return;
        }
        if (event.shiftKey) {
            var selIndex = checkboxes.index(this);
            var lastIndex = checkboxes.index(lastSelected);
            var checkValue = lastSelected.checked;
            if ( selIndex == lastIndex ) {
                return true;
            }
            var end = Math.max(selIndex,lastIndex);
            var start = Math.min(selIndex,lastIndex);
            for(i=start;i<=end;i++) {
                checkboxes[i].checked = checkValue;
            }
        }
        lastSelected = this;
    });
}
/* ===[ Status messages ]=== */
var desc={};
desc.parent_selector="#messages";
desc.loader={};
desc.loader.tpl='<img class="loader" src="public/images/loader.gif" alt="Подождите"/>';
desc.loader.selector='.loader';
desc.msg={};
desc.msg.tpl='<div class=""></div>';
desc.msg.selector='div';
function statusMessages(pars){
	var self=this;
}
statusMessages.prototype={
	init:function(pars){
		this.parent=$(pars.parent_selector);
		this.parent.append(pars.loader.tpl+pars.msg.tpl);
		this.loader=this.parent.find(desc.loader.selector);
		this.msg=this.parent.find(desc.msg.selector);
	},
	show:function(message){
		if (message.status=="loading"){
			this.loader.show();
			this.msg.empty();	
		} else {
			this.loader.hide();
			this.msg.removeClass().addClass(message.status).empty().append(message.msg);
		}
	}
}
/* ===[ DataBases ]=== */
/* Example: 
var dataBase=new simpleBase;
dataBase.createTable({
	name:"nameTable",
	keyColumn:"id",
	columns:["column1","column2"],
	uniq:["column_uniq1","column_uniq2"]
})
dataBase.addColumn(nameTable,nameColumn);
dataBase.push(nameTable,row);
dataBase.cut(nameTable,nameColumn,value);
dataBase.selectValues(nameTable,nameColumn,value);
dataBase.update(nameTable,row);

row - object : {"columnName":"value","columnName":"value"}
other - string
*/
/* Base  v 4.30*/
function simpleBase(){
	var self=this;
	self.t={};
	self.lengths={};
	self.hasColumns={};
	self.columns={};
	self.uniq={};
	self.keyColumn={};
	self.maxId={};
	self.errors={};
	self.errors.noUniq={status:"error",msg:"Already exist"};
	self.errors.noFind={status:"error",msg:"Don't find"};
	this.showLog=false;
}
simpleBase.prototype={
	// Tables managment
	createTable:function(Table){
		this.t[Table.name]={}; // rows
		this.columns[Table.name]=[]; // columns
		this.lengths[Table.name]=0;
		this.maxId[Table.name]=0;
		this.uniq[Table.name]={};
		this.keyColumn[Table.name]=Table.keyColumn || "id";
		this.addColumn(Table.name,this.keyColumn[Table.name]);
		if (Table.columns){
			for (var i=0,length=Table.columns.length;i<length;i++){
				this.addColumn(Table.name,Table.columns[i]);
				this.uniq[Table.name][Table.columns[i]]=false;
			}
		}
		this.uniq[Table.name][this.keyColumn[Table.name]]=true;
		if (Table.uniq){
			for (var i=0,length=Table.uniq.length;i<length;i++){
				this.uniq[Table.name][Table.uniq[i]]=true;
			}
		}
	},
	addColumn:function(nameTable,nameColumn){
		if (this.isNewColumn(nameTable,nameColumn)){
			this.columns[nameTable][columns[nameTable].length]=nameColumn;
		}
	},
	// Data managment
	push:function(nameTable,row){
		var flag=true;
		var status={
			"table":nameTable,
			"row":row,
			"action":"push"
		};
		if (this.uniq[nameTable]){
			flag=this.checkToUniq(nameTable,row);
		}
		if (flag){
			var table=this.t[nameTable];
			var id;
			if (row.id && row.id>this.maxId[nameTable]){
				this.maxId[nameTable]=row.id;
				id=row.id;
			}
			id=this.maxId[nameTable];
			this.maxId[nameTable]++;
			this.t[nameTable][id]={};
			this.t[nameTable][id].id=id;
			for (var nameCol in row){
				if (nameCol!="id"){
					this.t[nameTable][id][nameCol]=row[nameCol];
				}
			}
			this.lengths[nameTable]++;
			status.status="ok";
		} else {
			status=jQuery.extend(status,this.errors.noUniq);
		}
		if (this.showLog) console.log(status);
		return status;
	},
	simplePush:function(nameTable,row){
		var status={
			"table":nameTable,
			"row":row,
			"action":"simplePush"
		};
		var table=this.t[nameTable];
		var id;
		if (row["id"]){
			id=row.id;
			if (row.id>this.maxId[nameTable]){
				this.maxId[nameTable]=row.id;
			}
		} else {
			id=this.maxId[nameTable];
		}
		this.maxId[nameTable]++;
		this.t[nameTable][id]={};
		this.t[nameTable][id].id=id;
		for (var nameCol in row){
			if (nameCol!="id"){
				this.t[nameTable][id][nameCol]=row[nameCol];
			}
		}
		this.lengths[nameTable]++;
		if (this.showLog){
			status.status="ok";
			console.log(status);
		}
	},
	cut:function(nameTable,nameColumn,value){
		var status={
			"table":nameTable,
			"column":nameColumn,
			"value":value,
			"action":"delete"
		};
		if (nameColumn==this.keyColumn[nameTable]){
			if (this.t[nameTable][value]){
				delete this.t[nameTable][value];
				this.lengths[nameTable]--;
				status.status="ok";
			} else {
				status=jQuery.extend(status,this.errors.noFind);
			}
		} else {
			var row_id=false;
			
			var rowKeys=[];
			var k=0;
			for (var p in this.t[nameTable]){
				if (""+this.t[nameTable][p][nameColumn]==value || this.t[nameTable][p][nameColumn]==value){
					rowKeys[k]=p;
					++k;
				}
			}
			if (rowKeys.length>0){
				status.status="ok";
				status.length=rowKeys.length;
				for (var i=0,length=rowKeys.length;i<length;i++){	
					delete this.t[nameTable][rowKeys[i]];
					this.lengths[nameTable]--;
				}
			} else {
				status=jQuery.extend(status,this.errors.noFind);
			}
		}
		if (this.showLog) console.log(status);
	},
	selectFirst:function(nameTable,nameColumn,value){
		var table=this.t[nameTable];
		var tmp=false;
		if (nameColumn==this.keyColumn[nameTable]){
			tmp=table[value];
		} else {
			for (var row in table){
				if (table[row][nameColumn] && table[row][nameColumn]==value){
					tmp=table[row];
					break;
				}
			}
		}
		return tmp;
	},
	selectRows:function(nameTable,Qrow,Acolumns){
		var table=this.t[nameTable];
		var ans=[];		
		var k=0;
		for (var string in table){
			if(table[string][Qrow.name]==Qrow.value){
				ans[k]={};
				for (var i=0,length=Acolumns.length;i<length;i++){
					ans[k][Acolumns[i]]=table[string][Acolumns[i]]
				}
				k++;
			}
		}
		if (ans.length==0) ans=false;
		return ans;
	},
	update:function(nameTable,row){
		var status={
			"table":nameTable,
			"row":row,
			"action":"update"
		};
		for (var c in row){
			if (c!=this.keyColumn[nameTable]){
				this.t[nameTable][row[this.keyColumn[nameTable]]][c]=row[c];
			}
		}
		if (this.showLog) console.log(status);
	},
	// staff
	isNewColumn:function(nameTable,nameColumn){
		var flag=true;
		for (var i=0,length=this.columns[nameTable].length;i<length;i++){
			if (this.columns[nameTable][i]==nameColumn){
				flag=false;
				break;
			}
		}
	},
	checkToUniq:function(nameTable,row){
		var table=this.t[nameTable];
		var flag=true;
		for (var column in row){
			if (this.uniq[nameTable][column]){
				for (var string in table){
					if (row[column]==table[string][column]){
						flag=false;
						break;
					}
				}
				if (!flag) break;
			}
		}
		return flag;
	},
	checkRowToUniq:function(nameTable,row){
		var table=this.t[nameTable];
		var flag=true;
		var f=0;
		for (var string in table){
			for (var column in row){
				if (row[column]==table[string][column]){
					f=1;
				} else {
					f=-1;
					break;
				}
			}
			if (f==1){
				flag=false;
				break;
			}
			f=0;
		}
		return flag;
	},
	checkToNoUniq:function(nameTable,row){ // to delete
		var table=this.t[nameTable];
		var flag=false;
		for (var column in row){
			if (uniq[nameTable][column]){
				for (var string in table){
					if (row[column]==table[string][column] && keyColumn[nameTable]!=column){
						flag={"column":column};
						break;
					}
				}
				if (flag) break;
			}
		}
		return flag;
	}
}
/* ===[ End: DataBases ]=== */
/* ===[Crossing]=== */
function crossing(arrays){
	var cross;
	var remain=new Array();
	if (arrays.length>2){
		for (var i=2,qlength=arrays.length;i<qlength;i++){
			remain[i-1]=arrays[i];
		}
		remain[0]=simpleCrossing(arrays[0],arrays[1])
		crossing(remain);
	} else {
		cross=simpleCrossing(arrays[0],arrays[1]);
	}
	function simpleCrossing(arr1,arr2){
		var t;
		var result=new Array();
		arr1.sort();
		arr2.sort();
		if (arr1.length>arr2.length){t=arr2;arr2=arr1;arr1=t;}
		var k=0;
		var l=0;
		var flag=false;
		for (var j=0,flength=arr1.length;j<flength;j++){
			if (arr1[j]==arr2[l]){result[k]=arr2[l];k++}
			if (arr1[j]>arr2[l]){
				flag=false;
				for (var m=l,slength=arr2.length;m<slength;m++){
					if (arr1[j]<arr2[m]){
						break;
					} else if (arr1[j]==arr2[m]){
						flag=true;
						break;
					}
				}
				if (flag){l=m;result[k]=arr2[l];k++}
				else {continue;}
			}
			if (arr1[j]<arr2[l]){continue;}
		}
		return result;
	}
	return cross;
}
/* ============================[ End: Plugins ]=========================== */