// Taqualb Renewed (basic)
//variables
//alert('basic');
//(win=>{

_d = (typeof _d=="undefined")?document:_d; //document abbr throughout the script
_UND = "undefined"; //'undefined' string abbr
_Sec = 1000; //Seconds
_Min = _Sec * 60; //Minute
_Hour = _Min * 60; //Hour
_Day = _Hour * 24; //Day
_Week = _Day * 7; //Week
_Month = _Week * 4; //~Month
_Year = _Day * 365;//~Year

 //Show/Hide ID object (Show or Hide)
 //----------------------------------------
 //This function displays or hides the element
function SHs(ID,Show,display){
	//ID - Holds the Element or its id - Required
	//Show - Holds which operation to perform on the Element (1 => Show, Not 1 => Hide) - Required
	//display - Holds the Element CSS display value ('block','inline','inline-block','table' e.t.c) - Default = 'block' (true = 'block', false = 'inline')
	display = (typeof display == _UND || display === true)?"block":(display === false)?"inline":display; //handles the default setting of display argurment
	var elem = RP(ID); //RP - Make Sure the ID is an element (cos ID can either be an element or the element ID)
	if(elem == null)return; //if cannot get the element stop operation
	if (Show == 1){ //if to display
		elem.style.display = display; //set the css display attribute of the element to its display type
	}else{
		//if to hide, set to none
		elem.style.display = 'none';
	}
}

//function to display awesome font
//----------------------------------------
var Icon = function(type){
	//type - holds the font awesome icone name
	//Form the markup and return it as string
  return '<i class="fa fa-'+type+'" aria-hidden="true"></i>';	
}
//String Prototype for Icon function
String.prototype.Icon = function(){return Icon(this.toString())}

//function to return the actual type of supplied object
//----------------------------------------
//main advantage is, it checks array and return as array type not conventional javascript object type
function CheckType(obj){
	//obj - Holds the object/Element to Check Type - Required
	if(typeof obj == _UND || obj == null) return null; //if obj is null or not supplied return null
	//Check if obj is not a string and can have children 
	if (typeof obj != "string" && typeof obj.length != "undefined" ){
		try{ //Check if it is an array, by running native array function on the Obj. if no error occur, return 'array' else return the type of the element/Argurment
			var a = obj.sort();
			var b = obj.slice(0);
			return "array"
		}catch(e){
			return typeof obj;
		}
	}else{ 
		return typeof obj;
	}
}

//Specific Function that checks type using the CheckType function
//----------------------------------------
//IsArray return true if obj is array 
var IsArray = function(obj){return (CheckType(obj) == "array")?true:false;}
//IsString return true if obj is string
var IsString = function(obj){return (CheckType(obj) == "string")?true:false;}
//IsNumber return true if obj is numeric
var IsNumber = function(obj){return (CheckType(obj) == "number")?true:false;}
//IsObject return true if obj is object
var IsObject = function(obj){return (CheckType(obj) == "object")?true:false;}
//IsFunction return true if obj is a function
var IsFunction = function(obj){return (CheckType(obj) == "function")?true:false;}
//IsNull return true if obj is null
var IsNull = function(obj){return (obj == null)?true:false;}
var Null = IsNull; //Nickname - Null can also be used to check if null

//check if sent value is a valid phone number
//----------------------------------------
var _CheckPhoneNum = function(number){
	//number - the number to check its validity
	if(IsString(number)){ //if is sent as a string
		//trim out special phone prefix
		number = number.TrimLeft(["+","-"]); //TrimLeft function trim leading character
		//Check if all character is a digit
		for(var s=0,len=number.length; s <len; s++){ //loop through all characters
			var char = number[s]; //get current character
			//if(typeof parseInt(char) == "NaN"){
				if(isNaN(parseInt(char))){ //check if not an integer number
					return false; //return false; meaning not a valid phone number
				}
			//}
		}
		//check if number is between 6 to 15 digit(Can be modified to cater for any range) - idea => it will be beter if it is dynamic user defined
		if(number.length > 5 && number.length < 16){
			return true;
		}else{
			return false;
		}
	}else if(IsNumber(number)){ //if argument sent is a numeric
		//convert to string and rerun the function on it
		return _CheckPhoneNum(number.toString());
	}
}
//check if phone number (NickName)
var IsPhoneNumber = function(obj){
	//obj - holds user sent string or object
	if(IsObject(obj)){//check if sent argument is an object
		 //Object.Text() - Get or Set the innerHTML or TextContent or Value of the Object
		if(obj.Text() != ""){
			//use the textContent or innerHTML of the object and check if valid phone number
			return _CheckPhoneNum(obj.Text());
		}else{
		   return false;	
		}
		
	}else{
		return _CheckPhoneNum(obj);
	
		
	}
}

//check if sent value is a valid Email Address
//----------------------------------------
_CheckEmail = function(obj){
	//obj - holds the user sent email string
	//var regexp = /^((\w|\-)+\@(\w|\-)+\.\w{2,3})$|^((\w|\-)+\@(\w|\-)+\.\w{2,3}\.[a-z]{2})$/;
	var regexp = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
					var test = regexp.test(obj);//test if sent email string matches the email regexp 
					return test;
	
}

//check if email, accept more argument type
var IsEmail = function(obj){
	//obj - holds user sent string or object
	if(IsObject(obj)){ //check if sent argument is an object
		   //Object.Text() - Get or Set the innerHTML or TextContent or Value of the Object
			if(obj.Text() != ""){
				//use the textContent or innerHTML of the object and check if valid email address
				return _CheckEmail(obj.Text());
			}else{
			   return false;	
			}
			
		}else{
			return _CheckEmail(obj);
		}
}

//Checks if Children exist
var HasItem = function(obj){
	if(IsArray(obj)){
		// alert(obj.length);
		return (obj.length > 0)?true:false;
	}else if(IsString(obj)){
		return !IsEmpty(obj);
		//obj.childNodes.length
	}else{
		if(IsSet(obj.childNodes)){
			return (obj.childNodes.length > 0)?true:false;
		}else if(IsSet(obj.length)){
		 return (obj.length > 0)?true:false;
		}else{
			return false;
		}
	}
}
//Checks if an item exists inside an array
var _ArrObjExist = function(arr,obj,funct){
	arrnew = Object.keys(arr);
	for(const s of arrnew){
		if(IsSet(funct)){
			if(funct(arr[s],obj)){
				return {"Exist":true,"Index":s};
			}
		}else{
		  if(arr[s] == obj){
			  return {"Exist":true,"Index":s};
		  }
		}
	}
   return {"Exist":false,"Index":-1};	
}

/*var _CharExist = function(str,char){
	if(IsSet(str) && IsSet(char)){
		if(str.length == 1 && str == char){
			return {"Exist":true,"Index":0}
		}else if(str.length > 1){
			var strarr = str.ToArray();
			return strarr.InArray(char);
		}
	}
	return {"Exist":false,"Index":-1};
}*/

Array.prototype.InArray = function(obj,funct){return _ArrObjExist(this,obj,funct)}
Array.prototype.IndexOf = function(obj,funct){return _ArrObjExist(this,obj,funct).Index}

function PerformSH(obj,sh,inl){
	inl = (isset(inl))?inl:true;
	if(IsArray(obj)){
		obj.Walk(function(k,v,s){SHs(v,s[0],s[1]);},[sh,inl]);
	}else{
		SHs(obj,sh,inl);
	}
}
//Object.prototype.type = function(){return type(this)};

//string object prototyping to perform Showing/Hideing operation by object ID(the string)
String.prototype.Show = function(inl){PerformSH(this.toString(),1,inl)}; 
String.prototype.Hide = function(inl){PerformSH(this.toString(),0,inl)};
//array object prototyping to perform Showing/Hideing operation by object ID(the string)
Array.prototype.Show = function(inl){PerformSH(this,1,inl)}; 
Array.prototype.Hide = function(inl){PerformSH(this,0,inl)};
//object prototyping to perform Showing/Hideing operation on object (the string)
Object.prototype.Show = function(inl){PerformSH(this,1,inl)}; 
Object.prototype.Hide = function(inl){PerformSH(this,0,inl)};


 //The visibility of an element
 //----------------------------------------
function Visible(obj,Show){
	
	if(IsArray(obj)){ //if it is an array, perform the operation on all item of the array
		obj.Walk(function(k,v,s){vis(v,s);},Show);
	}else{ //if not array, perform on the element only
         vis(obj,Show);
	}
	
}

//real code that controls visibility
function vis(obj,Show){
//alert(Show);	
  var elem = RP(obj); //Return the element
  if(IsNull(elem) || !isset(elem.style))return;
  if (Show == 1){ 
	  elem.style.visibility = 'visible';
  }else{
	  elem.style.visibility = 'hidden';
  }	
	
}


//Array.prototype.
//string object prototyping to perform Apear/disapear operation by object ID(the string)
String.prototype.Appear = function(){Visible(this.toString(),1)}; 
String.prototype.Disappear = function(){Visible(this.toString(),0)};
//array object prototyping to perform Showing/Hideing operation by object ID(the string)
Array.prototype.Appear = function(){Visible(this,1)}; 
Array.prototype.Disappear = function(){Visible(this,0)};
//object prototyping to perform Showing/Hideing operation on object (the string)
Object.prototype.Appear = function(){Visible(this,1)}; 
Object.prototype.Disappear = function(){Visible(this,0)};

//Get Element(s) Functions
//---------------------------------------

//function get elements by ClassName, TagName or Name (Multiple Element Selector)
var GetBy = function(By, value){
	//By - The parameter we are using to get elemet (c=>ClassName, t=>TagName, n=>Name)
	switch (By){
	  case "c": //Classname
	  return document.getElementsByClassName(value);
	  break;
	  case "t": //TagName
	  return document.getElementsByTagName(value);	
	  break;
	  case "n": //Name
	  return document.getElementsByName(value);	
	  break;
		
	}
	
}

//----------------------------------------------------------------------
//get element by className or by tag names
var GetElemBy = function(arg,by){
	by = (IsNull(by))?"c":by;
	if (arg.length == 1){ //if only one parameters sent
		 //check the type of single parameter sent
		 if (IsString(arg[0])){ 
			 var className = arg[0]; //get the string (ClassName,TagName or Name)
			 objs = GetBy(by,className); //get the elements by supplied method
			 if(HasItem(objs)){ //if elements found
				 return AddtoArray(objs,by);
			 }else{
				return null; 
			 }
		 }else{
			  var obj = arg[0];
			 //check if it is not an array or class
			 if (!IsArray(arg[0])){// if it does not contain subelement
			     //return back the object
				 return obj;
			 }else{
				//use all the classname and get all elements into an array
				//from a comprehensive array, incase there are nexted array
				return AddtoArray(obj,by);
			 }
		 }
		//if multiple parameters 
	 }else if (arg.length > 1){
		 return AddtoArray(arg,by);
	 }else{
		return null; 
	 }
}
//get elements by className
function _c(){
	return GetElemBy(arguments);
}
//get elements by TagName
function _t(){return GetElemBy(arguments,"t");}
//get elements by Name
function _n(){return GetElemBy(arguments,"n");}


//Function to form a Comprehensive Super array of elements
function AddtoArray(classNamearr,by){
	//by represent the javascript function type to get element
	//get all the classname and get elements into an array
				//var arrelem = new Array(classNamearr.length);
				var genarr = new Array();
				//var totlenght = genarr.length; //set the current pointer to the next available space of the genarr
				 for (var i = 0,leni=classNamearr.length; i < leni; i++){
					 if(IsObject(classNamearr[i])){
						genarr.push(classNamearr[i]);
					// totlenght = genarr.length;
					 continue;
					 }
					 if(IsArray(classNamearr[i])){ //if item is an array run this function with the current item, is it array(parameter)?. merge the returned array with the array to form an updated array
					     var rtnarr = AddtoArray(classNamearr[i],by);
						 genarr = (HasItem(rtnarr))?genarr.concat(rtnarr):genarr;
					 }else if(IsString(classNamearr[i])){ //if item is a string,
					   var objs = GetBy(by,classNamearr[i]); //get the array of elements
					   //if a new set of objects is gotten
					   if(HasItem(objs)){
						 for(var w = 0,len=objs.length; w < len; w++){ //move through the elements and add them to the general array (arrelem)
							 genarr.push(objs[w]); //add element to array
							 //w+totlenght calculates the new location for insertion in the general array
						 }
					   }
					 }
					 //totlenght = genarr.length; //reset the new array starting key specifier
					 //make sure the totlenght is equal to the length of the general array currently so that subsequent looping key calculation will start from the general array length (the next available array slot)
				 }
				 return (genarr.length == 1)?genarr[0]:genarr;
	
}

