/*
	Written by Adam M. Euans
			   (Initally written by digitalbush.com)
	Date: 2008/01/09

	Overview:
	This is a masked input plugin for the initally for jQuery, but ported to MooTools javascript library. It allows a user to more easily enter fixed width input where you would like them to enter the data in a certain format (dates,phone numbers, etc). It has been tested on Internet Explorer 6/7, Firefox 1.5/2, Safari, and Opera.

	A mask is defined by a format made up of mask and placeholder characters. Any character not in the placeholder character list below is considered a mask character. Mask characters will be automatically entered for the user as they type and will not be able to be removed by the user.

	The following placeholder characters are predefined:
		* a - Represents an alpha character (A-Z,a-z)
		* 9 - Represents a numeric character (0-9)
		* * - Represents an alphanumeric character (A-Z,a-z,0-9) 
	
	Functions:
		addPlaceholder	: Add additional regular expression place holders. Default = a, 9, *
		mask			: Function that sets the mask
		inlineMask		: Function that will look for inline masks

	Options:
		placeholder		: Update the place holder.  Default = "_"		
		destroyInvalid	: Clear the input box if the input value doesn't match mask
		stripMask		: Removes the mask from the valid input
		onComplete		: What to do after the mask is complete
	
	Inline Options:
		mask			: Mask to apply
		maskSettings	: Options to apply to mask

	Usage:
		<script src="mooMask.js" type="text/javascript"></script>
		<script type="text/javascript">
		<!--
			mooMask = new mooMask();
			mooMask.mask($('inputField'), '(999) 999-9999');

			- or - 

			mooMask = new mooMask();
			mooMask.inlineMask();
		//-->
		</script>
		<form>
			<input name='test1' id='test1' mask='(999) 999-9999' maskOptions='{placeholder:'*'}'
		</form>

*/
var mooMask = new Class({
	initialize: function(options){
		$extend(this.options, options);
    },

	addPlaceholder: function(c,r){
		this.options.charMap[c]=r;
	},
	
	options: {
		onComplete: null,
		placeholder: "_",
		destroyInvalid: true,
		stripMask: false,
		charMap: {
			'9':"[0-9]",
			'a':"[A-Za-z]",
			'*':"[A-Za-z0-9]"
		}
	},

	inlineMask: function(){
		$$('INPUT[mask]').each(function(el){
			this.mask(el, el.getProperty('mask'),  JSON.decode(el.getProperty('maskOptions')) );
		}, this);
	},

	mask: function(el, mask, options){
	    if (el) {
    		var el =($type(el) == 'array')? el : [$(el)];
    		el.each(function(ele){
    			this._mask(ele, mask, options)
    		}, this);
    	}
	},

	_mask: function(el, mask, options) {			
			var options = $extend({
				onComplete: this.options.onComplete,
				placeholder: this.options.placeholder,
				destroyInvalid: this.options.destroyInvalid,
				stripMask: this.options.stripMask				
			}, options);

			var charMap = this.options.charMap;

			//Build Regex for format validation
			var reString="^";	
			for(var i=0;i<mask.length;i++)
				reString+=(charMap[mask.charAt(i)] || ("\\"+mask.charAt(i)));					
			reString+="$";
			var re = new RegExp(reString);
			
			//return this.each(function(){		
				var input=$(el);
				var buffer=new Array(mask.length);
				var locked=new Array(mask.length);		

				//Build buffer layout from mask
				for(var i=0;i<mask.length;i++){
					locked[i]=charMap[mask.charAt(i)]==null;
					buffer[i]=locked[i]?mask.charAt(i):options.placeholder;
				};
				var msk = buffer.join('');
				
				//Event Bindings
				input.addEvent('focus', function(){					
					checkVal();
					writeBuffer();
					setCaretPosition(el,0);		
				});

				input.addEvent('blur', checkVal);
				
				//Paste events for IE and Mozilla thanks to Kristinn Sigmundsson
				if (window.msie) 
					input.onpaste= function(){setTimeout(checkVal,0);};                     
				else if (window.gecko)
					input.addEvent('input',checkVal,false);
				
				var ignore=false;  //Variable for ignoring control keys
				
				input.addEvent('keydown', function(e){
					var pos=getCaretPosition(this);	
					var e = new Event(e);
					var k = e.code;
					ignore=(k < 16 || (k > 16 && k < 32 ) || (k > 32 && k < 41));
					//delete selection before proceeding
					if((pos.begin-pos.end)!=0 && (!ignore || k==8 || k==46)){
						clearBuffer(pos.begin,pos.end);
					}	
					//backspace and delete get special treatment
					if(k==8){//backspace
						while(pos.begin-->=0){
							if(!locked[pos.begin]){								
								buffer[pos.begin]=options.placeholder;
								if(window.opera){
									//Opera won't let you cancel the backspace, so we'll let it backspace over a dummy character.								
									writeBuffer(pos.begin);
									setCaretPosition(el,pos.begin+1);
								}else{
									writeBuffer();
									setCaretPosition(el,pos.begin);
								}	
								break;						
							}
						}	
						e.stop();				
					}else if(k==46){//delete
						clearBuffer(pos.begin,pos.begin+1);
						writeBuffer();
						setCaretPosition(el,pos.begin);
						e.stop();
					}else if (k==27){
						clearBuffer(0,mask.length);
						writeBuffer();
						setCaretPosition(el,0);
						e.stop();
					}
										
				});

				input.addEvent('keypress', function(e){
					if(ignore){
						ignore=false;
						return;
					}

					e=new Event(e);
					var k=e.code;

					var pos=getCaretPosition(el);					
					var caretPos=pos.begin;	
					
					if(e.control || e.alt){//Ignore
						return true;
					}else if ((k>=41 && k<=122) ||k==32 || k>186){//typeable characters
						while(pos.begin<mask.length){	
							var reString=charMap[mask.charAt(pos.begin)];
							var match;
							if(reString){
								var reChar=new RegExp(reString);
								match=String.fromCharCode(k).match(reChar);
							}else{//we're on a mask char, go forward and try again
								pos.begin+=1;
								pos.end=pos.begin;
								caretPos+=1;
								continue;
							}

							if(match)
								buffer[pos.begin]=String.fromCharCode(k);
							else{
								caretPos-=1;
								e.stop();
							}

							while(++caretPos<mask.length){//seek forward to next typable position
								if(!locked[caretPos])							
									break;							
							}
							break;
						}
					}else
						e.stop();								

					writeBuffer();
					if(options.onComplete && caretPos>=buffer.length) {
						options.onComplete.call(input);
						clearBuffer(0,mask.length);
					} else {
						setCaretPosition(el,caretPos);
					}
					
					e.stop();				
				});

				//Helper Methods
				function clearBuffer(start,end){
					for(var i=start;i<end;i++){
						if(!locked[i])
							buffer[i]=options.placeholder;
					}				
				};
				
				function writeBuffer(pos){
					var s="";
					for(var i=0;i<mask.length;i++){					
						s+=buffer[i];
						if(i==pos)
							s+=options.placeholder;
					}
					input.value = s;
					return s;
				};
				
				function checkVal(){	
					//try to place charcters where they belong
					var test=input.value;
					var pos=0;
					for(var i=0;i<mask.length;i++){
						if(!locked[i]){
							while(pos++<test.length){
								//Regex Test each char here.
								var reChar=new RegExp(charMap[mask.charAt(i)]);
								if(test.charAt(pos-1).match(reChar)){
									buffer[i]=test.charAt(pos-1);
									break;
								}									
							}
						}
					}
					var s=writeBuffer();
					if(!s.match(re)){
						//console.log(stripMask())
						if(options.destroyInvalid || (!options.destroyInvalid && (msk == test))){
							input.value = "";	
							clearBuffer(0,mask.length);
						}
					}else if(options.stripMask){
						input.value = stripMask();
					}					
				};	

				function stripMask(){
					var r = '';
					var s = input.value;
					for(i=0; i<locked.length; i++){
						if(!locked[i]){ r += s.charAt(i); }
					}
					return r
				};
				
			//Helper Functions for Caret positioning
				function getCaretPosition(ctl){
					var res = {begin: 0, end: 0 };
					if (ctl.setSelectionRange){
						res.begin = ctl.selectionStart;
						res.end = ctl.selectionEnd;
					}else if (document.selection && document.selection.createRange){
						var range = document.selection.createRange();			
						res.begin = 0 - range.duplicate().moveStart('character', -100000);
						res.end = res.begin + range.text.length;
					}
					return res;
				};

				function setCaretPosition(ctl, pos){
					if(ctl.setSelectionRange){
						ctl.focus();
						ctl.setSelectionRange(pos,pos);
					}else if (ctl.createTextRange){
						var range = ctl.createTextRange();
						range.collapse(true);
						range.moveEnd('character', pos);
						range.moveStart('character', pos);
						range.select();
					}
				};
		}
});

