﻿/// <reference path="../../../lib/jquery-1.2.6.js" />



/*



* Copyright (c) 2007-2008 Josh Bush (digitalbush.com)



* 



* Permission is hereby granted, free of charge, to any person



* obtaining a copy of this software and associated documentation



* files (the "Software"), to deal in the Software without



* restriction, including without limitation the rights to use,



* copy, modify, merge, publish, distribute, sublicense, and/or sell



* copies of the Software, and to permit persons to whom the



* Software is furnished to do so, subject to the following



* conditions:



* The above copyright notice and this permission notice shall be



* included in all copies or substantial portions of the Software.



* 



* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,



* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES



* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND



* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT



* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,



* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING



* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR



* OTHER DEALINGS IN THE SOFTWARE. 



*/







/*



* Version: 1.2.1



* Release: 2008-12-21



*/



(function($) {



	var pasteEventName = ($.browser.msie ? 'paste' : 'input') + ".mask";



	var iPhone = (window.orientation!=undefined); 







	$.mask = {



		//Predefined character definitions



		definitions: {



			'9': "[0-9]",



			'a': "[A-Za-z]",



			'*': "[A-Za-z0-9]"



		}



	};







	$.fn.extend({



		//Helper Function for Caret positioning



		caret: function(begin, end) {



			if (this.length == 0) return;



			if (typeof begin == 'number') {



				end = (typeof end == 'number') ? end : begin;



				return this.each(function() {



					if (this.setSelectionRange) {



						this.focus();



						this.setSelectionRange(begin, end);



					} else if (this.createTextRange) {



						var range = this.createTextRange();



						range.collapse(true);



						range.moveEnd('character', end);



						range.moveStart('character', begin);



						range.select();



					}



				});



			} else {



				if (this[0].setSelectionRange) {



					begin = this[0].selectionStart;



					end = this[0].selectionEnd;



				} else if (document.selection && document.selection.createRange) {



					var range = document.selection.createRange();



					begin = 0 - range.duplicate().moveStart('character', -100000);



					end = begin + range.text.length;



				}



				return { begin: begin, end: end };



			}



		},



		unmask: function() { return this.trigger("unmask"); },



		mask: function(mask, settings) {



			if (!mask && this.length > 0) {



				var input = $(this[0]);



				var tests = input.data("tests");



				return $.map(input.data("buffer"), function(c, i) {



					return tests[i] ? c : null;



				}).join('');



			}



			settings = $.extend({



				placeholder: "_",



				completed: null



			}, settings);







			var defs = $.mask.definitions;



			var tests = [];



			var partialPosition = mask.length;



			var firstNonMaskPos = null;



			var len = mask.length;







			$.each(mask.split(""), function(i, c) {



				if (c == '?') {



					len--;



					partialPosition = i;



				} else {



					tests.push(defs[c] ? new RegExp(defs[c]) : null);



					if (tests[tests.length - 1] && firstNonMaskPos == null)



						firstNonMaskPos = tests.length - 1;



				}



			});







			return this.each(function() {



				var input = $(this);



				var buffer = $.map(mask.split(""), function(c, i) { if (c != '?') return defs[c] ? settings.placeholder : c });



				var ignore = false;  			//Variable for ignoring control keys



				var focusText = input.val();







				input.data("buffer", buffer).data("tests", tests);







				function seekNext(pos) {



					while (++pos < len) {



						if (tests[pos])



							return pos;



					}



					return len;



				};







				function shiftL(pos) {



					while (!tests[pos] && pos >= 0) pos--;



					for (var i = pos; i < len; i++) {



						if (tests[i]) {



							buffer[i] = settings.placeholder;



							var j = seekNext(i);



							if (j < len && tests[i].test(buffer[j])) {



								buffer[i] = buffer[j];



							} else



								break;



						}



					}



					writeBuffer();



					input.caret(Math.max(firstNonMaskPos, pos));



				};







				function shiftR(pos) {



					for (var i = pos, c = settings.placeholder; i < len; i++) {



						if (tests[i]) {



							var j = seekNext(i);



							var t = buffer[i];



							buffer[i] = c;



							if (j < len && tests[j].test(t)) 



								c = t;



							else



								break;



						}



					}



				};







				function keydownEvent(e) {



					var pos = $(this).caret();



					var k = e.keyCode;



					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, delete, and escape get special treatment



					if (k == 8 || k == 46 || (iPhone && k==127)) {//backspace/delete



						shiftL(pos.begin + (k == 46 ? 0 : -1));



						return false;



					} else if (k == 27) {//escape



						clearBuffer(0, len);



						writeBuffer();



						$(this).caret(firstNonMaskPos);



						return false;



					}



				};







				function keypressEvent(e) {



					if (ignore) {



						ignore = false;



						//Fixes Mac FF bug on backspace



						return (e.keyCode == 8) ? false : null;



					}



					e = e || window.event;



					var k = e.charCode || e.keyCode || e.which;



					var pos = $(this).caret();







					if (e.ctrlKey || e.altKey) {//Ignore



						return true;



					} else if ((k >= 41 && k <= 122) || k == 32 || k > 186) {//typeable characters



						var p = seekNext(pos.begin - 1);



						if (p < len) {



							var c = String.fromCharCode(k);



							if (tests[p].test(c)) {



								shiftR(p);



								buffer[p] = c;



								writeBuffer();



								var next = seekNext(p);



								$(this).caret(next);



								if (settings.completed && next == len)



									settings.completed.call(input);



							}



						}



					}



					return false;



				};







				function clearBuffer(start, end) {



					for (var i = start; i < end && i < len; i++) {



						if (tests[i])



							buffer[i] = settings.placeholder;



					}



				};







				function writeBuffer() { return input.val(buffer.join('')).val(); };







				function checkVal(allow) {



					//try to place characters where they belong



					var test = input.val();					



					var lastMatch = -1;



					for (var i = 0,pos=0; i < len; i++) {



						if (tests[i]) {



							buffer[i] = settings.placeholder;



							while (pos++ < test.length) {



								var c = test.charAt(pos - 1);



								if (tests[i].test(c)) {



									buffer[i] = c;



									lastMatch = i;



									break;



								}



							}



							if (pos > test.length)



								break;



						}



					}



					if (!allow && lastMatch + 1 < partialPosition) {



						input.val("");



						clearBuffer(0, len);



					} else if (allow || lastMatch + 1 >= partialPosition) {



						writeBuffer();



						if(!allow)input.val(input.val().substring(0, lastMatch + 1));



					}					



					return (partialPosition ? i : firstNonMaskPos);



				};







				input



					.one("unmask", function() {



						input



							.unbind(".mask")



							.removeData("buffer")



							.removeData("tests");



					})



					.bind("focus.mask", function() {



						focusText = input.val();



						var pos = checkVal();



						writeBuffer();



						setTimeout(function() {



							input.caret(pos);



						}, 0);



					})



					.bind("blur.mask", function() {



						checkVal();



						if (input.val() != focusText)



							input.change();



					})



					.bind("keydown.mask", keydownEvent)



					.bind("keypress.mask", keypressEvent)



					.bind(pasteEventName, function(){ 



						setTimeout(function(){input.caret(checkVal(true));},0);



					});







				checkVal(); //Perform initial check for existing values



			});



		}



	});



})(jQuery);