function _Walk(elemarr,funct,passval){
	
	//passval is a parameter that will be passed into the funct function while calling it (optional)
	if(IsNull(elemarr))return;
	if(IsObject(elemarr)){ //if elemarr is an object  and it has children pass the current child into the supplied function (funct)
		if(elemarr.childNodes.length != "undefined"){
			for(var i=0,len=elemarr.childNodes.length; i<len; i++){
				funct(i,elemarr.childNodes[i],passval);
			}
		}else{
			return;
		}
	}else if(IsArray(elemarr)){ //if elemarr is an array pass the each item of the array to the supplied function;
	  for(var i=0,len=elemarr.length; i<len; i++){
		funct(i,elemarr[i],passval);
	  }
	}else if(IsString(elemarr)){ //if elemarr is string pass each character
	  for(var i=0,len=elemarr.length; i<len; i++){
		funct(i,elemarr.charAt(i),passval);
	  }
	}else{ 
	   return;	
	}
}

//function walk(elemarr,funct,passval){_Walk(elemarr,funct,passval)}
walk = _Walk;
Array.prototype.Walk = function(func,passVal){walk(this,func,passVal);}
Object.prototype.Walk = function(func,passVal){walk(this,func,passVal);}
String.prototype.Walk = function(func,passVal){walk(this.toString(),func,passVal);}

//Get element by ID-------------------------------------------------
 var otherfunc = [_n,_t,_c]; 
 
 function _(){	 
    
	 if (arguments.length == 1){
		if(IsNull(arguments[0]))return null;
		 //check the type of single parameter sent
		 if (IsArray(arguments[0]) || IsString(arguments[0])){


				 return Element4rmArr(arguments[0]); 
		 }else{
			return arguments[0];  
		 }
		 
		//if multiple parameters 
	 }else if ( arguments.length > 1){
		 return Element4rmArr(arguments); 
	 }else{
		return null; 
	 }
	 	 
 }
 
 
 
 var Element4rmArr = function(arr){
	 var arrelem = new Array();
	             //var len = 0;
				 if(IsString(arr)){
					  arr = arr.Trim();
					 return performGetElem(arr);
					
				 }
				 for (var i = 0,leni=arr.length; i < leni; i++){ //loop trough array of item
					 if(IsString(arr[i])){ //if item type is string get the element by ID and add it to the array otherfunc
					arr[i] = arr[i].Trim();
					// var rst = document.getElementById(arr[i]);
					  arrelem = performGetElem(arr[i],arrelem);  
					 }else if(IsObject(arr[i])){ //if item is an object add it to the array
						arrelem.push(arr[i]);
					 }else if(IsArray(arr[i])){ // if is an array run this samen function to loop throug it and get all element. then concatinate the return array with the current to form updated one
						arrelem = arrelem.concat(Element4rmArr(arr[i]));
						//len = arrelem.length - 1;
					 }else{ //if type is none of the above add null to array
						//arrelem.push(null); 
					 }
					// len++;
				 }
	return (arrelem.length == 1)?arrelem[0]:arrelem;
 }
 
 /*//function to perform the subtraction operation sending array of operands elements/string in which the first is the main value while others are to be subtracted from main
 var RemoveElement = function(arrelems){
	 
	 var mainelem = _(arrelems[0]);
	 
	 //check if main element if object
	 if(IsNull(mainelem))return null;
	 //get for other element
	 var pyherarr = new Array(arrelems.length - 1);
	 for(var d=1; d <arrelems.length; d++){
		 pyherarr[d-1] = arrelems[d];
	 }
	 var otherelem = _(pyherarr);
	 
	 //if no other element exist, return back the main element(s)
	 if(IsNull(otherelem))return mainelem;
	
	 var rstarr = new Array();
	 if(IsArray(mainelem)){//if the main elemenet is an array of elements
	   for(var a=0; a < mainelem.length; a++){
		   var curel = mainelem[a];
		    
		   var include = checkelement(curel,otherelem);
		   if(include == true){ //check if element is to be added or ignored
				 rstarr[rstarr.length] =  curel; //add to the resulting element array
			 }
	   }
	 // alert(IsEmpty(rstarr));
	   if(IsEmpty(rstarr)){ //if result array is empty
		   return null;
	   }else{
	      return rstarr;
	   }
	 }else{ //if main element is an object
		  include = checkelement(mainelem,otherelem);
		if(include == true){ //check if element is to be added or ignored
			return mainelem; //add to the resulting element array
		}else{
			return null; //if found
		}
	 }
 }*/
 
 
 
 //function to perform the subtraction operation sending array of operands (string) in which the first is the main value while others are to be subtracted from main
 //Limitation = if an element exit in even operands (e.g 3, 5, 7 operands) it will not be removed
 var RemoveElement = function(arrelems){
	 //alert(arrelems.length);
	 var mainelem = _(arrelems[0]); //the first operand
	 
	 var startpointer = 0;
	 var rstelem = null;
	 //check if main element if object
	
	 //get for other element
	// var pyherarr = new Array(arrelems.length - 1);
	//all intersection
	//var allint = _(arrelems.join("&"));
	//loop trough the remaining strings of the array to perform a subtract operation with the first.
	//result of the first operation of the loop is set to first, so that the operation can be down with the next
	 for(var d=1,len=arrelems.length; d <len; d++){
		 
		 
		 /* var nstr = arrelems[d]; //get the next operand
		 var nelem = _(nstr); //get its elements
		  if(IsNull(mainelem)){ //if current main is null
		    //set main to subtractin elemenet
			 mainelem = nelem;
			 continue
		  }
		  
		 if(IsArray(mainelem)){//if the main elemenet is an array of elements
	        for(var a=0; a < mainelem.length; a++){
			   var curel = mainelem[a];
			   if(IsNull(curel))continue;//if checking object is null ignore and go to next object
			   var include = checkelement(curel,nelem);
			   if(include.Exist == true){ //check if element exist
					 nelem = include.NewArray; //reset the lookup array to updated array
					 mainelem[a] = null; //set the current object to null
					 continue;
			   }
			}
			if(d+1 < arrelems.length){ //if not last operand combine the remaining elements in the of the two operand as mainelem for next subtraction 
				mainelem = FormRst(mainelem,nelem);
			}
		 }else{ //if main element is an object
			  include = checkelement(mainelem,nelem);
			if(include.Exist == true){ //check if element is to be added or ignored
			    nelem = include.NewArray;
				mainelem = FormRst(null,nelem); //add to the resulting element array
			}else{
				 mainelem = FormRst(mainelem,nelem);
			}
		 }*/
		 
		 //new pertern
		 //////////////////////////////
		 var union = FormRst(mainelem,_(arrelems[d])); //get the union of the first and second
		 var int = FormAND([mainelem,_(arrelems[d])]); //get the intersection of the first and second
		
		 //subtract the intersection from the union and set as first
		  mainelem = ExactRemove(union,int);
		 //alert(mainelem);
		 //////////////////////////
		  
	 }
	 
return mainelem;
	 
 }
 
 function ExactRemove(bigset,smallset){
	 if(IsArray(smallset)){ //if smallset is an array, loop through it and check if exist in big set
		 for(var s=0,len=smallset.length; s<len; s++){
			 var currelem = smallset[s];
			 if(!IsArray(bigset)){
				 if(bigset = currelem)return null;
			 }else{
				 
				 var checkext = bigset.InArray(currelem);
				 if(checkext.Exist){ //if exist in big set array
				// alert("seen");
					bigset[checkext.Index] = null; //set the element to null in bigarray
				 }
			 }
		 }
	 }else{ //if smallset is an object
		if(!IsArray(bigset)){
				 if(bigset = smallset)return null;
			 }else{
				 var checkext = bigset.InArray(smallset);
				 if(checkext.Exist){ //if exist in big set array
					bigset[checkext.Index] = null; //set the element to null in bigarray
				 }
			 } 
	 }
	 //alert("Normal: "+bigset);
	// alert("Exact: "+bigset.Exact());
	 return (IsArray(bigset))?bigset.Exact():bigset;
 }
 
  //function to check if current element exist in otherselement
 var checkelement = function(curel,otherelem){
	      if(IsArray(otherelem)){ //if the subtracting element is more than one i.e an array
		   var include = {Exist:false,NewArray:otherelem};
			 //loop through all other elements and compare each element with current main element
			  var existw =  otherelem.InArray(curel);
				 if(existw.Exist == true){ //if current element exist in main element, set indicator to ignore the element
					otherelem[existw.Index] = null; //remove it from the arraylist
					include = {Exist:true,NewArray:otherelem};
				 }
			
			 return include;
		   }else{//if the subtracting element is one i.e an object
			   if(curel != otherelem){
				   return {Exist:false,NewArray:otherelem};
				 // rstarr[rstarr.length] =  curel; //add to the resulting element array
			   }else{
				   return {Exist:true,NewArray:null};
			   }
		   }
 }
 
