;(function($) {

	$(document).ready( function () { $.fw.init(); } );

	/*=================================================================================================================================================*/
	$.fn.grids = {};
	$.fn.grid = function(settings) {

		var grid;
		
		function _init(){
			grid.templates = {};
			grid.content.find('div[class^=template]').each(function(){
				grid.templates[this.className.replace('template-','')] = $(this).html();
			});
			grid.content.addClass(_class('grid'));

			_clear();
			_loading();

			switch(grid.dataType){
				case 'local':
					_dataCheck();
					_build();
					break;
				case 'remote':
					_remote();
					break;
			}
		}

		function _remote(){
			var params = $.extend({}, {grid:grid.requestID,ps:grid.pageSize,cp:grid.currentPage}, grid.requestParams);
			if($.isArray(grid._filterArgs) && grid.filtred){
				if(grid._filterArgs.length == 0){
					grid.filtred = false;
					grid._filterArgs = undefined;
				}else{
					grid.filterParams = {};
					$.each(grid._filterArgs,function(){
						if($.isArray(this.field)){
							if($.isArray(this.value)){
								if(this.field.length = this.value.length){
									for(var i=0;i<this.field.length;i++){
										grid.filterParams[this.field[i]] = this.value[i];
									}
								}
							}
						}else{
							grid.filterParams[this.field] = this.value;
						}
					});
					var params = $.extend({}, params, grid.filterParams);
				}
			}else{
				grid.filtred = false;
			}
			for(var i=0;i<grid.cols.length;i++){
				if(typeof grid.cols[i].config == 'object'){
					for(config in grid.cols[i].config){
						switch(config){
							case 'sortable':
								params = $.extend({}, params, _dataSortCheckCol(i,false));
								break;
						}
					}
				}
			}
			$.post(grid.requestURL,params,function(data){
				grid.data = data.data;
				grid.totalRows = data.rc;
				_dataCheck();
				_build();
			},'json');
		}

		function _build(){
			if(grid.data.length > 0){
				
				if(grid.navPosition == 'top' || grid.navPosition == 'both'){_nav()}
				
				if(grid.navFilterSettings != null){
					grid.filter = $('<div>').addClass(_class('grid-filter')).appendTo(grid.content);
					grid.filter.form(grid.navFilterSettings);
					grid.content.find('.'+_class('grid-option-filter')).click(function(){
						grid.filter.slideToggle('normal');
					});
				}
				if($.isArray(grid._filterArgs) && grid.filtred && grid.navShowFilterOptions){
					grid.currentFilter = $('<div>').addClass(_class('grid-filter')).appendTo(grid.content);
					for(var i =0;i<grid._filterArgs.length;i++){
						$('<a>').attr({'fw:value':i}).html(grid._filterArgs[i].title).appendTo(grid.currentFilter).click(function(){
							grid._filterArgs.pop($(this).attr('fw:value'));
							grid.reload();
						});
					}
				}
								
				var table = _table();
				if(grid.showHeader){
					_header($('<thead>').addClass(_class('grid-header')).appendTo(table));
				}
				var tbody = $('<tbody>').addClass(_class('grid-rows')).appendTo(table);

				switch(grid.displayType){
					case 'table':
					
						var first = (grid.dataType == 'local') ? grid.startRow : 0 , last = (grid.dataType == 'local') ? grid.lastRow + 1 : grid.data.length;
						
						for(var i=first;i<last;i++){
							
							var css = ((i % 2) == 0) ? 'grid-row' : 'grid-row-alt';
							
							if(grid.selectionRecord){
								if(typeof grid.data[i].config == 'object'){
									if(grid.data[i].config['selected']){
										css = 'grid-row-selected';
									}
								}else{
									grid.data[i].config = {};
								}
							}
							var tr = $('<tr>').addClass(_class(css)).mouseover(function(){
											if(!$(this).hasClass(_class('grid-row-selected'))){
												$(this).removeClass(_class((((grid.showHeader) ? this.rowIndex-1 : this.rowIndex) % 2 == 0) ? 'grid-row' : 'grid-row-alt')).addClass(_class('grid-row-over'));
											}
										}).mouseout(function(){
											if(!$(this).hasClass(_class('grid-row-selected'))){
												$(this).removeClass(_class('grid-row-over')).addClass(_class((((grid.showHeader) ? this.rowIndex-1 : this.rowIndex) % 2 == 0) ? 'grid-row' : 'grid-row-alt'));
											}
										}).click(function(){
											$(this.parentNode).find('.'+_class('grid-row-selected')).each(function(){
																			if(grid.selectionMode == 'single'){
																				var regIndex = (grid.dataType == 'local') ? ((grid.showHeader) ? this.rowIndex-1 : this.rowIndex) + ((grid.currentPage-1)*grid.pageSize) : (grid.showHeader) ? this.rowIndex-1 : this.rowIndex ;
																				if(grid.selectionRecord){grid.data[regIndex].config['selected'] = false}
																				if(typeof grid.rowSelect == 'function'){grid.rowSelect(this,false,grid.data[regIndex])}
																				$(this).removeClass(_class('grid-row-selected')).addClass(_class((((grid.showHeader) ? this.rowIndex-1 : this.rowIndex) % 2 == 0) ? 'grid-row' : 'grid-row-alt'));
																			}
																		});
											
											var regIndex = (grid.dataType == 'local') ? ((grid.showHeader) ? this.rowIndex-1 : this.rowIndex) + ((grid.currentPage-1)*grid.pageSize) : (grid.showHeader) ? this.rowIndex-1 : this.rowIndex ;
											
											if(grid.selectionMode != 'none'){
												if($(this).hasClass(_class('grid-row-selected'))){
													$(this).removeClass(_class('grid-row-selected')).addClass(_class('grid-row-over'));
													if(grid.selectionRecord){grid.data[regIndex].config['selected'] = false};
													if(typeof grid.rowSelect == 'function'){grid.rowSelect(this,false,grid.data[regIndex])}
												}else{
													$(this).removeClass(_class('grid-row-over')).removeClass(_class((this.parentNode.rowIndex % 2 == 0) ? 'grid-row' : 'grid-row-alt')).addClass(_class('grid-row-selected'));
													if(grid.selectionRecord){grid.data[regIndex].config['selected'] = true};
													if(typeof grid.rowSelect == 'function'){grid.rowSelect(this,true,grid.data[regIndex])}
												}
											}
											
											if(typeof grid.rowClick == 'function'){grid.rowClick(this,grid.data[regIndex])}
											
										}).appendTo(tbody);

							for(var j=0;j<grid.cols.length;j++){
								var format = (typeof grid.cols[j].config == 'object') ? grid.cols[j].config['format'] : undefined ;
								var td = _fetch(tr,grid.cols[j].text,grid.data[i],format);
								td.css(grid.cols[j].css);
								td.attr(grid.cols[j].attr);
							}
						}
						break;
					case 'template':
						var first = (grid.dataType == 'local') ? grid.startRow : 0 , last = (grid.dataType == 'local') ? grid.lastRow+1 : grid.data.length;
					
						for(var i=first,k=0;i<last;i=i+grid.templateCols,k++){
							var css = (i % 2 == 0) ? 'grid-row' : 'grid-row-alt';
							var tr = $('<tr>').addClass(_class(css)).appendTo(tbody);
							
							for(var j=0;j<grid.templateCols && (i+j) <= grid.lastRow;j++){
								if(grid.data[i+j] != undefined){
									
									var css = ((k+j) % 2 == 0) ? 'grid-cell' : 'grid-cell-alt';
									if(grid.selectionRecord){
										if(typeof grid.data[i+j].config == 'object'){
											if(grid.data[i+j].config['selected']){
												css = 'grid-cell-selected';
											}
										}else{
											grid.data[i+j].config = {};
										}
									}
									
									if(grid.selectionRecord){
										var td = _fetch(tr,grid.templates[(grid.data[i+j].config['selected']) ? _class('cell-selected') : _class('cell')],grid.data[i+j]);
									}else{
										var td = _fetch(tr,grid.templates['cell'],grid.data[i+j]);
									}
									
									if(grid.selectionMode != 'none'){
										td.mouseover(function(){
											if(!$(this).hasClass(_class('grid-cell-selected'))){
												var regIndex = ( ((grid.showHeader)?this.parentNode.rowIndex-1:this.parentNode.rowIndex) * grid.templateCols) + this.cellIndex + ((((grid.dataType == 'remote')?1:grid.currentPage)-1)*grid.pageSize);
												$(this).removeClass(_class((regIndex % 2 == 0) ? 'grid-cell' : 'grid-cell-alt')).addClass(_class('grid-cell-over'));
											}
										}).mouseout(function(){
											if(!$(this).hasClass(_class('grid-cell-selected'))){
												var regIndex = ( ((grid.showHeader)?this.parentNode.rowIndex-1:this.parentNode.rowIndex) * grid.templateCols) + this.cellIndex + ((((grid.dataType == 'remote')?1:grid.currentPage)-1)*grid.pageSize);
												$(this).removeClass(_class('grid-cell-over')).addClass(_class((regIndex % 2 == 0) ? 'grid-cell' : 'grid-cell-alt'));
											}
										}).click(function(){
											$(this.parentNode.parentNode).find('tr>td.'+ _class('grid-cell-selected')).each(function(){
																			if(grid.selectionMode == 'single'){
																				$(this).removeClass(_class('grid-cell-selected')).addClass((((this.parentNode.rowIndex+this.cellIndex)-1) % 2 == 0) ? _class('grid-cell') : _class('grid-cell-alt'));
																				if(grid.templates['cell-selected'] != undefined){
																					var regIndex = ( ((grid.showHeader)?this.parentNode.rowIndex-1:this.parentNode.rowIndex) * grid.templateCols) + this.cellIndex + ((((grid.dataType == 'remote')?1:grid.currentPage)-1)*grid.pageSize);
																					if(grid.selectionRecord){grid.data[regIndex].config['selected'] = false}
																					$(this).removeClass(_class('.grid-cell-selected')).html(_replace((typeof grid.formatOptions == 'object') ? $.extend(grid.formatOptions,{text:grid.templates['cell'] ,obj:grid.data[regIndex]}) : {text:grid.templates['cell'] ,obj:grid.data[regIndex]}));
																				}
																			}
																		});
											
											var regIndex = ( ((grid.showHeader)?this.parentNode.rowIndex-1:this.parentNode.rowIndex) * grid.templateCols) + this.cellIndex + ((((grid.dataType == 'remote')?1:grid.currentPage)-1)*grid.pageSize);
											
											if(grid.selectionMode != 'none'){
												if($(this).hasClass(_class('grid-cell-selected'))){
													$(this).removeClass(_class('grid-cell-selected')).addClass(_class('grid-cell-over'));
													if(grid.selectionRecord){grid.data[regIndex].config['selected'] = false}
													if(grid.templates['cell-selected'] != undefined){
														$(this).addClass(_class('cell-selected')).html(_replace((typeof grid.formatOptions == 'object') ? $.extend(grid.formatOptions,{text:grid.templates['cell'] ,obj:grid.data[regIndex]}) : {text:grid.templates['cell'] ,obj:grid.data[regIndex]}));
													}
													if(typeof grid.cellSelect == 'function'){grid.cellSelect(this,true,grid.data[regIndex])}
												}else{
													$(this).removeClass(_class('grid-cell-over')).removeClass(_class(((this.parentNode.rowIndex+this.cellIndex) % 2 == 0) ? 'grid-cell' : 'grid-cell-alt')).addClass(_class('grid-cell-selected'));
													if(grid.selectionRecord){
														grid.data[regIndex].config['selected'] = true;
														for(var l=0;l<grid.data.length;l++){grid.data[l].config['selected'] = false}
													}
													if(grid.templates['cell-selected'] != undefined){
														$(this).addClass(_class('cell-selected')).html(_replace((typeof grid.formatOptions == 'object') ? $.extend(grid.formatOptions,{text:grid.templates['cell-selected'] ,obj:grid.data[regIndex]}) : {text:grid.templates['cell-selected'] ,obj:grid.data[regIndex]} ));
													}
													if(typeof grid.cellSelect == 'function'){grid.cellSelect(this,true,grid.data[regIndex])}
												}
											}
											if(typeof grid.cellClick == 'function'){grid.cellClick(this,grid.data[regIndex])}
										}).addClass( _class(css) );
									}else{
										td.mouseover(function(){
											var regIndex = ( ((grid.showHeader)?this.parentNode.rowIndex-1:this.parentNode.rowIndex) * grid.templateCols) + this.cellIndex + ((((grid.dataType == 'remote')?1:grid.currentPage)-1)*grid.pageSize);
											$(this).removeClass(_class((regIndex % 2 == 0) ? 'grid-cell' : 'grid-cell-alt')).addClass(_class('grid-cell-over'));
										}).mouseout(function(){
											var regIndex = ( ((grid.showHeader)?this.parentNode.rowIndex-1:this.parentNode.rowIndex) * grid.templateCols) + this.cellIndex + ((((grid.dataType == 'remote')?1:grid.currentPage)-1)*grid.pageSize);
											$(this).removeClass(_class('grid-cell-over')).addClass(_class((regIndex % 2 == 0) ? 'grid-cell' : 'grid-cell-alt'));
										});
									}
								}
							}
						}
						break;
				}
				
				if(grid.navPosition == 'bottom' || grid.navPosition == 'both'){_nav()}
				
				grid.content.find('.'+ _class('grid-option') +', .'+ _class('grid-table')).show();
				grid.content.find('.'+ _class('grid-loading')).hide();
				
			}else{
				grid.content.find('.'+ _class('grid-loading')).html(grid.noResultsText+'<br/>');
				if(grid.filtred){
					$('<input type="button" value="limpar filtro" />').addClass(_class('grid-button')).appendTo(grid.content.find('.'+ _class('grid-loading'))).click(function(){grid.filtred=false;grid.reload();})
				}
			}
			
			if(typeof grid.gridLoaded == 'function'){
				grid.gridLoaded(grid);
			}
			
		}

		function _fetch(tr,html,reg,format){
			switch(typeof(html)){
				case 'string':
					return $('<td>').html(_replace((typeof grid.formatOptions == 'object') ? $.extend(grid.formatOptions,{text:html,obj:reg}) : {text:html,obj:reg},format)).appendTo(tr);
				case 'function':
					return $('<td>').html(html(reg)).appendTo(tr);
			}
			return $('<td>').html('#ERRO#').appendTo(tr);
		}

		function _table(){
			return $('<table>').attr(grid.attibutes).css('display','none').addClass(_class('grid-table')).appendTo($('<div>').addClass(_class('grid-content')).appendTo(grid.content));
		}

		function _header(thead){
			switch(grid.displayType){
				case 'table':
					var tr = $('<tr>').addClass(_class('grid-head')).appendTo(thead);
					for(var i=0;i<grid.cols.length;i++){
						var th = $('<th>').addClass(_class('grid-head-col')).css(grid.cols[i].css).attr(grid.cols[i].attr).html(grid.cols[i].title).appendTo(tr);
						if(typeof grid.cols[i].config == 'object'){
							for(config in grid.cols[i].config){
								switch(config){
									case 'sortable':
										th.bind('click',function(){
											if(typeof grid.cols[this.cellIndex].config.sortDirection != 'string'){
												grid.cols[this.cellIndex].config.sortDirection = '';
											}
											_dataSort(_dataSortCheckCol(this.cellIndex,true));
										}).removeClass(_class('grid-head-col')).addClass(_class('grid-head-col-sortAble'));
										if(grid.cols[i].config.sortDirection == 'asc'){
											th.addClass(_class('grid-head-col-sortAsc'));
										}else if(grid.cols[i].config.sortDirection == 'desc'){
											th.addClass(_class('grid-head-col-sortDesc'));
										}
										break;
								}
							}
						}
					}
					break;
				case 'template':
					var tr = $('<tr>').addClass(_class('grid-head')).appendTo(thead);
					break;
			}
		}

		function _nav(){
			var config = 	{current_pag:	grid.currentPage, 
							total_pag	:	grid.totalPage, 
							total_reg	:	grid.totalRows, 
							start_reg	:	grid.startRow, 
							last_reg	:	grid.lastRow};
			
			grid.navText = _replace({text:grid.navText,obj:{selector_text:grid.navSelectorText,result_text:grid.navResultsText},mi:'#',mf:'#',ri:'',rf:''});
			var navBar = $('<div>').css('display','none').addClass(_class('grid-option')).html(_replace({text:grid.navText,obj:config})).appendTo(grid.content);
			
			grid.content.find('img[name=grid_btn_back]').click(function(){
				if(grid.currentPage > 1){
					if(typeof grid.pageChange == 'function'){grid.pageChange(grid,grid.currentPage,'back')}
					grid.currentPage = (grid.currentPage-1 < 1) ? 1 : grid.currentPage-1 ;
					grid.reload();
				}
			});
			grid.content.find('img[name=grid_btn_next]').click(function(){
				if(grid.currentPage < grid.totalPage){
					if(typeof grid.pageChange == 'function'){grid.pageChange(grid,grid.currentPage,'next')}
					grid.currentPage = (grid.currentPage+1 > grid.totalPage) ? grid.totalPage : grid.currentPage+1 ;
					grid.reload();
				}
			});
			
			grid.content.find('img[name^=grid_btn]').css('background-color','');
			grid.content.find('img[name=grid_btn_'+ ((grid.displayType == 'table') ? 'table' : 'template') +']').css('background-color','#1975A3');
			grid.content.find('img[name=grid_btn_'+ ((grid.displayType == 'table') ? 'template' : 'table') +']').click(function(){
				if(typeof grid.displayTypeChange == 'function'){grid.displayTypeChange(grid,grid.displayType)}
				grid.displayType = (grid.displayType == 'table') ? 'template' : 'table';
				_clear();
				_loading();
				_build();
			});
			
			var gs = grid.content.find('select[name=grid_selector]');
			for(var i=0;i<grid.navSelectorOptions.length;i++){
				$('<option>').html(grid.navSelectorOptions[i]).appendTo(gs);
			}
			gs.val(grid.pageSize);
			gs.change(function(){
				if(typeof grid.pageSizeChange == 'function'){grid.pageSizeChange(grid,grid.pageSize)}
				grid.currentPage = 1;
				grid.pageSize = parseInt(this.value);
				grid.reload();
			});
			
			navBar.find('div[class^=grid-option-]').css('visibility','hidden');
			
			for(var i=0;i<grid.navOptions.length;i++){
				navBar.find('div[class=grid-option-'+ grid.navOptions[i] +']').removeClass('grid-option-'+ grid.navOptions[i]).addClass(_class('grid-option-'+ grid.navOptions[i])).css('visibility','visible');
			}
			navBar.find('img[name=grid_btn_table],img[name=grid_btn_template]').css('display','none');
			for(var i=0;i<grid.navDisplayOptions.length;i++){
				navBar.find('img[name^=grid_btn_'+ grid.navDisplayOptions[i] +']').css('display','');
			}
			
			return navBar;
		}

		function _loading(){
			var html = '<img src="'+ grid.loadImage.src +'" width="'+ grid.loadImage.width +'" height="'+ grid.loadImage.height +'" />';
			if(grid.loadImage.src.indexOf('.swf') > 0){
				html = $.fw.utils.flashEmbed({movie:grid.loadImage.src,width:grid.loadImage.width,height:grid.loadImage.height,params:{wmode:'transparent'}});
			}
			$('<div>').addClass(_class('grid-loading')).html(html).appendTo(grid.content);
		}

		function _dataSortCheckCol(ix,change){
			var config = {};
			if(change){
				grid.cols[ix].config.sortDirection = (grid.cols[ix].config.sortDirection == 'asc') ? 'desc' : 'asc';
			}
			config[grid.cols[ix].config.sortable] = grid.cols[ix].config.sortDirection;
			return config;
		}

		function _dataSort(config){
			_clear();
			_loading();
			switch(grid.dataType){
				case 'local':
					grid.data = $(grid.data).sort(config);
					_dataCheck();
					_build();
					break;
				case 'remote':
					_remote(config);
					break;
			}
		}

		function _dataCheck(){
			if(grid.dataType == 'local'){grid.totalRows = grid.data.length}
			grid.totalPage = (grid.pageSize > 0) ? (parseInt(grid.totalRows/grid.pageSize) < parseFloat(grid.totalRows/grid.pageSize)) ? parseInt(grid.totalRows/grid.pageSize)+1 : parseInt(grid.totalRows/grid.pageSize) : 1 ;
			grid.startRow  = (grid.currentPage == 1) ? 0 : (grid.currentPage-1) * grid.pageSize;
			grid.lastRow   = ((grid.currentPage * grid.pageSize - 1) > (grid.totalRows - 1)) ? grid.totalRows - 1 : grid.currentPage * grid.pageSize - 1;
		}

		function _clear(fnc){
			grid.content.empty();
			if(typeof fnc == 'function'){
				fnc();
			}
		}

		function _class(name){
			return grid.themePrefix + name;
		}

		function _replace(config,format){
			config = $.extend({}, $.fn.grid.format_defaults, config);
			var rem = config.text;
			while((rem.indexOf(config.mi) != -1) && (rem.indexOf(config.mf,rem.indexOf(config.mi)+1) != -1)){
				var campo = rem.substring(rem.indexOf(config.mi)+1 , rem.indexOf(config.mf,rem.indexOf(config.mi)+1))
				var value = (typeof format == 'object') ? _format(config.obj[campo],format) : config.obj[campo];
				rem = (value != undefined) ? rem.replace(config.mi + campo + config.mf , value) : rem.replace(config.mi + campo + config.mf , config.ri + campo + config.rf);
			}
			
			return rem;
		}

		function _get(o){
			var g = o;
			while(g.cssName != _class('grid')){
				g = g.parentNode;
			}
			return $.fn.grids[g.id];
		}

		function _format(value,config){
			if(typeof config == 'object'){
				switch(config.type){
					case 'float':
						return ((typeof config.prefix == 'string')?config.prefix:'') + parseFloat(value).toFixed((!isNaN(config.decimal)?config.decimal:2)) + ((typeof config.sufix == 'string')?config.sufix:'');
						break;
				}
			}
			return '#'+value;
		}

		function _getTemplate(key){
			return $.fn.grids[grid.container.attr('id')].templates[key];
		}

		if(typeof settings == 'string'){

			if($.fn.grids[this[0].id] == undefined){
				return this;
			}else{
				grid = $.fn.grids[this[0].id];
				grid.content = this;

				switch(settings){
					case 'clear':
						grid.content.empty();
						break;
					case 'filter':
						if($.isArray(arguments[1])){
							grid.filtred = true;
							grid._filterArgs = arguments[1];
							grid.reload();
						}
						break;
					case 'selected':
						if(grid.data.length != 0){
							switch(grid.displayType){
								case 'table':
									var regIndex = 0;
									grid.content.find('.'+_class('grid-row-selected')).each(function(){
										regIndex = (grid.dataType == 'local') ? ((grid.showHeader) ? this.rowIndex-1 : this.rowIndex) + ((grid.currentPage-1)*grid.pageSize) : (grid.showHeader) ? this.rowIndex-1 : this.rowIndex ;
									});
									return grid.data[regIndex];
									break;
								case 'template':
									var regIndex = 0;
									grid.content.find('tr>td.'+ _class('grid-cell-selected')).each(function(){
										regIndex = ( ((grid.showHeader)?this.parentNode.rowIndex-1:this.parentNode.rowIndex) * grid.templateCols) + this.cellIndex + ((((grid.dataType == 'remote')?1:grid.currentPage)-1)*grid.pageSize);
									});
									return grid.data[regIndex];
									break;
							}
						}else{
							return undefined;
						}
						break;
				}
			}

		}else{

			if($.fn.grids[this[0].id] == undefined){
				grid = $.extend({}, $.fn.grid.defaults, settings);
				grid.content = this;
				grid.filtred = false;
				$.fn.grids[this[0].id] = grid;
				_init();
			}else{
				grid = $.fn.grids[this[0].id];
				grid.content = this;
				grid.filtred = false;
				grid = $.extend(grid, settings);
				grid.reload();
			}

			grid.getDataByElement = function(elem){
				if(grid.displayType == 'table'){
					var ix = (grid.dataType == 'local') ? ((grid.showHeader) ? elem.rowIndex-1 : elem.rowIndex) + ((grid.currentPage-1)*grid.pageSize) : (grid.showHeader) ? elem.rowIndex-1 : elem.rowIndex ;
				}else{
					var ix = ( ((grid.showHeader)?elem.parentNode.rowIndex-1:elem.parentNode.rowIndex) * grid.templateCols) + elem.cellIndex + ((grid.currentPage-1)*grid.pageSize);
				}
				return grid.data[ix];
			}
			grid.reload = function(){
				_clear(function(){
					_loading();
					switch(grid.dataType){
						case 'local':
							_dataCheck();
							_build();
							break;
						case 'remote':
							_remote();
							break;
					}	
				});
			}

			if(grid.returnGrid){
				return grid;
			}else{		
				return this;	
			}

		}
	};
	
	$.fn.grid.defaults = {
		data				:	[], /*JSON ARRAY*/
		cols				:	[], /**/
		templates			:	{},
		filtred				: 	false,
		returnGrid			:	false, /*TO DO*/
		dataType			:	'remote', /*remote, local, fw*/
		displayType			:	'table', /*table, template*/
		templateCols		:	1,
		width				:	'100%',
		themePrefix			:	'',
		currentPage			:	1,
		totalPage			:	0,
		totalRows			:	0,
		startRow			:	0,
		lastRow				:	0,
		pageSize			:	5,
		attibutes			:	{'cellpadding':2,'cellspacing':1,'border':0},
		showHeader			:	true,
		showFooter			:	false,
		requestURL			:	'/grid', /*padrao*/
		requestParams		:	{},
		requestID			:	'', /*ID do grid no FW ou no Case*/
		noResultsText		:	'sem resultados',
		navPosition			:	'top', /*top, bottom, both, none*/
		navOptions			:	['display','nav','results','selector'], /*display, selector, nav, results, filter, full*/
		navDisplayOptions	:	['table'], /*table, template*/
		navSelectorOptions	:	[5,20,50,100],
		navSelectorText		:	'por p&aacute;gina',
		navResultsText		:	'resultados',
		navText				:	'<div class="grid-option-filter"><img name="grid_btn_filter" src="/adm/img/ic-search.png" title="filtrar resultados" /><div>filtrar</div></div>'+
								'<div class="grid-option-display">'+
								'	<img name="grid_btn_template" src="/adm/img/ic-cols.png" title="exibir em colunas" />'+
								'	<img name="grid_btn_table" src="/adm/img/ic-grid.png" title="exibir em tabela" />'+
								'</div>'+
								'<div class="grid-option-selector"><select name="grid_selector"></select> #selector_text#</div>'+
								'<div class="grid-option-nav">'+
								'	<img name="grid_btn_back" src="/adm/img/ic-back.png" title="p&aacute;gina anterior" />'+
								'	<div><span class="grid-option-nav-currentPage">%current_pag%</span> de <span class="grid-option-nav-totalPage">%total_pag%</span></div>'+
								'	<img name="grid_btn_next" src="/adm/img/ic-next.png" title="pr&oacute;xima p&aacute;gina" />'+
								'</div>'+
								'<div class="grid-option-results"><span class="grid-option-nav-totalReg">%total_reg%</span> #result_text#</div>', /*current_pag, total_pag, total_reg, start_reg, last_reg*/
		navFilterSettings	:	null, /*jQuery.form configuration*/
		navShowFilterOptions:	true,
		sortBy				:	[],
		selectionMode		:	'none', /*none, single, multiple*/
		selectionRecord		:	false, /*nao implementado - com erros*/
		formatOptions		:	'',
		loadImage			:	{src:'/img/loading.gif',width:40,height:40},
		rowClick			:	null,
		rowSelect			:	null,
		cellClick			:	null,
		cellSelected		:	null,
		pageChange			:	null,
		pageSizeChange		:	null,
		displayTypeChange	:	null,
		gridLoaded			:	null
		
	};
	$.fn.grid.cols_defaults = {title:'',width:0,text:'',sortable:false,sorted:false,sortDir:'asc'};
	$.fn.grid.format_defaults = {text:'',obj:{},mi:'%',mf:'%',ri:'#',rf:'#'};
	/*=================================================================================================================================================*/	
	$.fn.forms = {};
	$.fn.form = function(settings){
		
		var form = $.extend({}, $.fn.form.defaults, settings);
		form.content = this;
		
		function _init(){
			form.content.addClass('form-content');			
			_load();
		}
		
		function _load(){
			var params = {};
			params = $.extend({}, params, form.requestParams);
			if(typeof form.formBeforeLoad == 'function'){form.formBeforeLoad(form)}
			$.post(form.requestURL +'/'+ form.requestAction +'/'+ form.requestID,params,function(data){
				form.content.html((form.dictionary != null) ? _replace({text:data ,obj:form.dictionary})  : data);
				if(typeof form.formLoaded == 'function'){form.formLoaded(form)}
				_pos();
				_script();
			});
		}
		
		function _pos(){
			_mask();
			
			var pos = $.fn.fancybox.getViewport();
			form.content.css('left', ((form.content.width()	+ 36) > pos[0] ? pos[2] : pos[2] + Math.round((pos[0] - form.content.width() - 36) / 2)));
			form.content.show();
		}
		
		function _script(){
			if(typeof form.requestScript == 'string'){
				if(typeof form.scriptCheckLoad == 'function'){
					if(form.scriptCheckLoad()){
						$.getScript('/script/'+form.requestScript+'/',function(){
							if(typeof form.scriptLoaded == 'function'){form.scriptLoaded()}
						})
					}else{
						if(typeof form.scriptLoaded == 'function'){form.scriptLoaded()}
					}
				}else{
					$.getScript('/script/'+form.requestScript,function(){
						if(typeof form.scriptLoaded == 'function'){form.scriptLoaded()}
					})
				}
			}
			if(typeof form.load == 'function'){form.load(form)}
			if(form.content.hasClass('grid-filter')){
				form.content.hide();
			}
		}
		
		function _format(value,config){
			if(typeof config == 'object'){
				switch(config.type){
					case 'float':
						return ((typeof config.prefix == 'string')?config.prefix:'') + parseFloat(value).toFixed((!isNaN(config.decimal)?config.decimal:2)) + ((typeof config.sufix == 'string')?config.sufix:'');
						break;
				}
			}
			return '#'+value;
		}
		
		function _mask(){
			$('.form-type-data').mask('99/99/9999');
			$('.form-type-fone').mask('(99) 9999-9999');
			$('.form-type-cep').mask('99999-999');
		}
		
		function _replace(config,format){
			config = $.extend({}, $.fn.form.replace_defaults, config);
			var rem = config.text;
			while((rem.indexOf(config.mi) != -1) && (rem.indexOf(config.mf,rem.indexOf(config.mi)+1) != -1)){
				var campo = rem.substring(rem.indexOf(config.mi)+1 , rem.indexOf(config.mf,rem.indexOf(config.mi)+1))
				var value = (typeof format == 'object') ? _format(config.obj[campo],format) : (typeof config.obj == 'object')?config.obj[campo]:'';
				rem = (value != undefined) ? rem.replace(config.mi + campo + config.mf , value) : rem.replace(config.mi + campo + config.mf , config.ri + campo + config.rf);
			}
			
			return rem;
		}

		if(typeof $.fn.forms[this[0].id] == 'object'){
			_init();
		}else{
			$.fn.forms[this[0].id] = form;
			_init();
		}
		return this;
	}
	$.fn.form.defaults = {
		requestURL			:	'/form', /*padrao*/
		requestParams		:	{},
		requestID			:	'', /*ID do form no FW ou no Case*/
		requestAction		:	'get',
		requestScript		:	null,
		dictionary			:	null, /*{label:traducao,label2:traducao}*/
		scriptCheckLoad		:	null,
		scriptLoaded		:	null		
	};
	$.fn.form.replace_defaults = {text:'',obj:{},mi:'%',mf:'%',ri:'#',rf:'#'};
	
	/*=================================================================================================================================================*/
	$.fn.combos = {};
	$.fn.combo = function(settings){
		
		if(typeof settings == 'string'){

			var cmb = $.fn.combos[this[0].id];
			switch(settings){
				case 'data':
					return cmb.data;
					break;
				case 'value':
					if(arguments[1] == undefined){
						return cmb.value.val();
					}else{
						cmb.vals = arguments[1];
						cmb.setValue(arguments[2]);
						return this;
					}
					break;
			}

		}else{
		
			var cmb = $.extend({}, $.fn.combo.defaults, settings);

			switch(cmb.comboType){
				case 'normal':
					cmb.content = (this[0].tagName.toLowerCase() != 'select') ? $('<select>').addClass(cmb.comboClass).appendTo(this) : this;
					cmb.value = cmb.content;
					$.fn.combos[this[0].id] = cmb;
					_init();
					break;
				case 'sequential':
					cmb.content = this;
					$(this).addClass('form-combo-sequence-content').empty();
					cmb.value = $('<input>').attr({type:'hidden',id:this[0].id + '-value'}).appendTo(this);
					cmb.text = $('<input>').attr({type:'hidden',id:this[0].id + '-text'}).appendTo(this);
					for(var i=0;i<cmb.comboSequence.length;i++){
						if(i < cmb.comboSequence.length-1){
							var tcmb = $('<select>').addClass(cmb.comboClass).attr({id:cmb.comboSequence[i].id}).change(function(){
								cmb.clearSequence(this.id);
								var c = cmb.getSequence(this.id);
								if(c != null){
									if(typeof c.optionNull == 'object'){
										if(c.optionNull.value != this.value){
											cmb.value.val(this.value);
											if(cmb.sequenceToText){
												cmb.selectSequenceText(this,c);
											}else{
												$((c.id.indexOf('#') != 0)?'#'+ c.id:c.id).combo(c);
											}
										}
									}
								}else{
									cmb.value.val(this.value);
									if(cmb.sequenceToText){
										cmb.selectSequenceText(this,c);
									}else{
										$((c.id.indexOf('#') != 0)?'#'+c.id:c.id).combo(c);
									}
								}
							}).appendTo(this);
							if(cmb.sequenceToText){
								$('<span>').attr({id:cmb.comboSequence[i].id +'-text'}).hide().click(function(){
									cmb.clearSequence(this.id.substring(0,this.id.lastIndexOf('-')));
									$(this).hide();
									var c = $('#'+ this.id.substring(0,this.id.lastIndexOf('-'))).css('display','inline-block');
									if(c[0].options.length == 0){
										var config = cmb.getSequence(c[0].id,'self');
										var prev_config = cmb.getSequence(c[0].id,'prev');
										config.requestParams.parentLabel = $(((prev_config.id.indexOf('#') != 0)?'#'+ prev_config.id:prev_config.id)+'-text').html();
										$((config.id.indexOf('#') != 0)?'#'+ config.id : config.id).combo(config);
									}
									c[0].selectedIndex = 0;
								}).appendTo(this);							
							}
							$('<span>').attr({id:cmb.comboSequence[i].id +'-sep'}).html(cmb.sequenceSeparator).appendTo(this);
						}else{
							$('<select>').addClass(cmb.comboClass).attr({id:cmb.comboSequence[i].id}).change(function(){
																												cmb.value.val(this.value);
																												$(this).hide();
																												$('#'+ this.id +'-text').html($(this).find('option:selected').text()).css('display','inline-block');
																											}).appendTo(this);
							if(cmb.sequenceToText){
								$('<span>').attr({id:cmb.comboSequence[i].id +'-text'}).hide().click(function(){
									$(this).hide();
									var c = $('#'+ this.id.substring(0,this.id.lastIndexOf('-'))).css('display','inline-block');
									if(c[0].options.length == 0){
										var config = cmb.getSequence(c[0].id,'self');
										var prev_config = cmb.getSequence(c[0].id,'prev');
										config.requestParams.parentLabel = $(((prev_config.id.indexOf('#') != 0)?'#'+ prev_config.id:prev_config.id)+'-text').html();
										$((config.id.indexOf('#') != 0)?'#'+ config.id : config.id).combo(config);
									}
									c[0].selectedIndex = 0;
								}).appendTo(this);							
							}
						}
					}
					$((cmb.comboSequence[0].id.indexOf('#') != 0)?'#'+cmb.comboSequence[0].id:cmb.comboSequence[0].id).combo(cmb.comboSequence[0]);
					cmb.clearSequence(cmb.comboSequence[0].id);
					$.fn.combos[this[0].id] = cmb;
					break;
				case 'search':
				
					cmb.content = (this[0].tagName.toLowerCase() != 'select') ? $('<select>').addClass(cmb.comboClass).appendTo(this) : this;
					cmb.parent = cmb.content.parent();
					cmb.field = $('<input type="text">').attr('id',cmb.content.attr('id')+'-searcher').addClass('form-combo-search-input');
					var val = $('<input type="hidden">').attr('id',cmb.content.attr('id'));
					cmb.content.replaceWith(cmb.field);
					cmb.content = val;
					cmb.value = cmb.content;
					cmb.content.appendTo(cmb.parent);
					cmb.results = $('<div>').hide().addClass('form-combo-search').appendTo(cmb.parent);
					$('<ul>').appendTo(cmb.results);
					
					cmb.field.keyup(function(event){
						if(event.keyCode == 13 && this.value.length > cmb.searchMinLength){
							if(cmb.results.css('display') != 'none'){
								cmb.field.val(cmb.results.find('ul>li.selected').text());
								cmb.content.val(cmb.results.find('ul>li.selected').attr('fw:value'));
								cmb.results.hide();
								if(typeof cmb.searchSelect == 'function'){cmb.searchSelect(cmb.results.find('ul>li.selected').text(),cmb.results.find('ul>li.selected').attr('fw:value'))}
							}else{
								_remote(this.value);
							}
						}else if(event.keyCode == 40){
							if(cmb.results.find('ul>li.selected').next().length == 1){
								cmb.results.find('ul>li.selected').removeClass('selected').next().addClass('selected');				
							}
						}else if(event.keyCode == 38){
							if(cmb.results.find('ul>li.selected').prev().length == 1){
								cmb.results.find('ul>li.selected').removeClass('selected').prev().addClass('selected');
							}
						}
					});
					$.fn.combos[this[0].id] = cmb;
					break;
			}
		
			return this;
		
		}
		
		function _init(){
			switch(cmb.dataType){
				case 'local':
					_build();
					break;
				case 'remote':
					_remote();
					break;
			}
		}
		
		function _remote(value){
			var rparams = {};
			for(param in cmb.requestParams){
				if(typeof cmb.requestParams[param] == 'object'){
					if(typeof cmb.requestParams[param].field == 'string'){
						rparams[param] = $((cmb.requestParams[param].field.indexOf('#') != 0)?'#'+cmb.requestParams[param].field:cmb.requestParams[param].field).val();
					}
				}else{
					rparams[param] = cmb.requestParams[param];
				}
			}
			if(typeof value == 'string'){rparams['value'] = value}
			var params = $.extend({}, {cmb:cmb.requestID}, rparams);
			$.post(cmb.requestURL,params,function(data){
				cmb.data = data;
				_build();
			},'json');
		}
		
		function _build(){
			if(cmb.comboType == 'search'){
				cmb.results.find('ul').empty();
				if(cmb.data.length > 0){
					for(var i=0;i<cmb.data.length;i++){
						$('<li>').attr('fw:value',cmb.data[i].value).html(cmb.data[i].label).appendTo(cmb.results.find('ul'));
					}
				}else{
					if(typeof cmb.optionNull == 'object'){
						$('<li>').attr('fw:value',cmb.optionNull.value).html(cmb.optionNull.label).appendTo(cmb.results.find('ul'));
					}
				}
				if(cmb.otherOptions.length > 0){
					for(var i=0;i<cmb.otherOptions.length;i++){
						$('<li>').attr('fw:value',cmb.otherOptions[i].value).html(cmb.otherOptions[i].label).appendTo(cmb.results.find('ul'));
					}
				}
				cmb.results.find('ul>li').click(function(){
					cmb.field.val($(this).text());
					cmb.content.val($(this).attr('fw:value'));
					cmb.results.hide();
					if(typeof cmb.searchSelect == 'function'){cmb.searchSelect($(this).text(),$(this).attr('fw:value'))}
				});
				cmb.results.show().find('li:first').addClass('selected');
				cmb.results.css({left:cmb.field.position().left,top:cmb.field.position().top+cmb.field[0].offsetHeight,width:cmb.field[0].offsetWidth-5});
			}else{
				cmb.content.empty();
				if(cmb.data.length > 0){
					if(cmb.data[0].value > 0){
						if(cmb.optionNull != null){
							var opt = $('<option>').attr('value',cmb.optionNull.value).html(cmb.optionNull.label).appendTo(cmb.content);
						}
					}

					for(var i=0;i<cmb.data.length;i++){
						var opt = $('<option>').attr('value',cmb.data[i].value).html(cmb.data[i].label).appendTo(cmb.content);
						if(typeof cmb.data[i].change == 'function'){
							opt.bind('change',cmb.data[i].change);
						}
					}
					if(cmb.selectedValue != null){
						cmb.content.val(cmb.selectedValue);
					}
	
				}else{
					if(typeof cmb.optionNull == 'object'){
						var opt = $('<option>').attr('value',cmb.optionNull.value).html(cmb.optionNull.label).appendTo(cmb.content);
					}
				}
				if(cmb.otherOptions.length > 0){
					for(var i=0;i<cmb.otherOptions.length;i++){
						var opt = $('<option>').attr('value',cmb.otherOptions[i].value).html(cmb.otherOptions[i].label).appendTo(cmb.content);
						if(typeof cmb.otherOptions[i].change == 'function'){
							opt.bind('change',cmb.otherOptions[i].change);
						}
					}
				}
			}
			if(typeof cmb.load == 'function'){cmb.load(cmb)}
			if(typeof cmb.change == 'function'){
				cmb.content.change(function(){
					if(cmb.optionNull != null){
						cmb.change(this, (this.selectedIndex > 0)?cmb.data[this.selectedIndex-1]:cmb.optionNull);
					}else{
						cmb.change(this, cmb.data[this.selectedIndex]);
					}
				});
			}
		}
		
	};
	$.fn.combo.defaults = {
		comboType			:	'normal', /*normal, sequencial, search*/
		dataType			:	'remote', /*remote, local, fw*/
		data				:	[],
		requestURL			:	'/combo', /*padrao*/
		requestParams		:	{},
		requestID			:	'',
		comboClass			:	'',
		textClass			:	'',
		comboSequence		:	[],
		sequenceSeparator	:	' / ',
		sequenceToText		:	false,
		selectedValue		:	null,
		optionNull			:	null,
		otherOptions		:	[],
		load				:	null,
		change				:	null,
		searchMinLength		:	3,
		searchSelect		:	null,
		getSequence			:	function(id,t){
			t = (t == undefined) ? 'next' : t;
			for(var i=0;i<this.comboSequence.length;i++){
				if(this.comboSequence[i].id == id){
					switch(t){
						case 'next':
							return (i+1 < this.comboSequence.length) ? this.comboSequence[i+1] : null;
							break;
						case 'prev':
							return (i-1 > 0) ? this.comboSequence[i-1] : null;
							break;
						default:
							return this.comboSequence[i];
							break;
					}
				}
			}
			return null;
		},
		clearSequence		:	function(id){
			for(var i=0;i<this.comboSequence.length;i++){
				if(this.comboSequence[i].id == id){
					var cid = (this.comboSequence[i].id.indexOf('#') != 0)?'#'+this.comboSequence[i].id:this.comboSequence[i].id;
					$(cid +'-text').hide();
					$(cid +'-sep').hide();
					
					for(var j=i+1;j<this.comboSequence.length;j++){
						cid = (this.comboSequence[j].id.indexOf('#') != 0)?'#'+this.comboSequence[j].id:this.comboSequence[j].id;
						$(cid).empty();
						if(this.sequenceToText){
							$(cid).hide();
						}
						$(cid +'-text').hide();
						$(cid +'-sep').hide();
					}
				}
			}
		},
		selectSequenceText	:	function(o,c){
			$(o).hide();
			$('#'+ o.id +'-text').html($(o).find('option:selected').text()).css('display','inline-block');
			var cid = (c.id.indexOf('#') != 0)?'#'+c.id:c.id;
			$(cid).show().combo(c);
			$('#'+ o.id +'-sep').css('display','inline-block');
		},
		setValue : function(value){
			switch(this.comboType){
				case 'normal':
					this.content.val(this.vals);
					break;
				case 'sequential':
					var vals = this.vals.split(this.sequenceSeparator);
					var texts  = this.content.find('span[id$=text]');
					var seps  = this.content.find('span[id$=sep]');
					this.content.find('select').hide();
					for(var i=0;i<vals.length;i++){
						$(texts[i]).html(vals[i]).css('display','inline-block');
						if(i < vals.length-1){
							$(seps[i]).show();
						}
					}
					if(value != undefined){
						this.value.val(value);
					}
					break;
				case 'search':
					this.field.val(this.vals);
					this.content.val(value);					
					break;
			}
				
		}
	};
	/*=================================================================================================================================================*/
	$.fn.overlay = function(settings){
		var ol = (typeof ol == 'object') ? $('<div>').appendTo('body') : $(this);
		
		settings = $.extend({}, $.fn.overlay.defaults, settings);
		ol.addClass('overlay').css({'background-color':settings.color,'z-index':settings.zIndex,'opacity':settings.opacity});
		
		if(typeof settings.click == 'function'){
			ol.click(settings.click);
		}
		
		return ol;
	};
	$.fn.overlay.defaults = {
		opacity			:	0.2,
		zIndex			:	9000,
		color			:	'#000000',
		click			:	null
	};
	/*=================================================================================================================================================*/
	$.fn.filecontrols = {};
	$.fn.filecontrol = function(settings, value){
		
		if(typeof settings == 'string'){
			
			switch(settings){
				case 'default':
					return $.fn.filecontrol.defaults[value];
					break;
				case 'value':
					if(typeof $.fn.filecontrols[this[0].id] == 'object'){
						return $.fn.filecontrols[this[0].id][value];
					}else{
						alert('fw::filecontrol::value:"referencia não encontrada"');
						return this;
					}
					break;
				case 'file':
					if(typeof value == 'object'){
						var fco = $.fn.filecontrols[this[0].id];
						fco.file = value;
						_checkFile(fco);
						$.fn.filecontrols[this[0].id] = fco;
					}
				case 'init':
					if(typeof $.fn.filecontrols[value] == 'object'){
						var fco = $.fn.filecontrols[value];
						fco.swf = $('#man_'+ fco.id)[0];
						fco.swf.addText($.extend(fco.textFormat,{text:fco.findText}));
						if($.isArray(fco.fileType)){
							for(var i=0;i<fco.fileType.length;i++){
								fco.swf.addFileType(fco.fileType[i]);
							}
						}else if(typeof fco.fileType == 'object'){
							fco.swf.addFileType(fco.fileType);
						}
						fco.swf.setOptions({path:fco.path,
											fieldName:fco.fieldName,
											maxSize:fco.maxSize,
											script:fco.script});
						for(param in fco.params){
							fco.swf.addParam(param, fco.params[param]);
						}
						
						_checkFile(fco);
						$.fn.filecontrols[value] = fco;
					}else{
						alert('fw::filecontrol::init:"referencia não encontrada"');
					}
					break;
				case 'upload':
					if(typeof $.fn.filecontrols[this[0].id] == 'object'){
						var fco = $.fn.filecontrols[this[0].id];
						if(typeof value == 'object'){ /*parametros adicionais*/
							for(param in value){
								fco.swf.addParam(param, value[param]);
							}
						}
						_upload(fco);
					}else{
						alert('fw::filecontrol::upload:"referencia não encontrada"');
						return this;
					}
					break;
				case 'handler':
					if(typeof $.fn.filecontrols[value] == 'object'){
						var fco = $.fn.filecontrols[value];
						var file = arguments[3], desc = arguments[4];
						
						switch(arguments[2]){
							case 'select':
								fco.file = file;
								_checkFile(fco);
								fco.activity = false;
								if(typeof fco.onSelect == 'function'){
									fco.onSelect(fco.file);
								}
								break;
							case 'progress':
								var perc = parseInt((desc.bytesLoaded*100)/desc.bytesTotal);
								$(fco.progress).progressbar('value',perc);
								fco.activity = true;
								if(typeof fco.onProgress == 'function'){
									desc.perc = perc;
									fco.onProgress(fco.file,desc);
								}
								break;
							case 'complete':
								fco.progress.hide();
								fco.current.addClass('filecontroll-success').removeClass('filecontroll-fail');
								if(fco.changeFileOption){
									fco.swf.addText($.extend(fco.textFormat,{text:fco.changeText}));
									fco.fc.width(100);
								}
								fco.activity = false;
								if(typeof fco.onComplete == 'function'){
									fco.onComplete(fco.file);
								}
								break;
							case 'completedata':
								fco.progress.hide();
								fco.current.addClass('filecontroll-success').removeClass('filecontroll-fail');
								if(fco.changeFileOption){
									fco.swf.addText($.extend(fco.textFormat,{text:fco.changeText}));
									fco.fc.width(100);
								}
								fco.activity = false;
								if(typeof fco.onComplete == 'function'){
									eval('var ret = '+ desc.data +';');
									fco.onComplete(fco.file,ret);
								}
								break;
							case 'fileSizeError':
								fco.activity = false;
								if(typeof fco.onError == 'function'){
									fco.onError(file,desc);	
								}
								break;
							case 'noFileSelected':
								fco.progress.hide();
								fco.current.addClass('filecontroll-fail').removeClass('filecontroll-success');
								fco.activity = false;
								if(typeof fco.onError == 'function'){
									fco.onError(fco.file,desc);
								}
								break;
							case 'IOError':
								fco.progress.hide();
								fco.current.addClass('filecontroll-fail').removeClass('filecontroll-success');
								fco.activity = false;
								if(typeof fco.onError == 'function'){
									fco.onError(fco.file,desc);
								}
								break;
							case 'securityError':
								fco.progress.hide();
								fco.current.addClass('filecontroll-fail').removeClass('filecontroll-success');
								fco.activity = false;
								if(typeof fco.onError == 'function'){
									fco.onError(fco.file,desc);
								}
								break;
							case 'httpstatus':
								fco.progress.hide();
								fco.current.addClass('filecontroll-fail').removeClass('filecontroll-success');
								fco.activity = false;
								if(typeof fco.onError == 'function'){
									fco.onError(fco.file,desc);
								}
								break;
							case 'open':
								fco.fc.width(1);
								fco.action.hide();
								fco.progress.show();
								fco.activity = true;
								if(typeof fco.onOpen == 'function'){
									fco.onOpen(fco.file,desc);
								}
								break;
							case 'cancel':
								fco.activity = false;
								if(typeof fco.onCancel == 'function'){
									fco.onCancel(fco.file,desc);
								}
								break;
							default:
								alert(arguments[2]);
						}
						$.fn.filecontrols[value] = fco;
					}else{
						alert('fw::filecontrol::handler"referencia não encontrada"');
					}
			}
			
		}else{
			
			$(this).find('.filecontrol').empty();
			
			var fco = $.extend({}, $.fn.filecontrol.defaults, settings);
			fco.id = this[0].id;
			if($(this).find('.filecontrol').size() > 0){
				fco.content = $('<div>').addClass('filecontrol');
				$(this).find('.filecontrol').replaceWith(fco.content);
			}else{
				fco.content = $('<div>').addClass('filecontrol').appendTo(this);
			}
			fco.field = $('<input type="hidden" id="'+ fco.id +'-arq">').appendTo(fco.content);
			fco.current = $('<div>').addClass('filecontrol-file').appendTo(fco.content).hide();
			fco.progress = $('<div>').addClass('filecontrol-progress').progressbar({value:0}).appendTo(fco.content).hide();
			fco.action = $('<div>').addClass('filecontrol-action').html(fco.sendText).appendTo(fco.content).hide().click(function(){
				if($(this).html() == fco.sendText){
					_upload(fco);
				}else{
					_cancel(fco);
				}
			});
			fco.fc = $('<div id="'+ fco.id +'-fc">').addClass('filecontrol-control').appendTo(fco.content);
			$('<div id="'+ fco.id +'-fco">').appendTo(fco.fc);
			swfobject.embedSWF(fco.man, fco.id + '-fco', '100', '20', '9.0.0','/swf/expressInstall.swf', {dispatcherID:fco.id}, {menu:false,wmode:'transparent'}, {id:'man_'+ fco.id});
			$.fn.filecontrols[fco.id] = fco;
			return this;
			
		}
		
		function _upload(fco){
			$.post(fco.requestURL,$.extend({},fco.requestParams,{req:fco.requestID}),function(data){
				fco.swf.addParam('key', data.key);
				fco.swf.upload();
			},'json');
		}
		
		function _cancel(fco){
			fco.swf.addText($.extend(fco.textFormat,{text:fco.findText}));
			fco.current.hide();
			fco.action.hide();
			fco.progress.hide();
			fco.fc.width(100);
		}
		
		function _checkFile(fco){
			if(typeof fco.file == 'object'){
				fco.swf.addText($.extend(fco.textFormat,{text:fco.changeText}));
				var size = (fco.file.size != undefined)?' ('+ ((parseInt((fco.file.size/1024)/1024) < 0) ? parseFloat(fco.file.size/1024).toFixed(2) +' KB' : parseFloat((fco.file.size/1024)/1024).toFixed(2) +' MB')+')':'';
				var html = (size == '')?'<a href="/filecontrol/proposta/'+ fco.file.name +'" title="'+ fco.downloadText +'">'+ fco.file.name.substring(0,fco.currentFileLengthText) +'</a>':'<strong>'+ fco.file.name.substring(0,fco.currentFileLengthText) +'</strong>'+ ((fco.file.name.length > fco.currentFileLengthText)?'...':'') + size;
				fco.current.html(html).attr('title',fco.file.name + size).show();
				fco.fc.width(1);
				for(var i=0;i<fco.actionOption.length;i++){
					switch(fco.actionOption[i]){
						case 'send':
							fco.action.show();
							break;
						case 'change':
							fco.swf.addText($.extend(fco.textFormat,{text:fco.changeText}));
							fco.fc.width(100);
							break;
					}
				}
			}
		}
		
	};
	$.fn.filecontrol.defaults = {
		requestURL				:	'/filecontrol', /*padrao*/
		requestParams			:	{},
		requestID				:	'',
		man						:	'/swf/fcman.swf', /*SWF Manager File*/
		type					:	'upload', /*upload ou download*/
		textFormat				:	{color:0xDDDDDD,font:'Verdana',size:'11',html:true},
		findText				:	'<u>anexar arquivo</u>',
		changeText				:	'<u>trocar arquivo</u>',
		cancelText				:	'<u>cancelar</u>',
		sendText				:	'<u>enviar</u>',
		downloadText			:	'baixar arquivo',
		actionOption			:	['change','send'],
		fileType				:	{description:'Todos os Arquivos (*.*)',extension:'*.*'}, /* array de objetos/objeto, ex: {description:'Imagens (*.jpg, *.jpge, *.gif, *.png)',extension:'*.jpg;*.jpge;*.gif;*.png'}*/
		path					:	'/upload/',
		maxSize					:	(2 * 1024 * 1024), /*2 MB*/
		script					:	'',
		params					:	{},
		fieldName				:	'arquivo',
		uploadOnSelect			:	false,
		changeFileOption		:	true,
		currentFileLengthText	:	20
	};
	/*=================================================================================================================================================*/
	$.fw = {
		//CORE -----------------------------------------------------------------------------------------
		init:function(){
			this.advisor.init();
		},
		find:function( selector , ix, bool){
			var ret = (bool) ? false : null;
			if(this[selector] != undefined){
				if(this[selector]._itens != undefined){
					for(var i=0;i<this[selector]._itens.length;i++){
						if(this[selector]._itens[i].cod == ix){
							ret = (bool) ? true : this[selector]._itens[i];
						}
					}
				}
			}
			return ret;
		},
		//utils ---------------------------------------------------------------------------------------
		utils:{
			isMod10:function(valor){
				var ar = new Array( valor.length ), i = 0, sum = 0;
				for(i=0;i<valor.length;++i){ar[i] = parseInt(valor.charAt(i));}
				for(i=ar.length-2;i>=0;i-=2){ar[i] *= 2;if(ar[i] > 9) ar[i]-=9;}
				for(i=0;i<ar.length;++i){sum += ar[i];}
				return (((sum%10)==0)?true:false);
			},
			viewport:function(){
				return {width:$(window).width(),height:$(window).height(),scrollLeft:$(document).scrollLeft(),scrollTop:$(document).scrollTop()};
			},
			flashEmbed:function( config ){
				var def = {
					params:{}
				};
				
				var opt = $.extend({},def,config), dhtml = '', chtml = '';
				
				if(opt.width){dhtml += 'width="'+ opt.width +'" '}
				if(opt.height){dhtml += 'height="'+ opt.height +'" '}


				var fhtml = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0" '+ dhtml +' >';
				fhtml += '<param name="movie" value="'+ opt.movie +'" />';
				
				for(a in opt.params){
					fhtml += '<param name="'+ a +'" value="'+ opt.params[a] +'" />';
					chtml += a +'="'+ opt.params[a] +'" ';
				}
				
				fhtml += '<embed src="'+ opt.movie +'" '+ chtml +' '+
						'pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash" '+
						'type="application/x-shockwave-flash" '+ dhtml +'></embed></object>';
						
				return fhtml;
			}
		},
		//advisor --------------------------------------------------------------------------------------
		advisor:{
			init:function(){
				this.overlay = $('<div>').attr('id','advisor-overlay').css({'opacity':0}).appendTo('body').hide();
				this.box = $('<div>').attr('id','advisor-box').appendTo('body').hide();
				this.html = $('<div>').attr('id','advisor-html').appendTo(this.box);
				this.content = $('<div>').attr('id','advisor-content').appendTo(this.html);
				this.icon = $('<div>').attr('id','advisor-icon').appendTo(this.html);
				this.title = $('<div>').attr('id','advisor-title').appendTo(this.content);
				this.text = $('<div>').attr('id','advisor-text').appendTo(this.content);
				this.bottom = $('<div>').attr('id','advisor-bottom').appendTo(this.content);
			},
			warn:function( config , callback ){
				
				var def = {
					title:'AVISO!',
					message:'',
					buttons:[
						{label:'OK'}
					],
					theme:'alert',
					themeFlashIcon:undefined, /*{movie:'movie.swf',height:50,width:50,params:{'quality':'high'}}*/
					animationSpeed:'fast',
					overlayOpacity:0.6,
					callback:undefined
				};
				
				if(typeof config == 'string'){
					config = {message:config};
				}
				if(typeof callback == 'function'){
					config.callback = callback;
				}
				
				var opt = $.extend({},def,config);
				var vp = $.fw.utils.viewport();
				
				this.overlay.css({'width':vp.width+vp.scrollLeft,'height':vp.height+vp.scrollTop}).show().fadeTo(opt.animationSpeed,opt.overlayOpacity,function(){
					$(window).bind("resize scroll", $.fw.advisor.adjust);
					$.fw.advisor.box.removeAttr('class').attr('class','advisor-box-'+opt.theme);
					$.fw.advisor.title.removeAttr('class').attr('class','advisor-title-'+opt.theme).html(opt.title);
					$.fw.advisor.icon.empty().removeAttr('class').attr('class','advisor-icon-'+opt.theme);
					if(typeof opt.themeFlashIcon == 'object'){
						$.fw.advisor.icon.html($.fw.utils.flashEmbed( opt.themeFlashIcon ))
					}
					$.fw.advisor.text.html(opt.message);
					$.fw.advisor.bottom.empty();
					for(var i=0;i<opt.buttons.length;i++){
						var btn = $('<input>').attr({'type':'button','value':opt.buttons[i].label,'class':'advisor-button-'+opt.theme});
						if(typeof opt.buttons[i].action == 'function'){
							btn.bind('click',opt.buttons[i].action);
						}
						if(typeof opt.callback == 'function' && opt.buttons[i].noCallbackPropagation == undefined){
							btn.bind('click',opt.callback);
						}
						btn.bind('click',$.fw.advisor.hide).appendTo($.fw.advisor.bottom);
					}
					$.fw.advisor.box.css( {'width':vp.width+vp.scrollLeft,'top':((vp.height+vp.scrollTop)/2)-($.fw.advisor.box.height()/2)} ).show(opt.animationSpeed,function(){
						$('#advisor-bottom>input:first').focus();
					});
				});

				
			},
			hide:function(){
				$.fw.advisor.box.hide('fast',function(){
					$.fw.advisor.overlay.hide('fast');
					$(window).unbind("resize scroll");
				});
			},
			adjust:function(){
				var vp = $.fw.utils.viewport();
				
				$.fw.advisor.overlay.css( {'width':vp.width+vp.scrollLeft,'height':vp.height+vp.scrollTop} );
				$.fw.advisor.box.css( {'width':vp.width+vp.scrollLeft,'top':((vp.height+vp.scrollTop)/2)-($.fw.advisor.box.height()/2)} );
			}
			
		}
	}
	
})(jQuery);