//valida telefone
function ValidaTelefone(tel){
    if (!tel) {
        tel = this;
    }
    ver = /\(\d{2}\)\ \d{4}\-\d{4}/
    if(!ver.test(tel.value))
        tel.value = '';
}

//valida CEP
function ValidaCep(cep){
    if (!cep) {
        cep = this;
    }
    ver = /\d{2}\.\d{3}\-\d{3}/
    if(!ver.test(cep.value))
        cep.value = '';
}

//valida data
function ValidaData(date){
    if (!date) {
        date = this;
    }
    ver = /\d{2}\/\d{2}\/\d{4}/
    if(!ver.test(date.value))
        date.value = '';
}

//valida o CPF digitado
function ValidarCPF(Objcpf){
    if (!Objcpf) {
        Objcpf = this;
    }
    var cpf = Objcpf.value;
    exp = /\.|\-/g
    cpf = cpf.toString().replace( exp, "" ); 
    var digitoDigitado = eval(cpf.charAt(9)+cpf.charAt(10));
    var soma1=0, soma2=0;
    var vlr =11;
    
    for(i=0;i<9;i++){
            soma1+=eval(cpf.charAt(i)*(vlr-1));
            soma2+=eval(cpf.charAt(i)*vlr);
            vlr--;
    }       
    soma1 = (((soma1*10)%11)==10 ? 0:((soma1*10)%11));
    soma2 =(((soma2+(2*soma1))*10)%11);
    var digitoGerado=(soma1*10)+soma2;
    if(digitoGerado!=digitoDigitado) {      
        Objcpf.value = '';
    }
}

//valida o CNPJ digitado
function ValidarCNPJ(ObjCnpj){
    if (!ObjCnpj) {
        ObjCnpj = this;
    }
    var cnpj = ObjCnpj.value;
    var valida = new Array(6,5,4,3,2,9,8,7,6,5,4,3,2);
    var dig1= new Number;
    var dig2= new Number;
    
    exp = /\.|\-|\//g
    cnpj = cnpj.toString().replace( exp, "" ); 
    var digito = new Number(eval(cnpj.charAt(12)+cnpj.charAt(13)));
            
    for(i = 0; i<valida.length; i++){
            dig1 += (i>0? (cnpj.charAt(i-1)*valida[i]):0);  
            dig2 += cnpj.charAt(i)*valida[i];       
    }
    dig1 = (((dig1%11)<2)? 0:(11-(dig1%11)));
    dig2 = (((dig2%11)<2)? 0:(11-(dig2%11)));
    
    if(((dig1*10)+dig2) != digito)  
            ObjCnpj.value = '';
                
}