/* //function to check if current element exist in otherselement
 var checkelement = function(curel,otherelem){
	      if(IsArray(otherelem)){ //if the subtracting element is more than one i.e an array
		   var include = true;
			 //loop through all other elements and compare each element with current main element
			 for(var r=0; r<otherelem.length ; r++){
				 var curothers = otherelem[r];
				 if(curothers == curel){ //if current element exist in main element, set indicator to ignore the element
					 include = false;
					 break;
				 }
			 }
			 return include;
		   }else{//if the subtracting element is one i.e an object
			   if(curel != otherelem){
				   return true;
				 // rstarr[rstarr.length] =  curel; //add to the resulting element array
			   }else{
				   return false
			   }
		   }
 }*/
 
 
 //function to form the new resulting array
 var FormRst = function(mainelem,nelem){
	 var arrays = [mainelem,nelem];
	 var rstarr = new Array();
	for(var q=0,len=arrays.length; q < len; q++){
	 if(IsArray(arrays[q])){
	   for(var y=0,leny=arrays[q].length; y < leny; y++){
		   var it = arrays[q][y];
		   if(!IsNull(it)){
			   if(!rstarr.InArray(it).Exist)rstarr[rstarr.length] = it;
		   }
	   }
	 }else if(!IsNull(arrays[q])){
		 if(!rstarr.InArray(arrays[q]).Exist)rstarr[rstarr.length] = arrays[q];
	 }
	}
	if(rstarr.length == 0){
		return null;
	}else if(rstarr.length == 1){
		return rstarr[0];
	}else{
		return rstarr;
	}
 }
 
 //function to perform the AND logical operation (intersection)
 function FormAND(items){
	 
	 if(IsArray(items)){ //if items to perform AND on is an array
		 if(items.length == 0)return null; //if no element exist in item array return null
		 if(items.length < 2){ //if only one element exist
			return _(items[0]); //return the get result of the element
		 }else{ //if more than one element exits
			 var first = _(items[0]); //get the first element and get the resulting element(s)
			 var second = _(items[1]);//get the second element and get the resulting element(s)
			// alert(items[0] + "="+first.name+ " " +items[1] + "="+second.length);
			 if((IsArray(first) && !IsArray(second)) || (IsArray(first) && IsArray(second) && first.length > second.length)){//if first item is greater than second, swap them (for optimization)
				 var temp = first;
				 first = second;
				 second = temp;
				 //alert("swaped");
			 }
			 
			 var newarr = new Array(); //array to hold the AND operation result of the first and second element
			 //alert(IsArray(first));
			 if(IsArray(first)){ //if the first item is an array, check one by one if its element exist in second item
			 
				 for(var h=0,lenh=first.length; h<lenh; h++){
					 var curfirst = first[h];//get individual element
					 if(IsArray(second)){ //if the second item is an array
						 var conf = second.InArray(curfirst); //check if current firse element, exist in second array
						 if(conf.Exist){ //if exist add to new array
						  newarr[newarr.length] = curfirst;
						 }
					 }else{ //if second item is not an array
						 if(curfirst == second){ //check if current first is the second item, if exist add to new array
							 newarr[newarr.length] = curfirst; 
						 }
					 }
					 //objclnarr.InArray(className);
	//if(clsnCheck.Exist){
				 }
			 }else{// if first item is not an array
			 
				 var curfirst = first;//get individual element
					 if(IsArray(second)){ //if the second item is an array
						 var conf = second.InArray(curfirst); //check if current firse element, exist in second array
						 if(conf.Exist){ //if exist add to new array
						  newarr[newarr.length] = curfirst;
						 }
					 }else{ //if second item is not an array
						 if(curfirst == second){ //check if current first is the second item, if exist add to new array
							 newarr[newarr.length] = curfirst; 
						 }
					 }
				 
			 }
			 //form the new item array to continue AND operation on
			 if(newarr.length > 0){ //if AND eleemnt exist
				 items[0] = newarr;
				 items[1] = null;
				// alert(items);
				 items = items.Exact(); //make array be exclusive value elements, i.e all element with no value are removed
				 //alert(items);
				 if(items.length <2){ //if one element remaining, return it (the AND operation result)
					return  _(items[0]);
				 }else{ //if items still remains, continue AND operation
					return  FormAND(items);
				 }
			 }else{
				 return null;
			 }
			 
			 
		 }
	 }else{
		 return _(items);
	 }
	 
 }
 
 //this function tries to get the element by the id if not exist tries get by classname else return none;
 var performGetElem = function(str,arrelem){
	 /* If arrelem is sent insert the newly goten element if it is one or concatinate array of elements if new elements are more than one */
	 /*Executing addition first signifies that subtraction has higher prority than addition in order*/
	
	 
	 
	 //break for subtraction/exemption operation
	  var sstrarr = str.Trim().split("~");
	 if(sstrarr.length > 1){
		 
		 var rtnelem = RemoveElement(sstrarr);
		 if(IsNull(arrelem) && !IsNull(rtnelem))return rtnelem; /*if no currently elements are gotten (i.e arrelem is not sent) 
								                                    return the result like that */
		  if(!IsNull(arrelem) && IsNull(rtnelem))return arrelem;
		  if(IsNull(arrelem) && IsNull(rtnelem))return null;															
		 if(IsArray(rtnelem)){ //if rst is an array concatinate with existing array of element
			 arrelem = arrelem.concat(rtnelem);
			 
		 }else{ //if not an array add to an existin array elements
			 arrelem.push(rtnelem); 
		 }
		 
		 //return the newly formed array
		 return arrelem;
	 }
	 
	 //breack down to perform the AND operation
	 var astrarr = str.Trim().split("&");
	 astrarr = astrarr.Exact();
	 if(astrarr.length > 1){
		
		 return FormAND(astrarr);
	 }
	 
	  //break string down to determin if it is multiple search
	 var nstrarr = str.Trim().split(" ");
	 nstrarr = nstrarr.Exact();
	 if(nstrarr.length > 1){
		 return Element4rmArr(nstrarr);
	 }
	 
	 
	 
	
	 
	 var rst = null;
	 if(str.substr(0,1) == "."){ //class selector
       rst = document.querySelectorAll(str);
	 }else if(str.substr(0,1) == "#"){
      rst = document.querySelector(str);
	 }else{
	  rst = document.getElementById(str);
	 }
	
					   if(IsNull(rst)){ //if no element exit with that ID try other posibilities (By Classname, By Tagname )
					    //alert('sss');
					       for(var q=0,lenq=otherfunc.length;q<lenq;q++){ // move through array of functions of alternate options
							   rst = otherfunc[q](str);// perform the alternate lookup  
							   if(!IsNull(rst)){ //if element or elements are founf
								   if(IsNull(arrelem))return rst; /*if no currently elements are gotten (i.e arrelem is not sent) 
								                                    return the result like that */
								  // if(IsArray(rst)){ //if rst is an array concatinate with existing array of element
									   return FormRst(arrelem,rst);
									   
								  // }else{ //if not an array add to an existin array elements
									   //arrelem.push(rst); 
								  // }
								   //return the newly formed array
								   //return arrelem;
								  // break;
							   }
						   }
						   //after moving checking through all posible options and no elements found
						  if(IsNull(arrelem))return rst; //if no existing array return the null rst
						  //if there exit an existing array return the array back because no elements found for all possible optons
						  return arrelem;
						//if(IsNull(rst))arrelem.push(rst) ;   
					   }else{ //if element is found by ID
						    if(IsNull(arrelem))return rst; //if no elements current exist return the gotten element
							//if some elements exits before add the new element to the array of elements and return the newly formed array
							return FormRst(arrelem,rst);
						   /*arrelem.push(rst);
						   return arrelem;*/
					   }
					   
 }
 
 //function to resolve array, making sure all element of the array contain valid value
 var ArrayExact = function(arrayobj){
	 if(IsArray(arrayobj)){
		 var rtnarr = new Array();
		 //if(typeof num == "undefined"){
			 var arrayobj2 = Object.keys(arrayobj);
		   for(const f of arrayobj2){
			  var val =  arrayobj[f];
			  if(!IsNull(val) && ((IsString(val) && !IsEmpty(val)) || (!IsString(val)) )){
				  if(IsNumber(f)){
				  rtnarr[rtnarr.length] = val;
				  }else{
				  rtnarr[f] = val;	
				  }
			  }
		   }
		 /*}else{
			 for(var ff=0; ff<arrayobj.length; ff++){
				 var val =  arrayobj[ff];
				 
				if(!IsNull(val)){
					alert(val);
					rtnarr[rtnarr.length] = val;
				}
			 }
		 }*/
		 return rtnarr;
	 }else{
		return arrayobj; 
	 }
 }
 
 Array.prototype.Exact = function(num){return ArrayExact(this,num)}
 
 
 //function to confirmly check an object classname
 var CheckClassName = function(obj,classname){
	 //var rtn = false; //default return value
	 if(IsString(obj)){ //if object classname sent is a string
	 //alert(obj);
		 var classarr = obj.split(" ");//break down to get individual class names
		 if(IsArray(classarr)){ //check if the break down is an array
			classarr = classarr.Exact(); //make sure no empty element exist in the array
			console.log(JSON.stringify(classarr));
			for(var s=0,lens=classarr.length; s<lens; s++){//loop through all the element of the array
				if(classarr[s] == null)continue;
				var clsnme = classarr[s].Trim(); //get individual classname
				if(clsnme == classname.Trim()){//compare with the compare classname
					return true; //if exist return true
				}
			}
		 }else{ //else is breack down is not an array
			if(obj.toString().Trim() == classname.Trim()){//compare the classnames
				return true;
			}
		 }
	 }else if(IsArray(obj)){//if object classname is an array
		 //loop through all the element and perform check
		 for(var v=0,lenv=obj.length; v<lenv; v++){
			 var elemobj = obj[v];
			return CheckClassName(elemobj,classname);
		 }
	 }else if(IsObject(obj)){
		 var clssname = obj.className;
		return CheckClassName(clssname,classname);
	 }
	 return false
 }
 
 Object.prototype.ClassNameIs = function(classname){return CheckClassName(this,classname)}
  String.prototype.ClassNameIs = function(classname){return CheckClassName(this.toString(),classname)}
  Array.prototype.ClassNameIs = function(classname){return CheckClassName(this,classname)}
  
  

 //----------------------------------------------------------------------

 //return object styles
  function _Style(){	
  //alert(arguments);
    var obj = null;
	/*if(obj == null){
		return null;
	}*/
	if(arguments.length > 1){
		 var arrelem = new Array(arguments.length);
		 for (i = 0,leni=arguments.length; i < leni; i++){
			 arrelem[i] = _(arguments[i]).style;
		 }
		 obj = arrelem;
	}else if(IsString(arguments[0])){
		obj = _(arguments[0]).style;
	}
	
	return obj;
  }
  function _CssToArray(css){
	  
	   var currRulearr = new Array()
	   if(css.Trim() != ""){
		  
		  var cssarr = css.Trim().split(";");
		  for (var s=0,lens=cssarr.length; s < lens ; s++){
			   if(cssarr[s].Trim() == ""){
				  continue; 
			   }
			  
			  var rulearr = cssarr[s].split(":");
			  if(rulearr.length == 2){
				  
				  currRulearr[rulearr[0]] = rulearr[1];
			  }
			  // alert(currRulearr);
		  }
		  
		  
	  }
	  return currRulearr;
  }
  String.prototype.CssToArray = function(){return _CssToArray(this.toString())}
  
  function _CssToString(cssarr){
	  var cssStr = "";
	  if(!IsArray(cssarr))return "";
	  cssarrkeys = Object.keys(cssarr);
	  for(const atr of cssarrkeys){
		  if(IsString(cssarr[atr])){
			 cssStr +=  atr + ":" + cssarr[atr] + ";"; 
		  }
	  }
	  return cssStr;
  }
  Array.prototype.CssToString = function(){return _CssToString(this)}
  
  function _SetStyle(obj, styl){
	  if(IsNull(obj) || !IsSet(obj) || IsEmpty(styl) || IsNumber(obj))return;
	    if(!IsObject(obj))return;//alert(obj);
	 var currRulearr =  obj.style.cssText.CssToArray();
	 //alert(currRulearr.length);
	 /*for(var a in currRulearr){
		 alert(a + " = " +currRulearr[a]);
	 }*/
	  //if there is cureently css style set for the object load into an array
	 //obj.style.cssText
	/*  if(!HasItem(currRulearr)){
		 obj.style.cssText = styl; 
	  }else{*/
		  var newRulearr = styl.CssToArray();
		  var newRulearrkeys = Object.keys(newRulearr);
		  //if(HasItem(newRulearr)){
			for(const atrn of newRulearrkeys){
				currRulearr[atrn] = newRulearr[atrn];
			}
		 // }
		 obj.style.cssText = currRulearr.CssToString();  
		 //alert(obj.style.cssText);
	 // }
	  //alert()
	 /* var rulearr = styl.split(";");
	  if(!HasItem(rulearr))return;*/
	  /*rulearr.Walk(function(k,v,obj){
		   if(IsString(v)){
			   styval = v.split("=");
			   obj.style[styval[0]] = styval[1];
		   }
		  },obj);*/
		  //document.getElementById().style.cssText
  }
  
 // var setstyle = function(obj, styl){SetStyle(obj, styl);}
  
  Object.prototype.SetStyle = function(styl){_SetStyle(this,styl)}
  String.prototype.SetStyle = function(styl){_(this.toString()).SetStyle(styl)}
  Array.prototype.SetStyle = function(styl){this.Walk(function(k,v,styl){
	   v.SetStyle(styl) 
	  },styl)}
 


//set opacity-------------------------------------
function _SO(obj,op){ //the initial setopacity function call - check if type of obj is array loop trough all item to set opacity
	if(IsArray(obj)){
		obj.Walk(function(k,v,obj){
			_SOStr(v,op);	
			},this);
	}else{
         _SOStr(obj,op);  
	}
}

function _SOStr(str,op){ /*real function that perform the setting - if str(the object sent) is still an array perform _SO() function on it so that it can loop throug all items to set their opacity, else if type of object is object then set the opacity as required*/
		var obj = _(str);
		if(IsNull(obj))return;
		if(IsArray(obj) && HasItem(obj)){
			_SO(obj,op);
		}else if(IsObject(obj)){
			obj.style.filter = 'alpha(opacity=' +  (op * 100) + ')'; //IE
		    obj.style.opacity = op;//Others
		}
}
  Object.prototype.SetOpacity = function(op){_SO(this,op)}
  Array.prototype.SetOpacity = function(op){_SO(this,op)}
  String.prototype.SetOpacity = function(op){_SO(this.toString(),op)}
  
var SO = _SO; //backword compatibility

//get opacity
/*function GO(obj){
	var obj = RP(obj);
	if(obj.style.opacity){
		alert('opacity = '+obj.style.opacity);
		
	}else{
		alert('opacityIE = '+obj.style.filter);
	}
}*/

//Togle Show/Hide Element (Toggle Show/Hide)-----------------------------
function _TSH(ID,Func){
	var elem = _(ID);
	if(IsNull(elem))return;
	if(IsArray(elem)){
		elem.Walk(function(k,v,obj){
		if(IsNull(v))return;
		   if(IsArray(v) || IsString(v)){
			   _TSH(v,Func);
		   }else if(IsObject(v)){
			   _TSHReal(v,Func);
		   }
		},Func);
	}else if(IsObject(elem)){
		_TSHReal(elem,Func);
	}
	
}