String.prototype.trim = function(s){
	var ts='', p=false, c='', u=0;
	for(var i=0;i < this.length;i++){
		c = (s == undefined) ? this[i] : s.charAt(i);
		if(c == ' '){
			if(p){ts += c}
		}else{
			ts+=c;u=i;p=true;
		}
	}	
	return (c == ' ') ? ts.substring(0,u) : ts;
};
String.prototype.getN = function(s){
	var ts = '';
	for(var i = 0;i < s.length;i++){
		var c = (s == undefined) ? this[i] : s.charAt(i) ;
		if( (c >= '0') && (c <= '9') ){
			ts+=''+c;
		}
	}
	return ts;
};
String.prototype.isDate = function(s){
	var re = /(((^([0][1-9]|[12][0-9])(\/|-)02(\/|-)([1-3][0-9])([13579][26]|[02468][048]))|(^([0][1-9]|[12][0-8])(\/|-)02(\/|-)([1-3][0-9])([02468][12356]|[13579][13579]))|((^([012][0-9]|30)(\/|-)(0[469]|11))|(^([0][1-9]|[12][0-9]|3[01])(\/|-)(0[13578]|1[02]))(\/|-)([1-3][0-9][0-9][0-9])))((\b)(([0-1][0-9])|(2[0-3])):[0-5]([0-9])$))|((^([0][1-9]|[12][0-9])(\/|-)02(\/|-)([1-3][0-9])([13579][26]|[02468][048]))|(^([0][1-9]|[12][0-8])(\/|-)02(\/|-)([1-3][0-9])([02468][12356]|[13579][13579]))|((^([012][0-9]|30)(\/|-)(0[469]|11))|(^([0][1-9]|[12][0-9]|3[01])(\/|-)(0[13578]|1[02]))(\/|-)([1-3][0-9][0-9][0-9])))|((([0-1][0-9])|(2[0-3])):[0-5]([0-9])$)/;
	return re.test( (s == undefined) ? this : s );
}
