/*
---

name: Meio.Mask.Extras

description: Extra functionality for Meio.Mask plugin. Like String.meiomask that masks a string and Element.meiomask which is a convinience method for setting the masks.

authors:
 - Fábio Miranda Costa

requires:
 - Meio.Mask

license: MIT-style license

provides: [Meio.Mask.Extras]

...
*/

(function(){

	var meiomask = 'meiomask';
	
	var upperCamelize = function(str){
		return str.camelCase().capitalize();
	};
	
	var getClassOptions = function(a1, a2, opts){
		var klass;
		if (typeOf(a1) == 'string'){
			if (typeOf(a2) != 'string'){
				opts = a2;
				a1 = a1.split('.');
				a2 = a1[1];
				a1 = a1[0];
			}
			klass = Meio.Mask[upperCamelize(a1)];
			if (a2) klass = klass[upperCamelize(a2)];
		} else {
			klass = a1;
			opts = a2;
		}
		return {klass: klass, options: opts || {}};
	};
	
	var executeFunction = function(functionName, args){
		var co = getClassOptions.apply(null, args); 
		return new co.klass(co.options)[functionName](this);
	};

	String.implement({
		meiomask: function(){
			return executeFunction.call(this, 'mask', arguments);
		},
		meiounmask: function(){
			return executeFunction.call(this, 'unmask', arguments);
		}
	});

	Element.Properties.meiomask = {
		set: function(args){
			args = getClassOptions.apply(null, args), mask = this.retrieve(meiomask);
			if (mask){
				mask.unlink();
				mask = null;
			}
			return this.store(meiomask, new args.klass(args.options).link(this));
		},
		// returns the mask object
		get: function(){
			return this.retrieve(meiomask);
		},
		// removes completely the mask from this input
		erase: function(){
			var mask = this.retrieve(meiomask);
			if (mask) mask.unlink();
			return this;
		}
	};
	
	Element.Properties[meiomask + ':value'] = {
		// sets the value but first it applyes the mask (if theres any)
		set: function(value){
			var mask = this.retrieve(meiomask);
			if (mask) value = mask.mask(value);
			return this.set('value', value);
		},
		
		// gets the unmasked value
		get: function(){
			var mask = this.retrieve(meiomask);
			var value = this.get('value');
			return (mask) ? mask.unmask(value) : value;
		}
	};

	Element.implement({
		meiomask: function(mask, type, options){
			return this.set(meiomask, [mask, type, options]);
		}
	});
	
})();