function _TSHReal(elem,Func){
	var state = elem.style.display;
	if (state == 'none'){
		elem.style.display = 'block';
		if(IsSet(Func) && IsSet(Func.ShowAction))Func.ShowAction(elem);
	}else{
		elem.style.display = 'none';
		if(IsSet(Func) &&  IsSet(Func.HideAction))Func.HideAction(elem);
	}
}

  Object.prototype.ToggleShowHide = function(Func){_TSH(this,Func)}
  Array.prototype.ToggleShowHide = function(Func){_TSH(this,Func)}
  String.prototype.ToggleShowHide = function(Func){_TSH(this.toString(),Func)}

var TSH = _TSH; //backword compatibility
//----------------------------------------------------------------------
var _ToArr = function(obj){
	
	if(IsNull(obj))return;
	
	var newarr = new Array();
	if(IsString(obj)){
		
		for(var s=0,lens=obj.length ; s<lens; s++){
		  newarr.push(obj[s]);	
		}
	}else if(IsNumber(obj)){
		
		obj = obj.toString();
		for(var s=0,lens=obj.length ; s<lens; s++){
			var digit = obj[s];
			if(digit != "."){
				digit = Number(digit);
			}
		  newarr.push(digit);	
		}
		
	}else if(IsArray(obj)){
		newarr = obj;
	}else{
		if(IsSet(obj.childNodes)){
			for(var w=0,lenw=obj.childNodes.length; w<lenw ; w++){
		     newarr.push(obj.childNodes[w]);
	        }
		}else if(IsSet(obj.length)){
			for(var w=0,lenw=obj.length; w<lenw ; w++){
		     newarr.push(obj[w]);
	        }
			
		}
		
	}
	
	
	return newarr;
}

Object.prototype.ToArray = function(){return _ToArr(this)}
Array.prototype.ToArray = function(){return _ToArr(this)}
String.prototype.ToArray = function(){return _ToArr(this.toString())}
Number.prototype.ToArray = function(){return _ToArr(parseFloat(this))}

//Resolve ID return string id value
function _GetId(){
	
	if(arguments.length < 1)return;
	if(arguments.length == 1){
	 ID = _(arguments[0]);	
	}else{
	 ID = _(arguments.ToArray());
	}
	
	
	if(IsNull(ID))return '';
	if(IsArray(ID)){
	 return FormarrID(ID);
	}else if(IsObject(ID)){
		return ID.id;
	}
	return '';
}



var FormarrID = function(arrobj){

			var arrid = new Array();
		    for(var w=0,lenw=arrobj.length; w<lenw; w++){
				var obj = arrobj[w];
				if(IsArray(obj)){
					arrid.concat(FormarrID(obj));
				}else{
					var id = (!IsSet(obj.id))?'':obj.id;
					arrid.push(id);
				}
			}
			return arrid;
		}


var RID = _GetId; //backward compatibility
Object.prototype.GetId = function(){return _GetId(this)}
Array.prototype.GetId = function(){return _GetId(this)}
String.prototype.GetId = function(){return _GetId(this.toString())}

//function to return element if parameter is either the elemnt or ID (Resolve Parameter)
function RP(parameter){
	if(typeof(parameter) == "object"){
		return parameter;
	}else if(typeof(parameter) == "string"){
		return _(parameter);
	}
}
//------------------------------------------------------------------------------

//Resolve Value- get the numeric value of a value containimg unit
function _RVal(val){
	if(IsString(val)){
		var rst= parseFloat(val);
		return (isNaN(rst))?0:rst;
	}
	if(IsArray(val)){
		var newarr = new Array();
		for(var q=0,lenq=val.length; q<lenq; q++){
			var rval = _RVal(val[q]);
			if(IsArray(rval)){
				newarr.concat(rval);
			}else{
				newarr.push(rval);
			}
		}
		return newarr;
	}
	if(IsObject(val)){
		var txt = val.GetText();
		if(!IsEmpty(txt)){
		   return _RVal(txt); 	
		}else{
			return 0;
		}
	}
		return val;
	
}
RVal = _RVal;
String.prototype.ToNumber = function(){return _RVal(this.toString());}
Object.prototype.ToNumber = function(){return _RVal(this);}
Array.prototype.ToNumber = function(){return _RVal(this);}
Number.prototype.ToNumber = function(){return this;}

//Resolve Value- get the numeric value of a value containimg unit  (%)
function RValOneU(val){
	
	if (parseFloat(val)){
		//alert(val);
		return parseFloat(val);
	}else{
	
	return Number(val.substr(0,val.length-1));
	}
}

//function to clear the content of an object
var _Clear = function(){
	if(!HasItem(arguments))return; //if no argument
	if(arguments.length == 1){//one argument sent
		if(IsString(arguments[0])){
			//if is string get the object or objects
			var obj = _(arguments[0]);
			
			if(IsNull(obj))return;
			_Clear(obj); //perform the same function on the object or objects
		}else if(IsArray(arguments[0])){ //if array sent
			arguments[0].Walk(function(k,v){ //move through each object of the array and perform the function on them
				   _Clear(v);
				});
			
	     }else if(IsObject(arguments[0])){ //if it is object
			 var obj = arguments[0];
			if(IsSet(obj.value)){ //if it is an input object clear the value
				obj.value = "";
			}else if(IsSet(obj.textContent)){ //if ti is a textcontent object clear the text content
				obj.textContent = "";
			}
		}
	}else{
		//if multiple argument is sent, convert it to an array and run the clear function on it
		_Clear(arguments.ToArray());
		
	}
	
}
String.prototype.Clear = function(){_Clear(this.toString())}
Object.prototype.Clear = function(){_Clear(this)}
Array.prototype.Clear = function(){_Clear(this)}

//Trim last n character 
var _StrTrimRight = function(val,n){
	n = typeof n == _UND?null:n;
  return _StrTrimDir(val,n,"r");
	
}

var _StrTrimLeft = function(val,n){
	n = typeof n == _UND?null:n;
  return _StrTrimDir(val,n,"l");
	
}

var _StrTrimDir = function(val,n,dir){
	//val - represent the object to trim (string,number,object,DOM object)
	//n - represent the number of character or item to trim
	//dir - represent the trim direction i.e right - r or left - l or both - b

	n = typeof n == _UND?null:n;
	dir = typeof dir == _UND?'b':dir; 
  if(IsString(val)){ //if is a string
	if(IsNull(n)){ //if n is null i.e no number of trim item sent, trim spaces only
		if(dir == "r"){ //if direction is right
		return val.replace(/\s+$/g,''); //trim all leading(right) white spaces
		}else if(dir == "l"){ //if direction is left
		return val.replace(/^\s+/g,''); //trim all trailing(left) white spaces	
		}else{
		return val.replace(/^\s+|\s+$/g,'');
		}
	}
	if(IsNumber(n)){ //if n is sent and is number
	  if (val != null && val.length > n){ //if the string to trim is greater than the number of character to trim
		  if(dir == "r"){ //if to trim right
		  val = val.substr(0,val.length-n); //trim n number of character from the right
		 }else if(dir == "l"){//if to trim left characters
			val = val.substr(n);
			//val = val.substr(n,val.length-n); 
		  }else{//if to trim both left and right characters
			if(val.length > n * 2){ //if the total character length if greater than the total removable character (n X 2)
			val = val.substr(n,val.length-n);
			}else{
				//return empty string if the total removable character is greater than or equals to the character length, meaning all character are trimed
				return "";
			}
		  }
	  }else{//if the total number of character to trim is greater than the real string return empty string
		val = "";  
	  }
	  return val; //return the resultant string
	}
	if(IsString(n)){ //if n  is a string trim the string
		var strlen = n.length; // get the lenght of the string to trim off
		if(strlen > val.length)return val; //if the trim lenght is greater than the real string, return back the string
		var lststr_r = ""; //the right trimable character
		var lststr_l = ""; //the left trimable character
		 if(dir == "r" || dir == "b"){//if to trim string from right or both
		//get last part of the string
		 lststr_r = val.substr(val.length - strlen,strlen);
		 }
		 if(dir == "l" || dir == "b"){//if to trim from left or both
           //get first part of the string
		 lststr_l = val.substr(0,strlen); 
		 }
		
			if((dir == "r" || dir == "b") && lststr_r == n){ //if right trim or both and right trimable character is same as sent trim character
				//return the trimed string
			val = val.substr(0,val.length - strlen);
			}
			
			if((dir == "l" || dir == "b") && lststr_l == n){//if left trim or both and left trimable character is same as sent trim character
			//return val.substr(strlen,val.length - strlen);
			val = val.substr(strlen);
			}
		
		return val;
	}
	if(IsArray(n)){ //if n is an array, meaning loop through all the item of n and use each item to run the trim function.
       for(var s=0,lens=n.length;s<lens;s++){
		   //alert(val+" ; "+n[s]);
		   val =_StrTrimDir(val,n[s],dir);//update val to the new trimed val
	   }
	   return val;
	}
	//if n is not any of the above checked type, just return val
	return val;
  }else if(IsArray(val)){//if val sent is an array, perform the trim on all elements of the array and return an array of trimed items
		var  newarr = new Array();
		if(val.length > 0){
			for(var a=0,lena=val.length; a<lena; a++){
			 var strtrim = _StrTrimDir(val[a],n,dir);
			 //if an array returned after trim just concatinate it to the result array
			  if(IsArray(strtrim))newarr.concat(strtrim);
			  //if a string is returned after trim, add it to the result array
			  if(IsString(strtrim))newarr.push(strtrim);	
			}
			
		}
		return newarr;
		
  }else if(IsObject(val)){ //if an object
	//perform trim on its text element (input - value, block elemet- textContent)
	  return _StrTrimDir(val.GetText(),n,dir);
  }	
	
}

String.prototype.StrTrimRight = function(n){return _StrTrimRight(this.toString(),n)}
String.prototype.TrimRight = function(n){return _StrTrimRight(this.toString(),n)}
Array.prototype.StrTrimRight = function(n){return _StrTrimRight(this,n)}
Array.prototype.TrimRight = function(n){return _StrTrimRight(this,n)}
Object.prototype.StrTrimRight = function(n){return _StrTrimRight(this,n)}
Object.prototype.TrimRight = function(n){return _StrTrimRight(this,n)}

String.prototype.StrTrimLeft = function(n){return _StrTrimLeft(this.toString(),n)}
Array.prototype.StrTrimLeft = function(n){return _StrTrimLeft(this,n)}
Object.prototype.StrTrimLeft = function(n){return _StrTrimLeft(this,n)}
String.prototype.TrimLeft = function(n){return _StrTrimLeft(this.toString(),n)}
Array.prototype.TrimLeft = function(n){return _StrTrimLeft(this,n)}
Object.prototype.TrimLeft = function(n){return _StrTrimLeft(this,n)}

//function to replace string
var _Replace = function(strSearch,strReplace,str){
	var newstr = "";
	if(str.Trim() != ""){
		var strarr = str.split(strSearch);
		newstr = strarr.join(strReplace);
	}
	return newstr;
}

String.prototype.Replace = function(strSearch,strReplace){return _Replace(strSearch,strReplace,this.toString());}

//return the textContent/Value of any supplied object
var _Text = function(objs,set){
	objs = _(objs);
	if(IsArray(objs)){
		//
		var newarr = new Array();
		for(var s=0,lens=objs.length; s < lens ; s++){
			if(IsNull(objs[s])){continue;}
			var rtn = _Text(objs[s],set);
			if(IsArray(rtn)){
				newarr.concat(rtn);
			}else{
				newarr.push(rtn);
			}
		}
		return newarr;
	}else if(IsObject(objs)){
		if(typeof objs.options != "undefined"){
			return objs.options[objs.selectedIndex].textContent;
		}else if(IsSet(objs.value)){
		   if(IsSet(set)){objs.value = set.toString()}
		   return objs.value;
	   }else if(IsSet(objs)){
		   if(IsSet(set)){objs.textContent = set.toString()}
		   return objs.textContent
	   }
	}
	
}

//the select element function (get selected value)
var _SelectVal = function(selectobj){
	if(IsString(selectobj)){
		selectobj = _(selectobj);
	}
	
	if(IsArray(selectobj)){
		var rstarr = new Array();
		for(var i=0,leni=selectobj.length; i<leni; i++){
			var obj = selectobj[i];
			 val = _SelectVal(obj);
			if(IsString(obj)){ //if array items are strings
				var key = obj;
				rstarr[key] = val
			}else if(typeof obj.id != "undefined"){ //if the array items and id attr exist
				var key = obj.id;
				rstarr[key] = val //insert using the object id
			}
			rstarr[i] = val; //insert using the index
		}
		return rstarr;
	}
	
	if(typeof selectobj.options != "undefined"){
	  return selectobj.options[selectobj.selectedIndex].value
	}else{
		return selectobj.Text();
	}
}
Array.prototype.Value = function(){ return _SelectVal(this)};
Object.prototype.Value = function(){ return _SelectVal(this)};
String.prototype.Value = function(){ return _SelectVal(this.toString())};

