﻿(function(pkg, $){

	if(!$ || !$.fn.jqzoom){
		throw new Error('ProductPageController Classs requires jQuery 1.3.2 and jQZoom 1.0.1');
		return;
	}
	pkg = pkg || {};
	/**
	 * Product Page Controller
	 */
	pkg.ProductPageController$Class = {
		className: 'pkg.ProductPageController$Class',
		_counter: 0,
		_nodes: {},
		_jNodes: {},
		_jThis: null, 
		
		_shortcuts: null, // Shortcut
		_data: {},
		_module: null,
		
		_popLink: null,
		_calledTypes: [],
		avoidSubmit: false,
		
		constructor: function(){
			$.extend(true, this, pkg.ProductPageController$Class);
			this._counter = pkg.ProductPageController.global_counter++;
			this._jThis = $(this);
		},
		init: function(data){
			this._nodes = data.nodes || {};
			this._shortcuts = new pkg.Shortcut(data.shortcuts || {});
			this.avoidSubmit = data.avoidSubmit;
			this._data = data.list || {};
			this._patterns = data.patterns || {};
			
			this._popLink = this._nodes.imagePop;
			if(this._popLink){
				this._popLink.modal({url: "about:blank"});
			}
			
			var instances = pkg.ProductPageController.global_instances;
			
			for(var name in this._nodes){
				var currNode = this._nodes[name];
				if(currNode != null && currNode.eq(0) != null && currNode.length > 0){
					this._jNodes[name] = currNode.eq(0);
				}
			}
			
			var _this = this;
			var dependencyNodes = {};
			$.each(data.dependencyNodes, function(name, val){
				var currentObject = [];
				$.each(val.split(' '), function(i, val){
					if(_this._jNodes[val]){
						currentObject[currentObject.length] = _this._jNodes[val];
					}
				});
				dependencyNodes[name] = currentObject;
			});
			
			this._data.dependencyNodes = dependencyNodes;
			this._data.zoomConfig = data.zoomConfig;
			
			this._module = new pkg.ProductPageModule(this._jNodes, this._data, this._patterns, this._shortcuts, this._counter);
			this._module.init();
			$.each(instances[this._counter] || [], function(){
				this._jThis
					.bind('unavailableItem', function(e, extra){
						_this._jThis.trigger('unavailableItem', extra);
					})
					.bind('buildList', function(e, extra){
						_this._jThis.trigger('buildList', extra);
					});
			});
			this._module.build();
			this._module.selectElement(0);
			
			this.form = $(this._nodes.buyButton[0].form);
			this.form.bind('submit', this, this._onSubmit);
		},
		_onSubmit: function(e){
			return e.data.validate();
		},
		validate: function(){
			var checked = {};
			var inputs = $('input[type=radio]', this.form);
			var invalidInputs = [];
			inputs.each(function(){
				var input = $(this);
				if(!checked[input.attr('name')])
					checked[input.attr('name')] = true;
			});
			$.each(checked, function(name, val){
				if(inputs.filter('[name='+name+']').filter('[checked=true]').length == 0){
					invalidInputs[invalidInputs.length] = inputs.filter('[name='+name+']').filter('[checked=false]').eq(0);
				}
			});
			if(invalidInputs.length > 0){
				this._jThis.trigger('validationError', {
					nodes: invalidInputs,
					form: this.form
				})
				return false;
			}
			
			if(this.avoidSubmit){
				this._jThis.trigger('onSubmit', {
					form: this.form
				});
				return false;
			}
			return true;
		}
	};
	pkg.ProductPageController = pkg.ProductPageController$Class.constructor;
	pkg.ProductPageController.global_counter = 0;
	pkg.ProductPageController.global_instances = [];
	
	
	/**
	 * Product Page Module
	 */
	pkg.ProductPageModule$Class = {
		className: 'pkg.ProductPageModule$Class',
		_counter: 0,
		
		_jThis: null, // jQuery
		_list: null, // SelectableList
		_items: [], // ModuleItem
		
		_jNodes: {}, 
		_patterns: {}, 
		_shortcuts: null, // Shortcut
		_jLiModel: null, // jQuery, base for SelectableList elements

		type: null,
		data: null, // Object: label, priceLabel, descLabel, shippingLabel, ref, active, stamps, content, list, value
		parent: null, 
		
		constructor: function(nodes, data, patterns, shortcuts, counter){
			$.extend(true, this, pkg.ProductPageModule$Class);
			this._counter = counter;
			this._jThis = $(this);
			this._data = data;
			this.type = data.type;
			this._patterns = patterns;
			this._shortcuts = shortcuts;
			this._jNodes = nodes;
			this._jLiModel = this._jNodes[this._data.nodes.list];
			var instances = pkg.ProductPageController.global_instances;
			if(!instances[this._counter]){
				instances[this._counter] = [];
			}
			instances[this._counter][instances[this._counter].length] = this;
		},
		init: function(){
			if(!this._jLiModel) return;
			this.type = this._data.type;
			
			this._list = new pkg.SelectableList(this._jLiModel.parent(), true, true);
			
			var jLis = [];
			var ul = $(document.createElement('ul'));
			
			this._data.dependencyNodes.hideListParents = [];
			var _this = this;
			// record parent of the dependencyNodes (to use later)
			$.each(this._data.dependencyNodes.contentList, function(i, val){
				_this._data.dependencyNodes.hideListParents[i] = val.parents('div:first');
			});
			
			// get data properties from parent and extends
			var data = {};
			var parentData = {};
			for (var name in this._data) {
				if(name != 'items'){
					parentData[name] = this._data[name];
				}
			};
			parentData.patterns = this._patterns;
			for (var i=0; this._data.items[i] ; i++) {
				data = $.extend(true, {}, parentData, this._data.items[i]);
				this._items[i] = new pkg.ProductPageModuleItem(this._jLiModel.clone(), data, this._shortcuts, this._counter, i);
				this._items[i].parent = this;
				this._items[i].init(this._jNodes);
				ul.append(this._items[i].jLi);
			};
			
			
			this._list._jThis
				.bind('change', this, this._onChangeItem)
				.bind('disabledItem', this, this._onUnavailableItem);
			this._list.init(ul.children('li'));
			this._list.setEnabledItemsRule(function(){
				return !$(this).hasClass('unavailable');
			});
		},
		build: function(){
			if(this._list){
				if(this._list._built){
					this._list.reset();
				}
				this._list.build();
			}
			this._jThis.trigger('buildList', {
				module: this,
				list: this._items
			});
		},
		_onChangeItem: function(e, extra){
			var itemInstance = e.data._getItemByLi(extra.node);
			itemInstance.refresh();
			if(extra.isEnabled){
				e.data._jNodes.buyButton.show();
				e.data._jNodes.unavailableButton.hide();
			}
		},
		_onUnavailableItem: function(e, extra){
			
			e.data._jNodes.buyButton.hide();
			e.data._jNodes.unavailableButton.show();
			
			var itemInstance = e.data._getItemByLi(extra.node);
			var instances = [];
			var currInstance = itemInstance;
			while(currInstance){
				if(currInstance.className == pkg.ProductPageModuleItem$Class.className){
					instances[instances.length] = currInstance;
				}
				currInstance = currInstance.parent;
			};
			e.data._jThis.trigger('unavailableItem', {
				instances: instances
			});
		},
		_getItemByLi: function(node){
			var returnValue = null;
			$(this._items).each(function(){
				if(this.jLi[0] == node){
					returnValue = this;
					return true;
				}
			});
			return returnValue;
		},
		selectElement: function(index){
			if(this._items[index] && this._items[index].jLi && this._items[index].jLi[0]){
				this._list.selectElement(this._items[index].jLi[0]);
			}
		}
	};
	pkg.ProductPageModule = pkg.ProductPageModule$Class.constructor;
	
	/**
	 * Module Item
	 */
	pkg.ProductPageModuleItem$Class = {
		className: 'pkg.ProductPageModuleItem$Class',
		_shortcuts: null, // Shortcut
		_counter: 0,
		_itemIndex: 0,
		_data: null, 
		_jA: null, 
		_jRadio: null, 
		_jLabel: null, 
		_jNodes: null, 
		_jStampsHolder: null, 
		_popLink: null, 
		
		jLi: null,
		child: null, // ProductPageModule
		parent: null, 
		_contentList: [], // Array of ProductPageContentList
		
		constructor: function(jLi, data, shortcuts, counter, itemIndex){
			$.extend(true, this, pkg.ProductPageModuleItem$Class);
			this._counter = counter;
			this._shortcuts = shortcuts;
			this._itemIndex = itemIndex;
			this.jLi = jLi;
			this._data = data;
			this._jA = this.jLi.children('a').eq(0);
			this._jLabel = this.jLi.children('label').eq(0);
			this._jRadio = this.jLi.children('input[type=radio]').eq(0);
		},
		init: function(nodes){
			this._jNodes = nodes;
			this._popLink = this._jNodes.imagePop;
			var _this = this;
			
			if (this._data.type == 'color') {
				this._jRadio
					.val(this._data.value)
					.attr('name', 'cartItem[0].pID')
					.attr('id', this._data.type+'_'+this._counter+this._itemIndex);
			}else {
				this._jRadio
					.val(this._data.ref)
					.attr('name', 'cartItem[0].skuGuid')
					.attr('id', this._data.type+'_'+this._counter+this._itemIndex);
			}	
			$('span', this._jLabel.attr('for', this._jRadio.attr('id'))).text(this._data.label);
			this._jStampsHolder = this._jNodes.stamps.parent();
			this._jStampsModel = this._jNodes.stamps.clone();
			this._jStampsModel.children('img').attr('src','');

			if(this._data.available === false){
				this.jLi.addClass('unavailable');
			}
			
			if(this._data.content){
				
				if(this._data.content != 'parent'){
					// build photos and videos
					$.each(this._data.content, function(i){
						_this._contentList[i] = new pkg.ProductPageContentList(
							$.extend(true, {}, this, {
								zoomConfig: _this._data.zoomConfig,
								patterns: _this._data.patterns,
								dependencyNodes: _this._data.dependencyNodes
							}),
							_this._jNodes,
							_this._shortcuts
						);
						_this._contentList[i].init();
						_this._contentList[i]._jThis.bind('change', _this, _this._onChangeBetweenLists);
					});
				
					// get replaced url photo names
					$.each(_this._contentList, function(){
						for(var name in _this._data.content){
							if(this._data[name]){
								_this._data.content[name] = this._data[name];
							}
						}
					});
				}
				
			}else if (this._data.unavailableContent){
				// build "no photos"
				$.each(this._data.unavailableContent, function(i){
					_this._contentList[i] = new pkg.ProductPageContentList(
						$.extend(true, {}, this, {
							patterns: _this._data.patterns,
							dependencyNodes: _this._data.dependencyNodes
						}),
						_this._jNodes,
						_this._shortcuts
					);
					_this._contentList[i].init();
				});
			}
			
			
			switch(this._data.type){
				case 'color':
				case 'flavor':
					// place label color
					if(this._data.color){
						switch(true){
							case (this._data.color.match(/#[0-9]{3,6}$/)):
								this._jLabel.css('background-color', this._data.color);
								break;
							default:
								this._jLabel.css('background-image', 'url('+this._shortcuts.parseString(this._data.color)+')');
								break;
						}
					}
					break;
			}
			
			if(this._data.list){
				// get data properties from parent and extends
				var parentData = {};
				for (var name in this._data) {
					if(name != 'list' && name != 'nodes' && name != 'content'){
						parentData[name] = this._data[name];
					}else if(name == 'content'){
						parentData[name] = 'parent';
					}
				};
				this.child = new pkg.ProductPageModule(
					this._jNodes,
					$.extend(true, {}, parentData, this._data.list),
					this._data.patterns,
					this._shortcuts,
					this._counter
				);
				this.child.parent = this;
				this.child.init();
			}
			
		},
		refresh: function(){
			var _this = this;
			if(this.child){
				this.child.build();
			}
			
			// apply texts
			var jLabel = this._jNodes[this._data.nodes.label];
			var labelPattern = this._data.patterns[this._data.nodes.label] || '$1';
			if(jLabel && this._data['label']){
				this._refreshText(labelPattern.replace(/\$1/g, this._data['label']), jLabel);
			}
			
			var jRef = this._jNodes['ref'];
			var refPattern = this._data.patterns['ref'] || '$1';
			if(jRef && this._data['label']){
				this._refreshText(refPattern.replace(/\$1/g, this._data['ref']), jRef);
			}
			
			if(this._data.stamps){
				_this._jStampsHolder.empty();
				$.each(this._data.stamps, function(){
					if(this.url){
						var toAppend = _this._jStampsModel.clone();
						toAppend.children('img').attr('src', _this._shortcuts.parseString(this.url));
						_this._jStampsHolder.append(toAppend);
					}
				})
			}
			
			// apply general text (from text property)
			$.each(this._jNodes, function(name, val){
				if(_this._data.texts[name] != null && typeof(_this._data.texts[name]) == 'string'){
					var pattern = (_this._data.patterns && _this._data.patterns[name]) ? _this._data.patterns[name] : '$1';
					_this._refreshText(pattern.replace(/\$1/g, _this._data.texts[name]), val);
				}
			});
			
			var parentContentList = [];
			// build content lists
			if(this._contentList && this._contentList.length > 0){
				var selectedIndex = null;
				var selectOnce = false;

				if(this._data.dependencyNodes && this._data.dependencyNodes.hideListParents){
					$.each(this._data.dependencyNodes.hideListParents, function(i, val){
						val.hide();
					});
				}
				
				$.each(this._contentList, function(){
					this.build();
					
					if(selectOnce) return;
					
					selectedIndex = this.getSelectedIndex();
					if(selectedIndex != null){
						selectOnce = true;
						this.selectIndex(selectedIndex);
					}
				});
				if(selectedIndex == null){
					this._contentList[0].selectIndex(0);
				}
			}else{
				var parentContent = this.parent;
				while(parentContent != null){
					if(parentContentList && parentContentList.length == 0)
						parentContentList = parentContent._contentList;
					parentContent = parentContent.parent;
				}
				if(!parentContent){
					if(this._data.dependencyNodes.contentList){
						$.each(this._data.dependencyNodes.contentList, function(i, val){
							val.empty();
						});
					}
				}
			}
			
			if(this._popLink){
				this._popLink.parents('div:first').show();
			}
			/* if(this._popLink && (parentContentList.length > 0 || this._contentList.length > 0)){
				this._popLink.parents('div:first').show();
			} */
			
		},
		_onChangeBetweenLists: function(e){
			var _this = this;
			$.each(e.data._contentList, function(){
				if(this != _this){
					this._list.reset();
				}
			});
		},
		_refreshText: function(text, jNode){
			if(text != null && jNode && jNode.text() != text)
				jNode.html(text);
		}
	};
	pkg.ProductPageModuleItem = pkg.ProductPageModuleItem$Class.constructor;
	
	/**
	 * Photo list
	 */
	pkg.ProductPageContentList$Class = {
		className: 'pkg.ProductPageContentList$Class',
		_data: {},
		_jThis: null,
		_jNodes: null,
		_shortcuts: null, // Shortcut
		
		_popLink: null, // jQuery
		_jLiModel: null, // jQuery
		_mainView: null, // jQuery
		
		_list: null, // SelectableList
		_items: [], // Array of ProductPagePhotoItem
		
		type: null,
		
		constructor: function(data, jNodes, shortcuts){
			$.extend(true, this, pkg.ProductPageContentList$Class);
			this._data = data;
			this._jThis = $(this);
			this._jNodes = jNodes;
			this._shortcuts = shortcuts;
			this._popLink = this._jNodes[this._data.nodes.modal];
			this._jLiModel = this._jNodes[this._data.nodes.list];
			this._mainView = this._jNodes[this._data.nodes.mainView];
			this._list = new pkg.SelectableList(this._jLiModel.parent(), true, false);
			this._list.selectOnOver = this._data.type == 'photo';
		},
		init: function(){
			var _this = this;
			var parseArray = this._data.thumbs
								.concat(this._data.mainView)
								.concat(this._data.zoom)
								.concat(this._data.pop)
								.concat(this._data.showcase);
			$.each(parseArray, function(i, val){
				if(val) val.url = _this._shortcuts.parseString(val.url);
			});
			
			this._data.thumbs = this._generateAutomadedData(this._data.thumbs, this._data.quantity);
			this._data.showcase = this._generateAutomadedData(this._data.showcase, this._data.quantity);
			this._data.mainView = this._generateAutomadedData(this._data.mainView, this._data.quantity);
			this._data.pop = this._generateAutomadedData(this._data.pop, this._data.quantity);
			this._data.zoom = this._generateAutomadedData(this._data.zoom, this._data.quantity);
			
			var ul = $(document.createElement('ul'));
			switch(this._data.type){
				case 'photo':
					$.each(this._data.thumbs, function(i, val){
						var data = {
							thumb: val.url,
							mainView: _this._data.mainView[i].url,
							zoom: _this._data.zoom ? _this._data.zoom[i].url : null,
							//pop: _this._data.pop ? _this._data.pop[i].url : null,
							pop: _this._data.pop ? _this._data.pop[i].url : '/Netshoes/locales/pt-BR/img/img_indisponivel.jpg',
							zoomConfig: _this._data.zoomConfig,
							patterns: _this._data.patterns,
							nodes: _this._data.nodes
						};
						_this._items[i] = new pkg.ProductPagePhotoItem(_this._jLiModel.clone(), _this._jNodes, _this._mainView, data, _this._shortcuts);
						ul.append(_this._items[i].jLi);
					});
					break;
				case 'video':
					$.each(this._data.thumbs, function(i, val){
						var videoId = _this._data.mainView[i].url.match(/v=(.*?)(?:&|$)/);
						var data = {
							thumb: val.url,
							mainView: videoId != null && videoId.length > 1 ? videoId[1] : '',
							patterns: _this._data.patterns
						};
						_this._items[i] = new pkg.ProductPageVideoItem(_this._jLiModel.clone(), _this._mainView, data, _this._shortcuts);
						ul.append(_this._items[i].jLi);
					});
					break;
			}
			this._list.init(ul.children('li'));
			this._list._jThis.bind('change', this, this._onChangeItem);
		},
		_generateAutomadedData: function(data, quant){
			if(!data) return null;
			var model = data[0];
			if(!model || !model.url) return null;
			var automadedData = [];
			if(data.length == 1 && model.url.match(/\$1/) && quant > 0){
				var currentObject;
				for (var i=0; i < quant; i++) {
					currentObject = $.extend(true, {}, model);
					currentObject.url = model.url.replace(/\$1/, i+1);
					automadedData[i] = currentObject;
				};
			}else if(!quant){
				automadedData = data;
			}else{
				automadedData = (quant && quant != data.length) ? data.slice(0, quant) : data;
			}
			return automadedData;
		},
		build: function(){
			$.each(this._items, function(i, val){
				if(val && !val.built){
					val.init();
				}
			});
			if(this._list){
				this._list._jLiHolder.parents('div:first').show();
				if(this._list._built){
					this._list.reset();
				}
				this._list.build();
			}
		},
		_onChangeItem: function(e, extra){
			var itemInstance = e.data._getItemByLi(extra.node);
			$.each(e.data._data.dependencyNodes.content, function(i, val){
				val.hide();
			});

			itemInstance.refresh();
			$.each(e.data._items, function(i, val){
				if(itemInstance != val){
					val.stop();
				}
			});
			e.data._jThis.trigger('change');
		},
		_getItemByLi: function(node){
			var returnValue = null;
			$(this._items).each(function(){
				if(this.jLi[0] == node){
					returnValue = this;
					return true;
				}
			});
			return returnValue;
		},
		selectIndex: function(index){
			if(this._list._jLi[index])
				this._list.selectElement(this._list._jLi[index]);
		},
		getSelectedIndex: function(){
			return this._list.selectedIndex;
		}
	};
	pkg.ProductPageContentList = pkg.ProductPageContentList$Class.constructor;
	
	/**
	 * Photo item
	 */
	pkg.ProductPagePhotoItem$Class = {
		className: 'pkg.ProductPagePhotoItem$Class',
		_data: {},
		
		jLi: null, // jQuery
		_jImg: null, // jQuery
		_jMainView: null, // jQuery Image holder
		_jMainViewImg: null, // jQuery Img
		_jMainViewLink: null, // jQuery A
		_jNodes: null, // jQuery A
		_popLink: null, // jQuery A
		
		constructor: function(jLi, jNodes, mainView, data, shortcuts){
			$.extend(true, this, pkg.ProductPagePhotoItem$Class);
			this._data = data;
			this._jNodes = jNodes;
			this._popLink = this._jNodes[this._data.nodes.modal];
			this._jMainView = mainView;
			this._jMainViewImg = $('img', mainView);;
			this._jMainViewLink = $('a:first', mainView);
			this.jLi = jLi;
			$('a:first', this.jLi).attr('href', 'javascript:;');
			this._jImg = $('img', this.jLi).attr('src', '');
			this._loader = new pkg.ImageLoader();
		},
		init: function(){
			this._loader.load('main', this._data.mainView);
			if(this._data.thumb && this._jImg.attr('src') != this._data.thumb){
				this._jImg.attr('src', this._data.thumb);
			}
		},
		refresh: function(){
			this._jMainView.show();
			if(this._jMainView.css('opacity') == 1){
				this._jMainView
					.css({opacity: 0})
					.animate({opacity: 1}, 300);
			}
			this._jMainViewImg.attr('src', this._data.mainView);
			if(!this._loader._imagesToLoad['zoom'] || this._loader._imagesToLoad['zoom'] != 'complete'){
				this._loader.load('zoom', this._data.zoom);
				this._loader.load('ampliacao', this._data.pop);
			}
			if(this._popLink){
				this._popLink.data('url', this._data.pop);
			}
			this._jMainViewLink.attr('href', this._data.zoom || 'javascript:;');
			if(!this._jMainViewLink.data('jqzoom') && this._data.zoomConfig)
				this._jMainViewLink.jqzoom(this._data.zoomConfig);
		},
		stop: function(){
			if(this._loader._imagesToLoad['zoom'] && this._loader._imagesToLoad['zoom'].status != "complete"){
				this._loader.stop('zoom');
			}
		}
	};
	pkg.ProductPagePhotoItem = pkg.ProductPagePhotoItem$Class.constructor;
	
	/**
	 * Video item
	 */
	pkg.ProductPageVideoItem$Class = {
		className: 'pkg.ProductPageVideoItem$Class',
		_data: null,
		_jMainView: null,
		jLi: null,
		_jImg: null,
		_shortcuts: null, 
		_embedCode: '',
		constructor: function(jLi, mainView, data, shortcuts){
			$.extend(true, this, pkg.ProductPageVideoItem$Class);
			this._data = data;
			this._jMainView = mainView;
			this.jLi = jLi;
			this._jImg = $('img', this.jLi).attr('src', '');
			this._shortcuts = shortcuts;
		},
		init: function(){
			this._embedCode = this._data.patterns['videoEmbed'].replace(/\$1/g, this._data.mainView).replace(/&/g, '&amp;');
			if(this._data.thumb && this._jImg.attr('src') != this._data.thumb){
				this._jImg.attr('src', this._data.thumb);
			}
		},
		refresh: function(){
			this._jMainView.show();
			var jEmbed = $('embed', this._jMainView);
			if(jEmbed.length == 0 || jEmbed.attr('src').indexOf(this._data.mainView) < 0){
				this._jMainView.html(this._embedCode);
			}
		},
		stop: function(){}
	};
	pkg.ProductPageVideoItem = pkg.ProductPageVideoItem$Class.constructor;
	
	/**
	 * Simple Mask Function
	 */
	var only = function(type, extra, e) {
		var value = extra || '';
		switch(type){
			case 'num':
			case 'number':
			case 'numeric':
				value += '0123456789';
				break;
			case 'alnum':
			case 'alphanumeric':
				value += 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZáàãâäéèêëíìîïóòõôöúùûüçÁÀÃÂÄÉÈÊËÍÌÎÏÓÒÕÔÖÚÙÛÜÇ 0123456789';
				break;
			case 'let':
			case 'letter':
			case 'letters':
				value += 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZãâáêéíõóôúÃÂÁÊÉÍÕÓÔÚ ';
				break;
			case 'rest':
			case 'restrict':
				value += 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
			case 'email':
				value += 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@-_.';
		}

		switch(e.which){
			case 8:
			case 9:
			case 13:
			case 27:
			/*case 37:
			case 38:
			case 39:
			case 40:*/
			case 46:
				return true;
			break
			case 199:
			case 231:
				if(e.data.extra.nodes.field.attr("id") == "customName"){
					return true;
				}
			 
		}
		if(value.indexOf(String.fromCharCode(e.charCode || e.keyCode)) >= 0){
			return true;
		}
		return false;
	};
	
	/**
	 * custom product
	 */
	pkg.CustomProduct$Class = {
		
		constructor: function(){
			$.extend(true, this, pkg.CustomProduct$Class);
		},

		/*
		{
			config:{ // can be "global" or "local"
				labelPattern: '+ R$ $1', "$1" will be replaced by value
				value: '0,10'
			},
			fields: [{
				config:{
					type: 'letter',
					maxlength: 10
				},
				nodes:{
					field: $('input#customName'),
					label: $('#customNamePrice')
				}
			}]
		}
		*/
		init: function(data){
			var _this = this;
			$.each(data.fields, function(i, val){
				$.extend(true, this.config, data.config);
				_this._applyHandlers(this);
			});
		},
		_applyHandlers: function(data){
			if(data.nodes && data.nodes.field && data.config){
				data.nodes.label.html('');
				data.nodes.field
					.attr('maxlength', data.config.maxlength || 20)
					.bind('keypress', {scope:this, extra: data}, this._onKeyPress)
					.bind('keyup', {scope:this, extra: data}, this._onKeyUp);
			}
		},
		
		// handlers
		_onKeyPress: function(e){
			var maskValue = only(e.data.extra.config.type, '.', e);
			if(maskValue === false){
				return false;
			}
		},
		_onKeyUp: function(e){
			var extra = e.data.extra;
			 if(!this.value.match(/^(?:\s+)?$/)){
				extra.nodes.label.html(extra.config.labelPattern.replace(/\$1/g, extra.config.value.replace(/\./, ',')));
			}else{
				extra.nodes.label.html('');
			}
			
			this.value = this.value.toUpperCase();
		}
	};
	pkg.CustomProduct = pkg.CustomProduct$Class.constructor;
	
	//}
})(window, jQuery);