Array.prototype.GetText = function(){ return _Text(this)};
Object.prototype.GetText = function(){ return _Text(this)};
String.prototype.GetText = function(){ return _Text(this.toString())};

Array.prototype.Text = function(txt){ return _Text(this,txt)};
Object.prototype.Text = function(txt){ return _Text(this,txt)};
String.prototype.Text = function(txt){ return _Text(this.toString(),txt)};

var triml = _StrTrimRight //backword compactibility

//trim leading and trailing space
var _Trim = function(val){
	//alert(val);
	if(IsString(val)){
	 //return val.replace(/^\s+|\s+$/g,'');
	 if (typeof String.prototype.trim != 'function')return val.replace(/^\s+/, '').replace(/\s+$/, '');
     return val.trim();
	}else if(IsObject(val)){
	val = val.GetText();
	return _Trim(val);	
	}else if(IsArray(val)){
		var newarr = new Array();
		for(var s=0,lens=val.length; s < lens ; s++){
			var rtn = _Trim(val[s]);
			if(IsArray(rtn)){
				newarr.concat(rtn);
			}else if(IsString){
				newarr.push(rtn);
			}
		}
		return newarr;
	}else{
	  return val;	
	}
}
String.prototype.Trim = function(n){return _Trim(this.toString())}
Array.prototype.Trim = function(n){return _Trim(this)}
Object.prototype.Trim = function(n){return _Trim(this)}
var trim = _Trim; //Backward compactibility

//check if a string is empty
var empty = function(){
	var rst = false;
	if (arguments.length == 1){//if one value send for check
	   if(typeof arguments[0] == "string"){
		val = arguments[0];
		}else if(IsArray(arguments[0])){
		   if(arguments[0].length < 1){
			  return true;
		   }else{
			return false; 
		   }
	   }else if(typeof arguments[0] == "object"){
		 val = arguments[0].Text(); 
	   
	   }else{
		  val = ''; 
	   }
		if(trim(val) == ''){
			return true;
		}else{
			return false;
		}
	}else if(arguments.length > 1){
		var arrlen = arguments.length;
		for(i=0;i<arrlen;i++){
			 var emt = empty(arrlen[i]);
			if(emt == true){
				return  true;
			}
		}
		return false;
	}
	
}

var _SetProp = function(ID,PropName,Value,Unit){
		_Style(ID)[PropName] = Value + Unit;
		
	}
var SetProp = _SetProp //backword compatibility
//function to set an attr of an object
var _SetAttribute = function(obj,attr,value){
	obj = _(obj);
	if(!IsNull(obj)){
		if(IsArray(obj)){
			obj.Walk(function(k,v,param){
				var nobj = _(v);
				_SetAttribute(v,param[0],param[1]);
				},[attr,value]);
		}else{
			obj[attr] = value;
		}
	 
	}
}

String.prototype.SetAttribute = function(attr,value){_SetAttribute(this.toString(),attr,value)}
Array.prototype.SetAttribute = function(attr,value){_SetAttribute(this,attr,value)}
Object.prototype.SetAttribute = function(attr,value){_SetAttribute(this,attr,value)}

var isset = function(variable){
	//alert(variable)
	return (typeof variable == "undefined")?false:true;
}
var IsSet = isset;
var IsEmpty = empty;
//Object.prototype.IsSets = function(){return IsSet(this)}();

 //Maintain Browser History, dnt support < IE10
 function BackgroundRedirect(obj, title, url, hreplace){
	 if(hreplace == false){
		 //alert('enter');
		 history.pushState(obj, title, url); 
	 }else{
		 history.replaceState(obj, title, url);  
	 }

	
 };


//object to deal with browser url  manipulations (Browser history)
var URLs =  new function(){
	
	 //Set the hash part of the url
	 this.SetHash = function(hashval){
		 //alert(hashval);
		window.location.hash = (IsString(hashval))?escape(hashval):""; 
		this.SetHashDone = true;
	 }
	 this.SetHashDone = false;
	  //get the hash part of the url
	 this.GetHash = function(){
		 //alert('sss');
		var hash = window.location.hash.substring(1); 
		return unescape(hash);   
	 }
	 //Has Change function
	 this.SetHashChange = function(){
		 window.onhashchange = URLs.ChangeFunc;
	 }
	 
	 //this function will be triggered when the hash value of the url changes
	 this.ChangeFunc = function(e){
		 //checks if the operation changing the hash value is a set operation, dnt perform any thing set it back to false to allow next change operation if not a set operation
		 if(URLs.SetHashDone){
			 URLs.SetHashDone = false;
			 return;
		 }else{
			 //if ProcessHashChange function is set run it, sending the current hash value as parameter
			if(!IsNull(URLs.ProcessHashChange)){
				
				URLs.ProcessHashChange(URLs.GetHash());
			}else{return}
		 }
		 
	 }
	 
	 this.Resolve = function(url){
		 var obj = {Hash:"",Data:"",Url:"",File:"",Host:"",Ext:""};
		 var urle = url;
		 if(urle.Trim() != ""){
			 var arr = urle.split("#");
			 if(arr.length == 2){
				obj.Hash = arr[1];
				 urle = arr[0]
			 }
			 
			 arr = urle.split("?");
			 if(arr.length == 2){
				obj.Data = arr[1];
				 urle = arr[0] 
			 }
			 
			 obj.Url = urle;
			 arr = urle.split("/");
			 if(arr.length == 1){
				var file = urle;
				var arrfile = file.split(".");
				if(arrfile.length == 2){
					obj.Ext = arrfile[1];
					obj.File = file;
				}
			 }else if(arr.length > 1){
				 var file = arr[arr.length - 1];
				 var arrfile = file.split(".");
				if(arrfile.length == 2){
					obj.Ext = arrfile[1];
					obj.File = file;
				}
				var host = "";
				 for(s=0,lens=arr.length - 1; s < lens ; s++){
					 host += arr[s] + "/";
					 
				 }
				 obj.Host = host.TrimRight("/");
			 }
			 
			return obj; 
		 }else{
			return obj; 
		 }
	 }
	 
	 this.ProcessHashChange = null
	
 } 
URLs.SetHashChange(); //initialize the URLs object
String.prototype.UrlResolve = function(){return URLs.Resolve(this.toString())}

var Cookie = new function(){
	this.Set = function(cname,cvalue,exdays){
		//alert();function adjustDate() {  }
		/* var currdat = new Date();
		var currGMT = currdat.getTime() - Cookie.AjustmentTime();
		expires = currGMT + expires;
		expires = new Date(expires);
		document.cookie = name + "=" + escape (value) + ((expires) ? "; expires=" + expires.toGMTString() : "");
		console.log(document.cookie); */
		var d = new Date();
  d.setTime(d.getTime() + (exdays*24*60*60*1000));
  var expires = "expires="+ d.toUTCString();
  document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
		//alert(expires.toGMTString());
	}
	
	this.AjustmentTime = function(){
		var base = new Date(); 
		var testDate = base;
		 testDate = testDate.toLocaleString() ;
		testDate = new Date(testDate) ;
		return testDate.getTime() - base.getTime();
	}
	
	this.Get = function(cname) {
		/* labelName = labelName + "=";
	var labelLen = labelName.length; // read cookie property only once for speed 
	var cookieData = document.cookie ;
	var cLen = cookieData.length ;
	var i = 0 
	var cEnd 
	while (i < cLen) { 
	  var j = i + labelLen 
	  if (cookieData.substring(i,j) == labelName) { 
	    cEnd = cookieData.indexOf(";",j) 
		if (cEnd == -1) { 
		 cEnd = cookieData.length 
		} 
		return unescape(cookieData.substring(j, cEnd)) 
	} 
	i++ 
	} 
	return ""  */
	var name = cname + "=";
	var decodedCookie = decodeURIComponent(document.cookie);
	var ca = decodedCookie.split(';');
	for(var i = 0,leni=ca.length; i <leni; i++) {
	  var c = ca[i];
	  while (c.charAt(0) == ' ') {
		c = c.substring(1);
	  }
	  if (c.indexOf(name) == 0) {
		return c.substring(name.length, c.length);
	  }
	}
	return "";
	}
}



//function to load set image from a file
var _SetFromFile = function(img,param){
  if(typeof img.id == _UND || img.id == ""){
	  var dt = new Date();
	  img.id = "img"+dt.getTime();
  }
  if(typeof param.onload == "function"){
	  img.onload = param.onload;
  }
  if(typeof param.onerror == "function"){
	  img.onerror = param.onerror;
  }

  if(typeof param.onchange == "function"){
	  img.onchange = param.onchange;
  }

  if(typeof param.type != "string"){
	param.type = "image/*";
}
//alert()
  var maxSize = (typeof param.maxSize == _UND)?0:param.maxSize.ToNumber();
  var minSize = (typeof param.minSize == _UND)?0:param.minSize.ToNumber();
  var defaultImg = typeof param.defaultSrc == _UND?"":param.defaultSrc;
 var startfunc_str = typeof param.start == _UND?"":param.start;
if(_(img.id+'_file') == null){
  var htmls = '<input type="file" id="'+img.id+'_file" name="'+img.id+'_file" onchange="fchange(this,\''+img.id+'\');'+startfunc_str+'" style="position:absolute;display:none" data-defaultSrc="'+escape(defaultImg)+'" data-maxSize="'+maxSize+'" data-minSize="'+minSize+'" accept="'+param.type+'" />';
 document.body.insertAdjacentHTML('beforeend',htmls);
}
 //alert("cli");
 _(img.id+'_file').click();
}
function FileSize(size){
	var sizestr = "";
	if(size > 1023){
		size = Math.floor(size / 1024);
	   sizestr = size + "KB";
	}else{
		sizestr = size + "B";
	}
	return sizestr;
}
function fchange(fid,imgid){
    var file = fid;
	var maxSize = file.Data("maxSize").ToNumber();
	var minSize = file.Data("minSize").ToNumber();
	var rfile = file.files[0];
	var img = _(imgid);
	var err = "";
	if(rfile.size < minSize){ //if file size is below min size
		var sizestr = FileSize(minSize);
         err = "File too small; Minimum Upload Size ("+sizestr+")";
	}else if(rfile.size > maxSize && maxSize > 0){
		var sizestr = FileSize(maxSize);
		/*if(maxSize > 1023){
		   maxSize = Math.floor(maxSize / 1024);
		   sizestr = maxSize + "KB";
		}else{
			sizestr = maxSize + "B";
		}*/
         err = "File exceeded Maximum Upload Size ("+sizestr+")";
	}

	if(err != ""){
		//img.src = file.Data("defaultSrc");
		if(typeof img.onerror == "function"){
			img.onerror(err);
		}else{
		
		  img.alt = err.toString();
		  
		}
       
    
		return;
	}
	//alert(typeof img);
	if(typeof img.onchange == "function"){
			img.onchange(img);
		}
		
    var reader = new FileReader();
    reader.imgid = imgid;
	//if(err != ""){reader.result = file.Data("defaultSrc")}
	reader.onload = function(){_(this.imgid).src = this.result}
    reader.readAsDataURL(file.files[0]);
}
Object.prototype.SetFromFile = function(param){_SetFromFile(this,param)}

//function to automatically calculate the fit width and height
function AutoFit($padW,$padH,$width,$height,$margin){
	$margin = typeof $margin == _UND?0:$margin;
	 var $orientation = "";
  var $Ratio = $width / $height;
  //alert($Ratio);
  //determin if its landscape or portraite
if($height > $width){
	$orientation = "p";
	//check if height is greater than pad hight
	if($height >= $padH){
       $height = $padH - $margin;
	   //calculate new width
      $width = Math.floor($Ratio * $height);
	  
	}
	if($width >= $padW){
          $width = $padW - $margin;
	      //calculate new width
          $height = Math.floor($width / $Ratio);
		}
}else if($width > $height){
	$orientation = "l";
	//check if width is greater than pad width
	if($width >= $padW){
		$width = $padW - $margin;
		//claculate $height
		$height = Math.floor($width / $Ratio);
       
		//check if calculated height is greater than the pad height

	}
	 if($height >= $padH){
          $height = $padH - $margin;
	      //calculate new width
          $width = Math.floor($Ratio * $height);
		}
}
//if square
if($orientation == ""){
	
	//$style = GetValue("style",$atrrValStr);
   if($height >= $padH){
          $height = $padH - $margin;
          $width = $height;
		}
		 if($width >= $padW){
           $width = $padW - $margin;
		   $height = $width;
		  }
}

return [$width,$height,$orientation];
}

var ImageLoaders = new Array(); //array to hold all ImageLoader objects created

//the ImageLoader object
var ImageLoader = function(strict,endaction,eparam){
	//generate a unique random number as string and set it as the ImageLoader object Id
	var rand = Math.random().toString();
	while(IsSet(ImageLoaders[rand])){
		rand = Math.random().toString();
	}
	this.EndParam = (IsNull(eparam) || !IsSet(eparam))?null:eparam;
	this.id = rand;
	//alert(this.id);
	//if strict not set, set it to false (i.e - load all images irespective of each other)
	this.Strict = (IsNull(strict) || !IsSet(strict))?false:strict;
	//if the EndAction is not sent, set it to an empty function
	this.EndAction = (IsNull(endaction) || !IsSet(endaction))?function(){}:endaction;
	this.Images = new Array(); //all image paths to be loaded
	this.pointer = -1;
	this.LoadFunc = null;
	this.StrictTimeout = 2 * 1000; //30 min
	this.StrictTimmer = null;
	this.LoadTry = 4;
	this.Tries = 0;
	this.curparam = null
	this.Load = function(){
		
		 if (arguments.length == 1){
			obj = arguments[0];
		 }else if(arguments.length > 1){
			obj = arguments.ToArray(); 
		 }else{
			return; 
		 }
		  
		if(IsObject(obj)){
			
			if(IsArray(obj.image)){//if the image property of the object sent is an array set the object images property to be the array
				this.Images = obj.image	
			}else{// else add the image path to the array
			
				this.Images.push(obj.image);
				
			}
			
			this.LoadFunc = obj.onload;
			this.curparam = (IsNull(obj.param) || !IsSet(obj.param))?null:obj.param;
			
		}else if(IsArray(obj)){ //if obj sent is an array
		//form the Images array, which individual item values are used as keys to form the corressponding functions as an array
			var imgarr = new Array();
			var func = new Array();
			var params = new Array();
			for(var i=0,leni=obj.length; i < leni ; i++){
				if(!IsSet(func[escape(obj[i].image)])){
				 imgarr[i] = obj[i].image;
				 func[escape(imgarr[i])] = obj[i].onload;
				 params[escape(imgarr[i])] = (IsNull(obj[i].param) || !IsSet(obj[i].param))?null:obj[i].param;
				}
			}
			this.Images = imgarr;
			this.LoadFunc = func;
			this.curparam =  params;
			//alert(this.Images + "\n" +  this.LoadFunc);
		}else{
		  return;	
		}
		
		if(HasItem(this.Images)){ //if images has items
			
			if(!this.Strict){ //if strict is not set, perform preload of all image path and there corresponding EndAction functions
			
				for(var a=0,lena=this.Images.length; a<lena; a++){
					//alert(this.Images[a] + " , " +this.LoadFunc[a] );
					this.Preload(this.Images[a],(IsArray(this.LoadFunc))?this.LoadFunc[escape(this.Images[a])]:this.LoadFunc,(IsNull(this.curparam))?null:(IsArray(this.curparam))?this.curparam[escape(this.Images[a])]:this.curparam);
				}
				//this.Images.Walk(function(k,v,param){param.Preload(v,(IsArray(param.LoadFunc))?param.LoadFunc[k]:param.LoadFunc)},this);
			}else{
			//if strict is set start loading image by calling the next method	
		
			this.Next();	
			}
			
		}
	}
	this.Next = function(retry){
		
		if(this.StrictTimmer){ //if the loading timeout is set, canclel it. because another prload operation is to be carried out i.e the current loading is no more loading
			clearTimeout(this.StrictTimmer);
		}
		
		//if the retry variable is set and it is less than the total number of retries allowed for a particular image loading
		//increament the number of tries
		
		if(IsSet(retry) && !IsNull(retry) && this.Tries < this.LoadTry){
			
			this.Tries += 1;
			//alert(this.Tries);
		}else{ //else if not to retry, then increament the pointer so as to load the next image in the images array
			this.pointer = this.pointer + 1;
			this.Tries = 0;
			
		}
			
		//if image path still exist in the images array, perform the Preload function
		if(this.pointer < this.Images.length){
			
			var imgid = escape(this.Images[this.pointer]); 
			var parr = (IsNull(this.curparam))?null:(IsNull(this.curparam[imgid]))?null:this.curparam[imgid];
			
			this.Preload(this.Images[this.pointer],null,parr);
			
			//if value of Tries is = 0; set it to one, so that the calculated timeout time will not result to 0
			val = (this.Tries == 0)?1:this.Tries
			this.StrictTimmer = setTimeout("ImageLoaders['"+this.id+"'].Next(1)",this.StrictTimeout * val); //set the timmer to handle the timeout operation
			
		}else{//if no more image path or image to load, run the EndAction
		  this.EndParam = (!IsSet(this.EndParam) || IsNull(this.EndParam))?null:this.EndParam
		  this.EndAction(this.EndParam);	
		}
		
		
	}
	
	//function to be triggered when a particular image completely loads
	this.ImageOnload = function(){
		
		var obj = ImageLoaders[this.tag] //get the ImageLoader object by accessing it through the global ImageLoaders array using the object id as key.
		//Note- the object id is passed into the function by creating a property to the image object named tag which holds the id of the imageLoader object that create the image 
		var imgid = escape(obj.Images[obj.pointer]); 
		if(!IsNull(obj.LoadFunc)){
			if(!IsNull(obj.LoadFunc[imgid])){
		 obj.LoadFunc[imgid](this,this.param); //run the function to be executed when the image loads sending the image and the user parameter if sent.
			}
		}
		
		
		ImageLoaders[this.tag].Next(); //call the Next function again to load the next image
		
	}
	
	//internaly create an image object to tempoaryly hold the loaded image set the src and tag(the id of the ImageLoader object that create it) and set the onload handler as requierd
	this.Preload = function(src,func,param){
		
		this.image = new Image();
		this.image.src = src;
		this.image.tag = this.id;
		//this.image.onload =  function(){alert('onload')};
		this.image.onload = (this.Strict == false)?function(){func(this,this.param)}:this.ImageOnload;
		//alert(this.image.onload);
		this.image.param = param;
		//alert(src);
	}
	ImageLoaders[this.id] = this; //add this object to the array of ImageLoaders object
	
}

var FileUpload = function(maxsize,dir,ext,rootfolder){
	this.rootfolder = (typeof rootfolder == "undefined")?"":rootfolder;
	this.maxSize = (typeof maxsize == "undefined")?50000:maxsize;
	var librBase = typeof TaquaLoader.lb=='undefined' || TaquaLoader.lb==''?'TaquaLB':TaquaLoader.lb;
	this.dir = (typeof dir == "undefined")?librBase+"/Basic/ImageLoader/Files/":dir;
	this.ext = (typeof ext == "undefined")?"":ext;
	this.UploadFuncs = [];
	
	document.body.onfocus = function(e){
		
	}
	//this function 
	//function to upload image from user local machine
	this.Upload = function(filename,endfunc,processScript){
		var librBase = typeof TaquaLoader.lb=='undefined' || TaquaLoader.lb==''?'TaquaLB':TaquaLoader.lb;
		processScript = typeof processScript == _UND?librBase+"/Basic/ImageLoader/form.php":processScript;
		var iframe = document.createElement('iframe');
		var maxsize = this.maxSize;
		var dir = this.dir;
		var ext = this.ext;
		var rf = this.rootfolder;
		filename = (typeof filename == "undefined")?"":filename;
		
		iframe.src = processScript+"?maxSize="+escape(maxsize)+"&dir="+escape(dir)+"&fn="+escape(filename)+"&ext="+escape(ext)+"&rf="+escape(rf);
		//iframe.src = processScript+"?maxSize="+escape(maxsize)+"&dir="+escape(dir)+"&fn="+escape(filename)+"&ext="+escape(ext)+"&rf="+escape(rf)+"&libBaseRelatice="+escape(librBase);
		//alert(iframe.src);
		iframe.id = Math.random().toString(); //set the id of the newly created iframe to a randomly generated value 
			this.UploadFuncs[iframe.id] = (typeof endfunc == "undefined")?function(){}:endfunc;
			iframe.name = iframe.id; //set the name as the id as well
			iframe.owner = this; //create a new property owner to the iframe element object which will hold the printer object that create it
			iframe.style.position = "fixed"; //make it a css absolute value so that it stands on it own, and it does not disarrange the layout of the html element already designed
			//iframe.style.left = "-3000px";//set the left css property to -3000px to make it not visible to the user
			iframe.style.visibility = "hidden";
			//iframe.style.display = "none";
			/*iframe.style.width = "500px";
			iframe.style.height = "500px";
			iframe.style.zIndex = "5";*/
			iframe.onload = function(){//this function will be triggered when the iframe complets it loading operation
			//this in this context represent the iframe object
			   this.owner.PerformUpload(this); //call the PerformPrint method of the iframe owner(creator) Printer object
			}
			document.body.appendChild(iframe);	//add the iframe object to the body of the page
			//if(!iframe || iframe.closed || typeof iframe.closed=='undefined'){
				
			//}
	}

	
	
	
	this.PerformUpload = function(iframe){
		//alert(iframe.src);
		if(iframe.contentDocument.getElementById("tImageStatus").value.Trim() == ""){
		  iframe.contentDocument.getElementById("tImageFile").click();
		  var librBase = typeof TaquaLoader.lb=='undefined' || TaquaLoader.lb==''?'TaquaLB':TaquaLoader.lb;
		  var mine = window.open(librBase+'/Basic/ImageLoader/popup.html','','width=1,height=1,left=-20,top=-20,scrollbars=no');
		 // alert("Loading....");
 try{
    mine.close();
 }catch(e){
    var popUpsBlocked = true;
	this.UploadFuncs[iframe.id]("0~#@~The Upload Pop-up is blocked by your Browser <br/> Enable Pop-up window and Try Again");
	//document.body.removeChild(iframe);
	//alert();
}
 //mine.close()
		  return false;
		  //document.getElementById()
		}else{
			this.UploadFuncs[iframe.id](iframe.contentDocument.getElementById("tImageStatus").value);
			document.body.removeChild(iframe);
		}
		
	}
	
	//
}


  
 function  _flip(){
	 var rtnarr = Array();
	 var obj2 = Object.keys(this);
	 for(const s of obj2){
		 rtnarr[this[s]] = s;
	 }
	 return rtnarr;
 }

 function  _flipobj(){
	var rtnarr = {};
	var obj2 = Object.keys(this);
	 for(const s of obj2){
		//if (this.hasOwnProperty(s)) {
			var v = this[s].toString()
			rtnarr[v.Trim()] = s
		//}
	}
	return rtnarr;
}
 
 Array.prototype.Flip = _flip;
 Object.prototype.Flip = _flipobj;
  Array.prototype.flip = _flip;
  
/*Screen Dimension Manager*/
var ScreenMgr = new function(){
	//Default settings 
	this.ScreenWidth = 0;
	this.ScreenHeight = 0;
	this.BodyWidth =0;
	this.BodyHeight = 0;
	//document.body.addEventListener('resize',ScreenMgr.HandleResize);
	this.Calculate = function(){
		alert('inner = ' + window.innerHeight);
		alert('docElement.client = ' + document.documentElement.clientHeight);
		alert('client = ' + document.body.clientHeight);
		alert('screen. = ' + window.screen.height);
		alert('screen.avail = ' + window.screen.availHeight);
		alert('outer = ' + window.outerHeight);
		
		/*window.outerWidth = 100;
		window.outerHeight = 100;*/
	}
	
	this.HandleResize = function(){
		if(ScreenMgr.GetWidth() < window.screen.width){
			alert("Not full");
		}else{
			alert("full");
		}
	}
	
	this.GetWidth = function(){
		if(IsSet(window.innerWidth))return window.innerWidth;
		if(IsSet(document.documentElement.clientWidth))return document.documentElement.clientWidth;
		if(IsSet(document.body.clientWidth))return document.body.clientWidth;
		return 0;
	}
	
	this.Width = function(){return ScreenMgr.GetWidth()}
	this.Height = function(){return ScreenMgr.GetHeight()}
	
	this.GetHeight = function(){
		if(IsSet(window.innerHeight))return window.innerHeight;
		if(IsSet(document.documentElement.clientHeight))return document.documentElement.clientHeight;
		if(IsSet(document.body.clientHeight))return document.body.clientHeight;
		
		return 0;
	}
	
	//function to recalculate an object base on a supplied ratio
	/*this.ScaleObj = function(obj,ratio){
		obj.SetStyle("");
	}*/
}

var Screen = ScreenMgr;

//array lenth shorthand
Array.prototype.len = function(){return this.length};

//check object falls in the supplied class
var _ClassIs = function(obj,className){
	obj = _(obj);
	objclassname = obj.className;
	//check if object has no class
	if(objclassname.Trim() == ""){
		return false;
	}
	
	//check if object have only one class and it is the class checking
	if(objclassname.Trim() == className){
		return true;
	}
	
	//break down classname to know if object belong to multiple class
	var objclnarr = objclassname.split(" ");
	objclnarr = objclnarr.Exact();
	//check if object do not belong to multiple class
	if(objclnarr.length < 2){
		return false;
	}
	
	//check if object belong to sent classname
	var clsnCheck = objclnarr.InArray(className);
	if(clsnCheck.Exist){
		return true;
	}
	return false;
	
}

Object.prototype.ClassIs = function(cls){return _ClassIs(this,cls);}
String.prototype.ClassIs = function(cls){return _ClassIs(_(this.toString()),cls);}


//dragging
var Drag = function(){
	return {
		StartX:0,
	    StartY:0,
		Prop:{X:"left",Y:"top"},
		Class:[],
		objClass : "", //variable to hold the classname of the object if register by classname
		Func:null,
		Objects:[],
		ObjectPropFunc:[],
		Current:{object:null,offsetX:0,offsetY:0},
		mousedown: function(e){
			
			if(IsNull(e)){
				e=window.event;
			}
			
				Drag.Current.object = e.target != null?e.target:e.srcElement;
				//alert(Drag.Current.object.className);
				var classnamecond = false //class name checking condition variable
				
				if(typeof Drag.Current.object.className != "" && Drag.Class.length > 0){ //if object has classname and there are classname registered
				//loop through all registered classname and check if object falls in the class
				for(var w=0,lenw=Drag.Class.length;w<lenw;w++){
					var classname = Drag.Class[w];
					if(Drag.Current.object.ClassIs(classname)){
						classnamecond = true;
						Drag.objClass = classname;
						break;
					}
				}
					
				}
				//alert(Drag.Objects.InArray(Drag.Current.object).Exist);
				if((e.button == 1 && window.event != null || e.button == 0) &&( Drag.Objects.InArray(Drag.Current.object).Exist || classnamecond)){
					
					Drag.StartX = e.clientX;
					Drag.StartY = e.clientY;
					var refid = classnamecond?Drag.objClass:Drag.Current.object.id; //if class set use the classname to access its other drag details
					//set the current position or value of the object before draginng
					Drag.Current.offsetX = (Drag.ObjectPropFunc[refid].Prop.X.Trim() != "")?Drag.Current.object.style[Drag.ObjectPropFunc[refid].Prop.X.Trim()].ToNumber():0;
					Drag.Current.offsetY = (Drag.ObjectPropFunc[refid].Prop.Y.Trim() != "")?Drag.Current.object.style[Drag.ObjectPropFunc[refid].Prop.Y.Trim()].ToNumber():0;
					if(Drag.ObjectPropFunc[refid].Handler.Start != null){
						
					    Drag.ObjectPropFunc[refid].Handler.Start({DragObject:Drag.Current.object,OffsetX:Drag.Current.offsetX,OffsetY:Drag.Current.offsetY,StartX:Drag.StartX,StartY:Drag.StartY,PropX:Drag.ObjectPropFunc[refid].Prop.X.Trim(),PropY:Drag.ObjectPropFunc[refid].Prop.Y.Trim()});
					}
					document.onmousemove = Drag.mousemove;
					
					document.body.focus();
					document.onselectstart = function(){return false}
					Drag.Current.object.ondragstart = function(){return false}
					//alert("aaa");
					return false
				}else{ //reset current object back to null
					Drag.Current.object = null;
				}
			
		},
		mousemove: function(e){
			//alert("enetr");
			if(IsNull(e)){
				e=window.event;
			}
			//var refid = objClass.Trim() == ""?Drag.Current.object.id
			//_("Names").Text(e.clientX);
			var refid = Drag.objClass.Trim() == ""?Drag.Current.object.id:Drag.objClass
			//alert(Drag.ObjectPropFunc[refid].Prop)
			if(Drag.ObjectPropFunc[refid].Handler.Moving != null){
				Drag.ObjectPropFunc[refid].Handler.Moving({DragObject:Drag.Current.object,OffsetX:Drag.Current.offsetX,OffsetY:Drag.Current.offsetY,StartX:Drag.StartX,StartY:Drag.StartY,MouseX:e.clientX,MouseY:e.clientY,PropX:Drag.ObjectPropFunc[refid].Prop.X.Trim(),PropY:Drag.ObjectPropFunc[refid].Prop.Y.Trim()});
			}else{
				
			if(Drag.ObjectPropFunc[refid].Prop.X.Trim() != "")Drag.Current.object.style[Drag.ObjectPropFunc[refid].Prop.X.Trim()] = (Drag.Current.offsetX + e.clientX - Drag.StartX) + "px";
			if(Drag.ObjectPropFunc[refid].Prop.Y.Trim() != "")Drag.Current.object.style[Drag.ObjectPropFunc[refid].Prop.Y.Trim()] = (Drag.Current.offsetY + e.clientY - Drag.StartY) + "px";
			}
		},
		mouseup: function(e){
			if(IsNull(e)){
				e=window.event;
			}
			
			if(!IsNull(Drag.Current.object)){
				var refid = Drag.objClass.Trim() == ""?Drag.Current.object.id:Drag.objClass
			if(Drag.ObjectPropFunc[refid].Handler.Stop != null){
					    Drag.ObjectPropFunc[refid].Handler.Stop({DragObject:Drag.Current.object,EndX:e.clientX,EndY:e.clientY,PropX:Drag.ObjectPropFunc[refid].Prop.X.Trim(),PropY:Drag.ObjectPropFunc[refid].Prop.Y.Trim()});
					}
				document.onmousemove = null;
				document.onselectstart = null;
				Drag.Current.object.ondragstart = null;
				Drag.objClass = "";
				Drag.Current.object = null;
			}
		},
		register: function(obj,prop,func){
			//alert("reg");
			
			func = func || {Moving:null,Start:null,Stop:null};
			prop = prop || {X:"left",Y:"top"}
			if(IsString(obj)){
				obj = obj.Trim();
				if(obj.substr(0,1) == "#"){
					//register the string as classname
					var clname= obj.substr(1);
					Drag.Class.push(clname);
					Drag.ObjectPropFunc[clname] = {Prop:prop,Handler:func};
					return;
				}
			}
			
			obj = _(obj);
			if(obj == null)return;
			if(IsArray(obj)){
				for(var g=0,leng=obj.length; g<leng; g++){
					var nobj = _(obj[g]);
					Drag.register(nobj,prop,func);
				}
			}else if(IsObject(obj)){
				/*if(typeof obj.id == "undefined" || obj.id.Trim() == ""){
					var dt = new Date()
					obj.id = "id_"+dt.getTime();
				}*/
				var objid = NeedID(obj);
				var objext = Drag.Objects.InArray(obj);
				if(!objext.Exist){
				 Drag.Objects.push(obj);
				// alert("push");
				 Drag.ObjectPropFunc[objid] = {Prop:prop,Handler:func}
				}
			}
			
		}
	}
	
}();
	document.onmousedown = Drag.mousedown;
	document.onmouseup = Drag.mouseup;
	/*Drag.Prop.X = "left";
	Drag.Prop.Y = "top";
	Drag.Class = "Fender";*/
//function to make sure an object has id
function NeedID(obj){
	if(IsNull(obj))return null;
	    if(typeof obj.id == "undefined" || obj.id.Trim() == ""){
					var dt = new Date();
					var nid = "id_"+dt.getTime()+Math.Random();
					while(_(nid) != null){
						var nid = "id_"+dt.getTime()+Math.Random(); 
					}
					obj.id = nid;
					
		}
		return obj.id;
}
//alert('basic');
function handlemove(param){
	//)alert("aa");
	param.object.style[param.propX] = (param.offsetX + param.mouseX - param.startX) + "px";
	param.object.style[param.propY] =(param.offsetY + param.mouseY - param.startY) + "px";
}

//get the data attrribute of an object
function GetDataAttr(obj,atr,value){
	if(IsArray(obj)){
		var rstarr = new Array();
		for(var s=0,lens=obj.length;s<lens;s++){
			var objn = obj[s];
			//alert(obj.length);
			rstarr.push(GetDataAttr(objn,atr,value));
		}
		return rstarr;
	}else{
	  if(typeof value == _UND){
		  var val = obj.getAttribute("data-"+atr);
		  return val;
	  }else{
		  
		  obj.setAttribute("data-"+atr,value);
		  return value
	  }
	}
}
Object.prototype.Data = function(atr,val){return GetDataAttr(this,atr,val)}
Array.prototype.Data = function(atr,val){return GetDataAttr(this,atr,val)}

//function to run all func
var Run = function(func,param){
	if(IsString(func)){
		//__('If function is string');
		//__('Trim the function brackets if exist');
		   func = func.Trim().TrimRight(")").Trim().TrimRight("(");
		// __('Form the string function with parameter if exist and set to the Options parameter :'+func);
		  if(typeof param != _UND){
			  param = func + "("+(IsNumber(param)?param:"'"+param.toString()+"'")+")";
		  }else{
			  param = func + "()";
		  }
		  
		  //__('Reset the function to function that runs the string which is sent as parameter');
		  func = function(para){
			eval(para);  
		  }
		
	}else{
		param = typeof param == _UND?null:param;
	}
	
	func(param);
}

 var _DataStrToArray = function(str,order){
	 order = typeof order == _UND?false:order;
	 var rtArr = {};
	 var orderarr = new Array();
	 var strarr = str.split("&");
	 if(strarr.length > 0){
		 for(var s=0,lens=strarr.length; s<lens; s++){
			 var atrrVal = strarr[s].split("=");
			 if(atrrVal.length == 2){
				 //atrrVal[1]=atrrVal[1].Replace("%2A","*").Replace("%2B","+").Replace("%2F","/").Replace("%40","@");
				 rtArr[atrrVal[0]] = rawunescape(atrrVal[1]);
				 if(order)orderarr[s] = atrrVal[0];
			 }
			 
		 }
		 
	 }
	 if(order){
		return {NewArray:rtArr,OrderArray:orderarr} 
	 }else{
	 return rtArr;
	 }
	 
 }
 
 var rawescape = function(str){
	 var esstr = escape(str);
	 esstr = esstr.Replace("*","%2A").Replace("+","%2B").Replace("/","%2F").Replace("@","%40");
	 return esstr;
 }
 
 var rawunescape = function(str){
	 str = str.Replace("%2A","*").Replace("%2B","+").Replace("%2F","/").Replace("%40","@").Replace("%C2%A0"," ");//%C2%A0
	 return unescape(str);
 }
 
 
 String.prototype.ToDataArray = function(order){return _DataStrToArray(String(this),order);};
/* function aaa(){alert(this.id)}
 Object.prototype.namel = aaa;*/
 var Keyboard =  {
		 KeyPress:function(e){
			  if(window.event){ // IE                 
                keynum = e.keyCode;
            }else if(e.which){ 
                    // Netscape/Firefox/Opera                   
                    keynum = e.which;
			}
					keynum = (typeof keynum != "undefined")?keynum:0;
                    var char = String.fromCharCode(keynum);
                    var unicode=e.keyCode? e.keyCode : e.charCode;
					return {Code:keynum,Char:char,Unicode:unicode}
		 },
		 _PlaceCursorAt:function(node,postion){
			var isinput = typeof node.value != _UND?true:false;
			 var str = isinput?node.value:node.textContent;
			 var pos = typeof position == _UND?str.length:postion;
			 node.focus();
var caret = pos; // insert caret after the 10th character say
var range = document.createRange();
range.setStart(node, caret);
range.setEnd(node, caret);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
		 }
		 
	 }
Object.prototype.PlaceCursorAt = function(position){
	Keyboard._PlaceCursorAt(this,position);
}
	 var Generator = {
		 Random:{
			 Number:function(len){
				 len = typeof len == _UND?1:isNaN(parseInt(len))?1:parseInt(len);
				 return Math.floor(Math.random() * len);
			 },
             String:function(len,charset){
				 len = typeof len == _UND?1:isNaN(parseInt(len))?1:parseInt(len);
				 var chr = "abcdefghijklmnopqrstuvwxyzQWERTYUIOPASDFGHJKLZXCVBNM";
				 charset = typeof charset == _UND?chr:charset;
				 var str = "";
				 for(var d=0; d < len ; d++){
					 var rnum = Generator.Random.Number(chr.length);
					 str += charset.substr(rnum,1);
				 }
				 return str;
               
			 }
		 }
	 }

	 function SupportHTML5(){
		 return (typeof document.createElement('canvas').getContext === "function") ;
	 }

	 //DataString Object
	 var DataString = {
		 Get:function(datastr,key){
            var ref = key + "=";
			var pos = datastr.indexOf(ref);
			if(pos > -1){//if cell data exist in data string
					 var nxtind = datastr.indexOf("&",pos+ref.length);
					// var lst = false;
					 if(nxtind == -1){
						 var rawvalue = datastr.substring(pos+ref.length);
					 }else{
					 var rawvalue = datastr.substring(pos+ref.length,nxtind);
					}
					return rawunescape(rawvalue);

			}else{
				return "";
			}
		 },
		 Set:function(datastr,key,newval){
			// var datastr = spdatastrObj.value;
				// var rownum = idarr[2].ToNumber() - 1;
				// var colnum = cell.Data("column");
				 var ref = key + "=";
				 var first = false; //determine if the item is the first
				 var last = false;
				 //check if ref start 
				 if(datastr.substr(0,ref.length) == ref){
					 var pos =0;first = true;
				 }else{ //check if withe string
					 var pos = datastr.indexOf("&"+ref);
					 //if seen use the position of the ref without &
					 if(pos > 0)pos = pos+1;
				 }
				 
				 var rawnewvalue = typeof newval == _UND?null:rawescape(newval);
				 if(typeof key == "object"){
				  if(rawnewvalue == null){ //if to delete
                   return datastr.replace(key,"");
				  }
				  return datastr.replace(key,newval);
				}
				 if(pos > -1){//if cell data exist in data string
					 var nxtind = datastr.indexOf("&",pos+ref.length);
					// var lst = false;
					 if(nxtind == -1){ //if no more data exist
						last = true;
						//get the remaining string as value
						 var rawvalue = datastr.substring(pos+ref.length);
					 }else{ //if other data exist
						//get the string after the = and the next & as value
					 var rawvalue = datastr.substring(pos+ref.length,nxtind);
					}
					if(rawnewvalue == null){ //if to delete
						var dem = (nxtind == -1)?"":"&"; //if last
						var pre = (pos > 0 && nxtind == -1)?"&":""; //if the last but not the first
						if(pos == 0 && nxtind == -1){ //if is the first and the last
                          dem = ""; pre = "";
						}
                      return datastr.replace(pre+ref+rawvalue+dem,"");
					}
					 //alert(rawvalue);
                    var value = rawunescape(rawvalue);
				   if(value == newval){ //if no changes
                       return datastr;
					 }
					 var dem = "&"; var pre = "&";
					 if(first)pre = "";
					 if(last)dem = "";


					   //replace the to newvalue in datastring 
                     // alert(ref+rawvalue+" : " + ref+rawnewvalue);
					    var newdatstr = datastr.replace(pre+ref+rawvalue+dem,pre+ref+rawnewvalue+dem);
						//alert(newdatstr);
						return newdatstr;
					  // spdatastrObj.value = datastrn;
				   //}
				 }else{
					 //add new
                     return datastr + "&" + ref + rawnewvalue;
					 //spdatastrObj.value = datastrn;
                  // value =  "NE";
				 }
		 },
		 Remove:function(datastr,key){
			// alert(typeof key);
            return DataString.Set(datastr,key);
		 },
		 RangeGet:function(datastr,tot){
            //break to _DataArray 
			var Dataarr = datastr.ToDataArray(true);
			//loop through order array 
			for(var s=0,lens=Dataarr.OrderArray.length; s<lens; s++){
				var key = Dataarr.OrderArray[s];
				//check if key has < or <
				var sym = key.substr(0,1);
				if(sym == "<" || sym == ">"){
                   var num = key.substr(1).ToNumber();
				   var cond = (sym == "<")?tot<num:tot>num;
				   if(cond){ //if true
                     return Dataarr.NewArray[key];
				   }
				   continue;
				}

				//check if is range
				var splitv = key.split("-");
                if(splitv.length == 2){
					if(tot >= splitv[0].ToNumber() && tot <= splitv[1].ToNumber()){
						return Dataarr.NewArray[key];
					}
					continue;
				}

				//check if it is the num
				if(key == tot + ""){
					return Dataarr.NewArray[key];
				}
			}

			return "-";

		 }
	 }

	 //function to convert array to data string
	 function _ArrayToString(cssarr){
		var cssStr = "";
		if(!IsArray(cssarr) && !IsObject(cssarr))return "";
		var cssarrkeys = Object.keys(cssarr);
		for(const atr of cssarrkeys){
			if(IsString(cssarr[atr])){
			   cssStr +=  atr + "=" + cssarr[atr] + "&"; 
			}
		}
		return cssStr.TrimRight("&");
	}

	Array.prototype.ToDataString = function() {
		return _ArrayToString(this);
	}
	Object.prototype.ToDataString = function() {
		return _ArrayToString(this);
	}

	 	 //function to asign event handler to object events
		  var Handlers = {
			//assign an event handler to element(s)
			_Assign:function(eventName,element,handler){
				if(IsArray(element)){ //if array, get individual item and perform asign
					for(var aad=0,lenaad=element.length; aad < lenaad; aad++){
						elementc = element[aad];
						Handlers._Assign(eventName,elementc,handler);
					}
					return;
				}else if(IsString(element)){ //
				   Handlers._Assign(eventName,_(element),handler);
				   return;
				}
				if (element.addEventListener) {
					   element.addEventListener(eventName, function(ev){handler(ev,element)},false);
				   }
				   else if (element.attachEvent) {
					   element.attachEvent('on' + eventName, function(ev){handler(ev,element)});
				   }
				   else {
					   element['on' + eventName] = function(){handler(ev,element)};
				   }
				 //obj.addEventListener(ev,func);
			}
		}
   Object.prototype.Assign = function(eventName,handler){
	   Handlers._Assign(eventName,this,handler);
   }
   Array.prototype.Assign = function(eventName,handler){
	   Handlers._Assign(eventName,this,handler);
   }
   String.prototype.Assign = function(eventName,handler){
	   Handlers._Assign(eventName,this.toString(),handler);
   }

   //Table to Excel
   var tableToExcel = (function() {
	var uri = 'data:application/vnd.ms-excel;base64,'
	  , template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>'
	  , base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }
	  , format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) }
	return function(table, name) {
	 // if (!table.nodeType) table = document.getElementById(table)
	  //var ctx = {worksheet: name || 'Worksheet', table: table.innerHTML}
	  var ctx = {worksheet: name || 'Worksheet', table: table}
	  window.location.href = uri + base64(format(template, ctx))
	}
})();

//object to perform operations on date in webdesk
var DateObject = new function(){
	this.IsDate = function(dob,pat){
		var dobarr = dob.split("/");
	  if(dobarr.length != 3){ //check invalid date of birth patern
		  return "Wrong Date";
	  }
	  //check day
	  var dd = parseInt(dobarr[0],10);
	  if(isNaN(dd)){
		  return "Wrong Day";
	  }
	  if(dd < 1 || dd > 31){
		  return "Wrong Day";
	  }
	  //check month
	  var mm = parseInt(dobarr[1],10);
	  if(isNaN(mm)){
		  return "Wrong Month";
	  }
	  if(mm < 1 || mm > 12){
		  return "Wrong Month";
	  }
	  //check year
	  /*var yy = parseInt(dobarr[2],10);
	   if(isNaN(yy)){
		  return "Wrong Year";
	  }
	  if(dobarr[2].length != 2 && dobarr[2].length != 4){
		  return "Wrong Year";
	  }*/
	  var isy = DateObject.IsYear(dobarr[2]);
	  if(isy !== true)return isy;
	  return true;	
	}
	
	this.IsYear = function(year){
		 var yy = parseInt(year,10);
	   if(isNaN(yy)){
		  return "Wrong Year";
	  }
	  if(year.length != 2 && year.length != 4){
		  return "Wrong Year";
	  }
		return true;
	}
}


String.prototype.IsDate = function(pat){return DateObject.IsDate(this.toString(),pat)};
String.prototype.IsYear = function(){return DateObject.IsYear(this.toString())};

/* Run function when user scroll document the document :: 18/09/2017*/
//global array to hold all scroll run details
var Scrollfuncs = []; //array to hold window scroll functions
var objscrollarr = []; //hold all object and thier equivalent function

//run all the function added to window scroll functions arry
function _RunAllScrolFunc(){
	var scrolt = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; //get the curent window srolltop and send to all the registered functions
	for(var s=0,lens=Scrollfuncs.length; s<lens; s++){
		if(IsFunction(Scrollfuncs[s])){
		 Scrollfuncs[s](scrolt); //run the function
		}
	}
}

Function.prototype.RunWhenScroll = function(obj){
	 obj = obj || window;
	 _WhenScrollRun(obj,this)
}

//function to add object and its scroll function to the global array
function _WhenScrollRun(obj,func){
	if(obj == window){ //if the object is window
		if(Scrollfuncs.length <= 0){
			window.onscroll = _RunAllScrolFunc;
		}
		Scrollfuncs.push(func);
		return;
	}
	objid = NeedID(obj);
	if(typeof objscrollarr[objid] == _UND){
		objscrollarr[objid] = [];
		obj.onscroll = _RunOnScroll;
	}
	objscrollarr[objid].push(func); //add the object and its function to the array
	
}
var _RunOnScroll = function(e){
   var obj = e.target;
   if(typeof obj != _UND && obj != null){
	   var st = typeof obj.scrollTop != _UND?obj.scrollTop:-1;
	   //alert(st);
       objscrollarr[obj.id].Walk(function(k,v,st){
         v(st);
	   },st);
   }
}
Object.prototype.WhenScrollRun = function(func){_WhenScrollRun(this,func)}

/*
 * onDOMReady
 * Copyright (c) 2009 Ryan Morr (ryanmorr.com)
 * Licensed under the MIT license.
 */
function onDOMReady(fn, ctx) {
    var ready, timer;
    var onStateChange = function(e) {
        if (e && e.type == "DOMContentLoaded") {
            fireDOMReady()
        } else if (e && e.type == "load") {
            fireDOMReady()
        } else if (document.readyState) {
            if ((/loaded|complete/).test(document.readyState)) {
                fireDOMReady()
            } else if (!!document.documentElement.doScroll) {
                try {
                    ready || document.documentElement.doScroll('left')
                } catch (e) {
                    return
                }
                fireDOMReady()
            }
        }
    };
    var fireDOMReady = function() {
        if (!ready) {
            ready = true;
            fn.call(ctx || window);
            if (document.removeEventListener) document.removeEventListener("DOMContentLoaded", onStateChange, false);
            document.onreadystatechange = null;
            window.onload = null;
            clearInterval(timer);
            timer = null
        }
    };
    if (document.addEventListener) document.addEventListener("DOMContentLoaded", onStateChange, false);
    document.onreadystatechange = onStateChange;
    timer = setInterval(onStateChange, 5);
    window.onload = onStateChange
};


//})(window);

/*window.onscroll = function() {myFunction()};
function myFunction() {
    var navbar = document.getElementById("myNavbar");
    if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 100) {
        navbar.className = "w3-bar" + " w3-card-2" + " w3-animate-top" + " w3-white";
    } else {
        navbar.className = navbar.className.replace(" w3-card-2 w3-animate-top w3-white", "");
    }
}*/

   


