YAHOO.namespace( "Smartweb.util" );

function showLabel (id, label)
{
	document.getElementById(id).innerHTML = label;
}

function showHide ( elem, img, bSaveState, bIco )
{ 
	var elem;
	var elemtStyle;
	var elemtImg;
	
	if ( bSaveState == null )
		bSaveState = false;
	
	if ( typeof ( elem ) == 'string' ) {
		var allElems = document.getElementsByName (elem);
		for (var i=0; i < allElems.length; i++)
			showHide (allElems[i], img, bSaveState, bIco);
		
		if (allElems.length == 0)
			elem = document.getElementById( elem );
		else
			return;
	}
	
	if (elem == null)
		return -1; 
	
	elemtStyle 	= elem.style;
	elemtImg 	= ( img ? document.getElementById(img) : null );
	
	if ( bSaveState )
		SetShowHideState ( elem.id, img );
		
	if ( elemtImg != null )
	{
		var sDisplay = elemtStyle.display;
		elemtStyle.display = ( sDisplay == "none" ? "" : "none" );
		elemtImg.alt = ( sDisplay == "none" ? "Retrair" : "Expandir" );
		
		if (bIco) {						

			if ( sDisplay == "none" ) 				
				YAHOO.util.Dom.replaceClass(elemtImg, "ico plus", "ico minus");
			else
				YAHOO.util.Dom.replaceClass(elemtImg, "ico minus", "ico plus");
		}	
		else {
			elemtImg.src = YAHOO.Smartweb.util.getRoot() + ( sDisplay == "none" ? "img/icoMinus.gif" : "img/icoPlus.gif" ) ;
		}	
	}
	
}

function SetShowHideState ( id, img )
{
	var showHideStateAux = GetCookie ( "showHideState" );
	var showHideStateArray;
	var i, bAdd;
	
	if ( showHideStateAux == null ) 
	{
		showHideStateAux	= "";
		showHideStateArray	= new Array ();
	}
	else
		showHideStateArray	= showHideStateAux.split ( "\n" );
	
	bAdd = !( showHideStateAux.indexOf (id) > -1 );
	
	if ( bAdd )
	{
		showHideStateArray.push ( id + "\t" + img );
	}
	else
	{
		for ( i = 0; i < showHideStateArray.length; i++)
			if ( showHideStateArray[i].indexOf (id) == 0 )
				break;
				
		if ( i >= showHideStateArray.length )
			return;
		else
		{
			if ( i == 0 )
				showHideStateArray = showHideStateArray.slice ( 1, showHideStateArray.length  );
			else if ( i == ( showHideStateArray.length - 1 ) )
				showHideStateArray = showHideStateArray.slice ( 0, showHideStateArray.length - 1 );
			else
				showHideStateArray = showHideStateArray.slice ( 0, i ).concat ( showHideStateArray.slice ( i + 1, showHideStateArray.length ) );
		}
	}
	
	SetCookie ( "showHideState", showHideStateArray.join ( "\n" ) );
}

function RestoreShowHideState ( )
{
	var showHideStateAux 	= GetCookie ( "showHideState" ) ;
	var showHideStateArray;
	
	if ( showHideStateAux == null ) 
	{
		showHideStateAux	= "";
		showHideStateArray	= new Array ();
	}
	else
		showHideStateArray	= showHideStateAux.split ( "\n" );	
	
	for ( var i = 0; i < showHideStateArray.length; i++)
	{
		showHideStateAux = showHideStateArray[i].split ( "\t" ) ;
		showHide ( showHideStateAux[0], showHideStateAux[1] ) ;
	}
}

/***************************************************************
Função que deve ser usada nos eventos onKey´s para monitorar
uma determinada tecla e chamar o evento onClick de um botão

*************************************************************/		
function onKey(e, pTecla, pBotao) {

	var characterCode ; 

	if (e.keyCode) characterCode = e.keyCode;
	else if (e.which) characterCode = e.which;
	
    if (characterCode == pTecla) {
		var followingInput = document.getElementById(pBotao);
		followingInput.focus();
		followingInput.onclick();	
    }
}


/***************************************************************
Abre uma janela que contem uma datawindow para buscar um determinado
valor e preencher uma outra datawindow com este valor

sURLPagina: página de busca
sColumn: Nome da coluna a ser preenchida
sDWname: Nome da DataWindow a ser preenchida
nRow: Linha a ser preenchida
nWidth: Largura da Janela que será Aberta

*************************************************************/		
function windowBuscaValue (sURLPagina, nWidth, sDWName, sColumn, nRow) {
  window.open(sURLPagina + "?nDWRow=" + nRow + "&sDWName=" + sDWName + "&sDWColumn=" + sColumn, "", "menubar=no,toolbar=no,width=" + nWidth + ",status=yes,scrollbars=yes");
}


/***************************************************************
Abre uma janela que contem uma datawindow para buscar dois determinados
valores e preencher uma outra datawindow com estes valores

sURLPagina: página de busca
sColumnValue: Nome da coluna a ser preenchida
sColumnLabel: Nome da outra coluna a ser preenchida
sDWname: Nome da DataWindow a ser preenchida
nRow: Linha a ser preenchida
nWidth: Largura da Janela que será Aberta

*************************************************************/		
function windowBuscaValueLabel (sURLPagina, nWidth, sDWName, sColumnValue, sColumnLabel, nRow) {
  window.open(sURLPagina + "?nDWRow=" + nRow + "&sDWName=" + sDWName + "&sDWColumnValue=" + sColumnValue + "&sDWColumnLabel=" + sColumnLabel , "", "menubar=no,toolbar=no,width=" + nWidth + ",status=yes,scrollbars=yes");
}


/***************************************************************
Funcao que retira os espaços em branco no inicio e no fim de 
uma string
*************************************************************/		
function trim(s) {
  while (s.substring(0,1) == ' ') {
    s = s.substring(1,s.length);
  }
  while (s.substring(s.length-1,s.length) == ' ') {
    s = s.substring(0,s.length-1);
  }
  return s;
}

 /***************************************************************
 Funcao que Verifica se um campo eh vazio
 Parametros : field --> Nome do campo
              msg   --> mensagems que será exibida se houver erro
*************************************************************/							  
function isVazio(valor,msg){
   var thisChar;
   var counter = 0;
   var str;
   
    str = valor;
    if (isnull(str))
    {       if (typeof(msg) != "undefined"){ 
		   alert(msg)
//		   field.focus()
		}   
		return true;
    }
    
    if ( str == "" ) {
            if (typeof(msg) != "undefined"){ 
		   alert(msg)
//		   field.focus()
		}   
		return true;
    }
    
    for (var i=0; i<str.length; i++){
       thisChar = str.substring(i, i+1);
       if (thisChar == " ")
           counter++;
   }
   
   if (counter == str.length){
       if (typeof(msg) != "undefined"){
	    alert(msg);
  //        field.focus();		
	 }   
      return true;
   }
   
    return false;	
}


/////////////////////////////////////////
//
//	Descrição: Exibe/Esconde Mensagens no Browser estilo GMail.
//	Autor: Daniel Gomes Silveira (danielgomes@medicware.com.br)
//
/////////////////////////////////////////

//////////////////////
//	Configuração
//////////////////////
var msgDefault = "Aguarde&#8230;";
//var msgDefault = "<table><tr><td><div class='ico loading'></div></td><td style='color: white; font-size: 12px'>Carregando...</td></tr></table>";

//////////////////////
//	Core
/////////////////////
var bIsIE = ( navigator.appName.indexOf("Microsoft") != -1 );
var bIsIENOTopera = document.all && navigator.userAgent.indexOf( "Opera" ) == -1;

//////////////////////
//	Objeto Mensagem
//	Usado para mostrar mensagens na aplicação WEB.
//////////////////////
function MsgClass ( msgHtml, msgId )
{
	if ( msgHtml == null )
		msgHtml = msgDefault;
	
	if  ( msgId == null )
		msgId = "msgBox";
	
	this.msgHtml 	= msgHtml;
	this.msgId 		= msgId;
}

//////////////////////
//	Seta a posição inicial do MsgBox
//////////////////////
/* function posMsgBoxOnUpperRight ( msgBox, win ) {

	var dsocleft 		= bIsIE? win.document.body.scrollLeft : win.pageXOffset;
	var dsoctop 		= bIsIE? win.document.body.scrollTop : win.pageYOffset;
	var window_width 	= bIsIENOTopera? win.document.body.clientWidth : win.innerWidth - 16;
	var window_height 	= bIsIENOTopera? win.document.body.clientHeight : win.innerHeight;
	
	if ( bIsIE || win.document.getElementById ) {
		msgBox.style.left 	= ( parseInt(dsocleft) + window_width - msgBox.offsetWidth ) + "px";
		msgBox.style.top 	= parseInt(dsoctop) + "px";
	}
	else if ( win.document.layers ) {
		msgBox.left = dsocleft + window_width - msgBox.document.width;
		msgBox.top 	= dsoctop; 
	}
}

function posMsgBoxOnCursor ( msgBox, win, event ) {

	var apName 		= navigator.appName.toLowerCase();
	var is_nav4 	= ((apName == "netscape") && (parseInt(navigator.appVersion) < 5))? 1:0;
	var is_ie4 		= ((apName == "msie") && (parseInt(navigator.appVersion) < 5))? 1:0;
	var is_dom 		= document.getElementById? 1:0;

	// IE5+ uses this event model to position content on a page
	if (is_dom && win.event) {
		leftVal = win.event.clientX + win.document.documentElement.scrollLeft + win.document.body.scrollLeft + 15;
		topVal 	= win.event.clientY + win.document.documentElement.scrollTop + win.document.body.scrollTop;
	}
	else
		// IE4 uses this event model. IE5 will, but
		// we are treating IE5 as dom compliant
		if (is_ie4) {
			topVal 	= eval(event.y + 2 + win.document.body.scrollTop);
			leftVal = eval(event.x - 125);
		} 
		else
			// NS 4.x uses this event model
			if (is_nav4) {
				topVal 	= eval(event.pageY + 2);
				leftVal = eval(event.pageX);
			} 
			else {
				// Navigator 6.x uses the dom event model
				leftVal = event.clientX + win.scrollX;
				topVal 	= event.clientY + win.scrollY;
			}
		
	if (leftVal < 2) 
		leftVal = 2;
		
	if ( bIsIE || win.document.getElementById ) {
		msgBox.style.left 	= ( leftVal ) + "px";
		msgBox.style.top 	= ( topVal ) + "px";
	}
	else if ( win.document.layers ) {
		msgBox.left = leftVal;
		msgBox.top 	= topVal; 
	}		
} */

//////////////////////
//	Mostra um Objeto MsgClass
//////////////////////
function showMsgBox( msg, win, style, event, notSubscribe )
{
	//1. Validação inicial
	if (msg == null){
		msg = new MsgClass ();
	}
	else if (typeof (msg) == "string") {
		msg = new MsgClass ( msg );
	}
	
	//2. Busca a Janela onde vai conter o MsgBox
	if ( win == null ) {
		win = window;
	}
	
	//Primeira execução
	if( !showMsgBox.OverlayManager ) {
		showMsgBox.OverlayManager = new YAHOO.widget.OverlayManager( );
	}
	
	//3. Verifica se já existe esse MsgBox nesta Janela
	var msgBox = showMsgBox.OverlayManager.find( msg.msgId );
	if ( msgBox ) {
		if( notSubscribe ) {
			return;
		}
		
		showMsgBox.OverlayManager.remove( msgBox );
		msgBox.destroy( );
	}
	
	//3.1. Cria o MsgBox
	msgBox = new YAHOO.widget.Overlay( msg.msgId, {
		constraintoviewport: true, 
	    visible:false,  
    	constraintoviewport:true,
		fixedcenter:true
	});
	showMsgBox.OverlayManager.register( msgBox );
	
	msgBox.setBody( msg.msgHtml );
	msgBox.render(document.body); 
	msgBox.bringToTop();
	
	var msgElem = msgBox.body;
	msgElem.style.fontFamily = "Trebuchet MS";
	msgElem.style.fontSize = "116%";
	msgElem.style.padding = "10px";
	msgElem.style.border = "3px solid white";
	
	YAHOO.util.Dom.addClass( document.body, "yui-skin-sam" ); 
	
	if ( style != null ) {
		msgElem.style = style ;
	}
	else {
		msgElem.style.backgroundColor 	= "red"; 
		msgElem.style.color 			= "white";
	}
	msgBox.show();
	
	//7. Coloca a mesma mensagem na Barra de Status do Browser
	if ( bIsIE )
		win.status = msgElem.innerText;
		
	else {
		var r = win.document.createRange() ;
		r.selectNodeContents ( msgElem ) ;
		win.status = r.toString();
	};
	
	return msgElem;
	
	/*msgBox = win.document.createElement ( 'div' );
	msgBox.style.visibility = "hidden";
	msgBox.style.position = "absolute";
	msgBox.style.zIndex = 100;
	msgBox.noWrap = true;
	win.document.body.appendChild ( msgBox );
	
	//4. Característica do MsgBox
	msgBox.innerHTML = msg.msgHtml;
	msgBox.id = msg.msgId;
	
	if ( style != null ) {
		msgBox.style = style ;
	}
	else {
		msgBox.style.padding 			= "5px";
		msgBox.style.fontFamily 		= "Arial";
		msgBox.style.fontSize 			= "12px";
		msgBox.style.backgroundColor 	= "red"; 
		msgBox.style.color 				= "white";
	}
	
	//6. Posicão
	msg.posFunc ( msgBox, win, event );
	msgBox.style.display = "";
	msgBox.style.visibility = "";
	
	return msgBox;
	*/
};

//////////////////////
//	Esconde um Objeto MsgClass
//////////////////////
function hideMsgBox ( msgId, win )
{
	if( !showMsgBox.OverlayManager ) { return; }

	//2. Identificação do MsgBox
	var msg = new MsgClass ( null, msgId );

	//
	var msgBox = showMsgBox.OverlayManager.find( msg.msgId );
	if ( msgBox ) {
		showMsgBox.OverlayManager.remove( msgBox );
		msgBox.destroy( );
	}
	
	//1. Busca a Janela onde vai conter o MsgBox
	if ( win == null ) {
		win = window;
	}
	
	win.status = "Concluído";	
	//3. Verifica se já existe esse MsgBox nesta Janela
	var msgBox = win.document.getElementById ( msg.msgId );
	
	//3.1. Cria o MsgBox
	if ( msgBox != null ) {
		msgBox.style.display = "none";
		win.document.body.removeChild ( msgBox ) ;
	}
};

function showMsgBoxSucesso ( arguments )
{
	var msgBox = showMsgBox( arguments );
	msgBox.style.backgroundColor = "#009900";
}

/////////////////
//	Adiciona um ToolTip a um elemento
/////////////////
function addToolTip ( elem, msg, msgId ) 
{
	elem.msg = msg;
	elem.msgId = msgId;
		
	addEventListenerFunc ( elem, 'onmouseover', toolTipOnMouseOver );
	addEventListenerFunc ( elem, 'onmouseout', toolTipOnMouseOut );
}

function toolTipOnMouseOut ( event ) {

	event = event ? event : window.event ;
	var elem = bIsIE ? event.srcElement: event.target;
	
	hideMsgBox ( elem.msgId, window );
}

function ttOut ( event ) {
	toolTipOnMouseOut ( event )
}

function toolTipOnMouseOver ( event, msg, msgId ) {
		
	event = event ? event : window.event ;
	var elem = bIsIE ? event.srcElement: event.target;
	
	if ( msg != null )
		elem.msg = msg;
	
	if ( msgId != null )
		elem.msgId = msgId;
	
	var toolTip 	= new MsgClass ( elem.msg, elem.msgId, posMsgBoxOnCursor );	
	var toolTipBox 	= showMsgBox( toolTip, window, null, event );
	var ttStyle = toolTipBox.style;
	
	ttStyle.color 			= "black";
	ttStyle.backgroundColor = "#ffffc6";
	//ttStyle.fontSize		= "10px";
	ttStyle.border			= "1px solid black";
	ttStyle.padding			= "2";
	ttStyle.filter	 		= "dropshadow(color=#cdcdcd, offX=-2, offY=2, positive=true)";
}

function ttOver ( event, msg, msgId ) {
	toolTipOnMouseOver ( event, msg, msgId ) 
}

///////////////////////
//	Vincula um Evento a um controle
///////////////////////
function addEventListenerFunc ( elem, eventType, funcHandler ) {
		
	if ( bIsIE )
		elem.attachEvent ( eventType, funcHandler ) ;
	else {
		eventType = new String ( eventType ) ;
		eventType = eventType.replace ( "on", "" ) ;
		elem.addEventListener ( eventType, funcHandler, false ) ;
	}
}

///////////////////////
//	Desvincula um Evento a um controle
///////////////////////
function removeEventListenerFunc ( elem, eventType, funcHandler ) {
		
	if ( bIsIE )
		elem.detachEvent ( eventType, funcHandler ) ;
	else {
		eventType = eventType.replace ( "on", "" ) ;
		elem.removeEventListener ( eventType, funcHandler, false ) ;
	}
}

/////////////////////////////////////////////
//	Funções para tratamento de Janelas tipo MODAL
/////////////////////////////////////////////
var winModal; 

function openModal (onCloseFunc)
{ 
	if ( arguments.length > 1 ) {
		if ( arguments[1].indexOf ( "?" ) == -1 ) 
			arguments[1] += "?";
		else
			arguments[1] += "&";
			
		arguments[1] += "onclose=" + onCloseFunc ; 
	}
	
	switch ( arguments.length ) {
		case 0:
			return;
			break;
		case 1:
			winModal = window.open();
			break;
		case 2:
			winModal = window.open( arguments[1] );
			break;
		case 3:
			winModal = window.open( arguments[1], arguments[2] );
			break;
		case 4:
			winModal = window.open( arguments[1], arguments[2], arguments[3] );
			break;
		default:
			winModal = window.open( arguments[1], arguments[2], arguments[3], arguments[4] );
			break;
	}
			
	winModal.onclose = onCloseFunc;
	
	var bodyElem = document.body;
	if ( bodyElem != null )	
	{
		var restoreFocusFunc = function ()
			{
				try 
				{
					if (winModal && winModal.open)
					{
						winModal.focus();
					}
				}
				catch (e) {}
				finally {}
			}	
	
		bodyElem.onfocus		= restoreFocusFunc;
		bodyElem.onclick		= restoreFocusFunc;
	}
}

function closeModal ( returnObj, sOnClose )
{
	if (window.opener != null)
	{
		window.opener.winModal = null;
		
		var bodyElem = window.opener.document.body;
		if ( bodyElem != null )
		{
			bodyElem.onfocus = null;
			bodyElem.onclick = null;
		}
		
		if ( sOnClose != "" && sOnClose != null ) { 
			var func = eval ( "window.opener." + sOnClose );
			if ( func ) { func( returnObj ); }
		}
	}
	
	close();
}

///////////////////////////
//	Reposiciona uma Janela Pop-Up
///////////////////////////
function centralizeWin ( win, offsetX, offsetY ) 
{
	var left 	= 10 ;
	var top 	= 10 ;

	if ( offsetX != null )
		top += offsetX;
		
	if ( offsetY != null )
		left += offsetY;
	
	try {
		win.moveTo ( left, top );
	}
	catch (e) {}
}

/////////////////////////
//	Funções para tratamento de Cookie
//////////////////////////
function SetCookie ( name, value ) 
{
   var argv	= arguments ;
   var argc	= arguments.length ;
   
   expires	=	(argc>2) ? argv[2] : new Date ( 2020, 01, 01 ) ;
   path		=	(argc>3) ? argv[3] : "/" ;
   domain	=	(argc>4) ? argv[4] : null ;
   secure	=	(argc>5) ? argv[5] : false ;
   
   document.cookie	=	name + "=" + escape(value) +
			((expires === null) ? "" : ("; expires=" + expires.toUTCString())) +
			((path === null) 	? "" : ("; path="+path)) +
			((domain === null) 	? "" : ("; domain="+domain)) +
			((secure === true) 	? "; secure" : "");
}

function GetCookie ( name ) 
{
   arg	= name + "=" ;
   alen	= arg.length;
   clen	= document.cookie.length;
   i	= 0;
   
   while ( i < clen ) 
   {
      j = i + alen;
	  
      if (document.cookie.substring( i, j ) == arg) 
	  {
          return GetCookieVal ( j );
      }
	  
      i = document.cookie.indexOf( " ", i ) + 1;
      if (i == 0) { break; }
   }
   
   return null;
}

function GetCookieVal ( offset ) {

   var endstr = document.cookie.indexOf( ";", offset );
   if (endstr == -1) { endstr = document.cookie.length; }
   
   return unescape ( document.cookie.substring ( offset, endstr ) );
}

function DelCookie ( name ) 
{
   expDate = new Date( 2000, 0, 0 );
   document.cookie = name + '=foobar; expires=' + expDate.toGMTString();
}

function IsNumeric(sText)
{
	var ValidChars = "0123456789.";
	var IsNumber=true;
	var Char;
	
	for (i = 0; i < sText.length && IsNumber == true; i++) { 
		Char = sText.charAt(i); 
		if (ValidChars.indexOf(Char) == -1) {
			IsNumber = false;
		}
	}
	return IsNumber;
}

function equal( objA, objB )
{
	if( objA == null || objB == null ) return ( objA == objB ) ;

	var isEqual  ;
	if ( isFunction ( objA ) )
		isEqual = ( objA == objB );
	else if ( isObject ( objA ) )
	{
		isEqual = true ;
		
		for( var i in objA )
		{ 
			isEqual = equal ( objA[i], objB[i] );
				
			if ( !isEqual ) 
				break ;
		}
	}
	else 
		isEqual = ( objA == objB );

	return isEqual;
}

function clone(myObj)
{
	if(typeof(myObj) != 'object') return myObj;
	if(myObj == null) return myObj;

	var myNewObj = new Object();

	for(var i in myObj)
	{
		if ( isArray( myObj[i] ) )
		{
			myNewObj[i] = new Array( myObj[i].length );
			for (var j in myObj[i])
			{
				myNewObj[i][j] = clone(myObj[i][j]);
			}
		}
		else
			myNewObj[i] = clone(myObj[i]);
	}

	return myNewObj;
}

function isAlien(a) {
   return isObject(a) && typeof a.constructor != 'function';
}

function isArray(a) {
    return isObject(a) && a.constructor == Array;
}

function isBoolean(a) {
    return typeof a == 'boolean';
}

function isEmpty(o) {
    var i, v;
    if (isObject(o)) {
        for (i in o) {
            v = o[i];
            if (isUndefined(v) && isFunction(v)) {
                return false;
            }
        }
    }
    return true;
}

function isFunction(a) {
    return typeof a == 'function';
}

function isNull(a) {
    return typeof a == 'object' && !a;
}

function isNumber(a) {
    return typeof a == 'number' && isFinite(a);
}

function isObject(a) {
    return (a && typeof a == 'object') || isFunction(a);
}

function isString(a) {
    return typeof a == 'string';
}

function isUndefined(a) {
    return typeof a == 'undefined';
} 

/* Open Popup */
function openPopUp ( url, width, height, options, modalOnCloseFunction )
{
	if( modalOnCloseFunction ) {
		url += ( url.indexOf ( "?" ) == -1 ? "?" : "&" ) + "onclose=" + modalOnCloseFunction;
	}

	var left = ( screen.width - width ) / 2 ;
	var top = ( screen.height - height ) / 2;
	
	if ( options == null ) options = "status=yes,scrollbars=yes,menubar=no,toolbar=no";
	
	var popUp = window.open( url, "", "width=" + width + ",height=" + height + ",left=" + left + ",top=" + top + "," + options );
	
	if ( !popUp ) {
		alert( "Oops! Parece que um bloqueador de pop-up's bloqueou a janela.\nDesabilite-o e tente novamente." ) ;
		return popUp;
	}
	
	//
	if( modalOnCloseFunction ) {
		popUp.onclose = modalOnCloseFunction;
		
		var bodyElem = document.body;
		if ( bodyElem ) {
			var restoreFocusFunc = function () {
					try {
						if (popUp && popUp.open) { popUp.focus(); }
					}
					catch (e) {}
					finally {}
				}	
		
			bodyElem.onfocus		= restoreFocusFunc;
			bodyElem.onclick		= restoreFocusFunc;
		}
	}
	
	return popUp;
}

function consisteCpfCgc (tipo, cpfCgc)
{
	var  i, tam, total, resto1, resto2
	var letra;
	
	// Ignora espaços, '-', '/', '\', '.',':,';' da string
	cpfCgc = cpfCgc.replace(/[ -\/\\.:;]/g, "")

	tipo = trim(tipo).toUpperCase();
	cpfCgc = trim(cpfCgc).toUpperCase();
	
	tam = cpfCgc.length;

	// Consiste o CPF
	if (tipo == 'CPF') { 
	
		// Deixa a variável com 11 posições
		if (tam > 11) { 
			return false;
		}	
		
		cpfCgc = ("00000000000" + cpfCgc).substring(tam);

		// Calcula o primeiro Dígito	
		total =	cpfCgc.substring(0, 1) * 10 + 
				cpfCgc.substring(1, 2) * 9 + 
	  			cpfCgc.substring(2, 3) * 8 + 
	  			cpfCgc.substring(3, 4) * 7 + 
	  			cpfCgc.substring(4, 5) * 6 + 
	  			cpfCgc.substring(5, 6) * 5 + 
	  			cpfCgc.substring(6, 7) * 4 + 
	  			cpfCgc.substring(7, 8) * 3 + 
	  			cpfCgc.substring(8, 9) * 2;			
				
		resto1 = total % 11;
		
		if ( resto1 > 1 ) {
			resto1 = 11 - resto1;
		}	
		else {
			resto1 = 0;
		}

		// Calcula o segundo Dígito	
		total = cpfCgc.substring(0, 1) * 11 + 
				cpfCgc.substring(1, 2) * 10 + 
	  			cpfCgc.substring(2, 3) * 9 + 
	  			cpfCgc.substring(3, 4) * 8 + 
	  			cpfCgc.substring(4, 5) * 7 + 
	  			cpfCgc.substring(5, 6) * 6 + 
	  			cpfCgc.substring(6, 7) * 5 + 
	  			cpfCgc.substring(7, 8) * 4 + 
	  			cpfCgc.substring(8, 9) * 3 + 				
	  			cpfCgc.substring(9, 10) * 2;	
				  
		resto2 = total % 11;

		if ( resto2 > 1 ) {
			resto2 = 11 - resto2;
		}
		else {
			resto2 = 0;
		}	
		
		if (cpfCgc.substring(9, 11) == "" + resto1 + resto2) {
			return true;
		}
		else {
			return false;
		}
	}
	// Consiste o CGC
	else if ( tipo == 'CGC') {
	
		// Deixa a variável com 14 posições
		if (tam > 14) {
			return false;
		}
	
		cpfCgc = ("00000000000000" + cpfCgc).substring(tam);
		
		// Calcula o primeiro Dígito
		total = cpfCgc.substring(0, 1) * 5 + 
				cpfCgc.substring(1, 2) * 4 + 
		  		cpfCgc.substring(2, 3) * 3 + 
		  		cpfCgc.substring(3, 4) * 2 + 
		  		cpfCgc.substring(4, 5) * 9 + 
		  		cpfCgc.substring(5, 6) * 8 + 
		  		cpfCgc.substring(6, 7) * 7 + 
		  		cpfCgc.substring(7, 8) * 6 + 
		  		cpfCgc.substring(8, 9) * 5 + 				
		  		cpfCgc.substring(9, 10) * 4 +
		  		cpfCgc.substring(10, 11) * 3 +
		  		cpfCgc.substring(11, 12) * 2;
		  
		resto1 = total % 11;
		
		if (resto1 > 1) {
			resto1 = 11 - resto1;
		}	
		else {
			resto1 = 0;
		}
	
		// Calcula o Segundo Dígito	
		total = cpfCgc.substring(0, 1) * 6 + 
				cpfCgc.substring(1, 2) * 5 + 
		  		cpfCgc.substring(2, 3) * 4 + 
		  		cpfCgc.substring(3, 4) * 3 + 
		  		cpfCgc.substring(4, 5) * 2 + 
		  		cpfCgc.substring(5, 6) * 9 + 
		  		cpfCgc.substring(6, 7) * 8 + 
		  		cpfCgc.substring(7, 8) * 7 + 
		  		cpfCgc.substring(8, 9) * 6 + 				
		  		cpfCgc.substring(9, 10) * 5 +
		  		cpfCgc.substring(10, 11) * 4 +
		  		cpfCgc.substring(11, 12) * 3 +
		  		cpfCgc.substring(12, 13) * 2;
	
		resto2 = total % 11;
		
		if (resto2 > 1) {
			resto2 = 11 - resto2;
		}	
		else {
			resto2 = 0;
		}
	
		// Verifica os dígitos
		if (cpfCgc.substring(12, 14) == "" + resto1 + resto2) {
			return true;
		}	
		else {
			return false;
		}	
	}	
	else {
		// Não verificou
		return false;
	}
}


/**
Class ImagePreloader
Carrega imagens em back-ground

Paramatros:
	- images, Array com o URL das imagens que se deseja carregar
	- callBack, Função que será invocada quando todas as imagens tiverem sido processadas. 
		- Os parâmetros de callBack são:
			- aImages, Array de objetos Image
				Três atributos foram adicionados no objeto Image para validação
					- bLoaded, indica se a imagem foi carregada
					- bError, indica se houve erro no carregamento da imagem
					- bAbort, indica se o carregamento da imagem foi abortado
			- nLoaded, Número de imagens carregadas
*/
function ImagePreloader(images, callBack)
{
	// store the callBack
	this.callBack = callBack;
	
	// initialize internal state.
	this.nLoaded = 0;
	this.nProcessed = 0;
	this.aImages = new Array;
	
	// record the number of images.
	this.nImages = images.length;
	
	// for each image, call preload()
	for ( var i = 0; i < images.length; i++ )
		this.preload(images[i]);
}

ImagePreloader.prototype.preload = function(image)
{
	// create new Image object and add to array
	var oImage = new Image;
	this.aImages.push(oImage);
	
	// set up event handlers for the Image object
	oImage.onload = ImagePreloader.prototype.onload;
	oImage.onerror = ImagePreloader.prototype.onerror;
	oImage.onabort = ImagePreloader.prototype.onabort;
	
	// assign pointer back to this.
	oImage.oImagePreloader = this;
	oImage.bLoaded = false;
	
	// assign the .src property of the Image object
	oImage.src = image;
}

ImagePreloader.prototype.onComplete = function()
{
   this.nProcessed++;
   if ( this.nProcessed == this.nImages )
   {
      this.callBack(this.aImages, this.nLoaded);
   }
}

ImagePreloader.prototype.onload = function()
{
   this.bLoaded = true;
   this.oImagePreloader.nLoaded++;
   this.oImagePreloader.onComplete();
}

ImagePreloader.prototype.onerror = function()
{
   this.bError = true;
   this.oImagePreloader.onComplete();
}

ImagePreloader.prototype.onabort = function()
{
   this.bAbort = true;
   this.oImagePreloader.onComplete();
}

/*
Mesma função de eval() porém executa o script no escopo global.
Obs.: Apesar da execução ser síncrona, não é possível obter o retorno do código executado.
Portanto, caso seja necessário obter o retorno de código, use eval().
*/
function evalGlobal( code ) {
	if (!code) return;
	if (window.execScript) window.execScript(code);
	else if (navigator.userAgent.indexOf('Safari')!=-1) window.setTimeout(code,0);
	else window.eval(code);
}

/* Adiciona o recurso de resize no layout */
(function(){ 

	var Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event,
		menu = null,
		main = null;
	
	Event.addListener(window, "load", function() {
		
		//
		var doc = Dom.get('doc3');
		if( !doc ) { return; }
		Dom.addClass( doc, "yui-skin-sam" );
		
		//
		hideMsgBox();
		
		//
		var size = Dom.get('bd').offsetWidth;
		menu = Dom.get('bd-menu');
		main = Dom.get('bd-main');
		
		return;
		if ( !menu ) { return; }
		
		Dom.setStyle( menu, 'min-height', menu.offsetHeight + 'px' );
		Dom.setStyle( menu, 'height', menu.offsetHeight + 'px' );
		
		var resize = new YAHOO.util.Resize('bd-menu', {
			handles: ['r'],
			minWidth: 15,
			maxWidth: 135
		});
		
		resize.on('resize', function(ev, h , w) {
			var mainOffsetH = main.offsetHeight;
			var menuMinH = Dom.getStyle( menu, 'min-height' ).replace( 'px', '' ) - 0;
			Dom.setStyle( menu, 'height', ( mainOffsetH < menuMinH ? menuMinH : mainOffsetH ) + 'px' );
			Dom.setStyle( main, 'margin-left', ( ev.width + 5 ) + "px" );
			YAHOO.util.Cookie.set( "menuwidth", ev.width, { path: "/" });
		});
		
		var menuWidth;

		try { menuWidth = YAHOO.util.Cookie.get("menuwidth"); } catch(exp_error){};
		
		if( !menuWidth ) { menuWidth = 135; }
		setTimeout( function() { resize.resize( null, 0, menuWidth, 0, 0, true ); }, 0 );
	});
	
	Event.addListener(window, "unload", function(){showMsgBox();});
})();


YAHOO.Smartweb.util.nl2br = function (text){
	if( !text ) return null;
	text = escape( text );
	return unescape(text.replace(/(%0A%0D)|(%0D%0A)|%0D|%0A/g,"<br />"));
}

YAHOO.Smartweb.util.br2nl = function (text) {
	return text.replace (/\<br ?\/?\>/g, "\n");
}

/**
* Adiciona um calendário a um input 
*
* @param input
* @param opt {object} Opçoes
* @param opt.format {string} Formato da data
* @param opt.title {string} Título do calendário
*/
YAHOO.Smartweb.util.addCalendar = function( input, opt )
{ 
	var dom = YAHOO.util.Dom,
		event = YAHOO.util.Event,
		currDate = DW_DateParse( input.value ),
		config, 
		calendar;
	
	if( !opt ) { opt = new Object(); } 
	if( !opt.format ) { opt.format = "dd/mm/yyyy"; }
	if( !opt.title ) { opt.title = ""; }
	opt.title = opt.title.replace( " ", "&nbsp;" );
	
	//Cria o container para o calendário
	callContainerContainer = document.createElement( "div" );
	callContainerContainer.style.position = "relative";
	callContainerContainer.style.display = "inline";
	callContainerContainer.style.left = "2px";
	callContainerContainer.style.top = "1px";
	callContainerContainer.style.zIndex = 99;
		
	callContainer = document.createElement( "div" );
	callContainer.style.display = "none";
	callContainer.style.position = "absolute";
	callContainerContainer.appendChild( callContainer );
	
	//callContainer.style.top = ( dom.getY( input ) + input.offsetHeight ) + "px";
	//callContainer.style.left = ( dom.getX( input ) - 2 ) + "px";

	dom.insertAfter( callContainerContainer, input );

	//Cria o calendário
	config = { locale_weekdays: "1char", close: true };
	
	if( currDate ) {
		input.dateValue = currDate;
		input.value = DW_FormatDate( opt.format, currDate );
		
		config.pagedate = DW_FormatDate( "mm/yyyy", currDate );
		config.selected = DW_FormatDate( "m/d/yyyy", currDate );
	}
	
	calendar = new YAHOO.widget.Calendar( callContainer, config );
	
	calendar.cfg.setProperty("MONTHS_LONG", DW_longMonthNames );
	calendar.cfg.setProperty("WEEKDAYS_1CHAR", ["D", "S", "T", "Q", "Q", "S", "S"]);
	calendar.cfg.setProperty("title", opt.title );
	calendar.render();
	
	//
	event.addListener( input, "click", function( ev ) { 
		var currentInputCalendar = YAHOO.Smartweb.util.currentInputCalendar;
		if( currentInputCalendar ) {
			currentInputCalendar.hide();
		} 
		YAHOO.Smartweb.util.currentInputCalendar = calendar;
		calendar.show(); 
	} );
	input.readOnly = true;

	calendar.selectEvent.subscribe( function( type, args, obj ) {
		var date = args[0][0];
		input.dateValue = new DW_DateClass( date[0] - 1900, date[1] - 1, date[2] );
		input.value = DW_FormatDate( opt.format, input.dateValue );
		this.hide();
		YAHOO.Smartweb.util.currentInputCalendar = null;
	}, calendar, true);
}

/**
* Extrai o conteúdo das tags <style> de um código HTML
*/
YAHOO.Smartweb.util.extractStyles = function( html )
{
	// find all styles in the string
	var styleFragRegex = '<style[^>]*>([\u0001-\uFFFF]*?)</style>',
		matchAll = new RegExp(styleFragRegex, 'img'),
		matchOne = new RegExp(styleFragRegex, 'im'),
		styles = (html.match(matchAll) || []), idx;
	
	for( idx = 0; idx < styles.length; idx++ )
		styles[idx] = (styles[idx].match(matchOne) || ['', ''])[1];

	return { 	style: styles.join( "\n" ), 
				html: html.replace(matchAll, ""), 
				toString: function(){ return this.styles } };
}

/**
* Aplica na página regras CSS
*/
YAHOO.Smartweb.util.applyStyles = function( style )
{
	var node,
		dom = YAHOO.util.Dom,
		head = document.getElementsByTagName('head')[0];
		
	if (!head) throw new Error("HEAD element not found to append STYLE node");
		
	node = document.createElement('style');
	node.type = 'text/css';
	dom.generateId( node );
	
	if (node.styleSheet) {
		node.styleSheet.cssText = style;
	} else {
		node.appendChild( document.createTextNode( style ) );
	}
	
	head.appendChild( node );
	return node;
}

/**
*/
YAHOO.Smartweb.util.disabledStyle = function( style )
{
	if( !style ) return;
	if( YAHOO.lang.isString( style ) ) style = YAHOO.util.Dom.get( style );	
	if( !style ) return;
	
	( style.sheet || style.styleSheet ).disabled = true;
}

/**
* Verifica se o elemento está visíbel na tela
* 
* @param element 
* @param partial {Booelan} Apenas parcialmente? se true, caso o elemento esteja parcialmente visível
* 							na tela, a função retorna true. se false, a função somente retornará true caso o 
* 							elemento esteja completamente visível na tela. default é true
*/
YAHOO.Smartweb.util.isInViewport = function( element, partial ) 
{
	if( partial == null ) { partial = true; }
	
	var dom = YAHOO.util.Dom,
		element = dom.get(element),
		scrollTop = (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop),
		viewportHeight = dom.getViewportHeight(),
		elementPosYTop = dom.getY(element),
		elementPosYBottom = elementPosYTop + element.offsetHeight;
	
	var visibilityTop = elementPosYTop >= scrollTop && elementPosYTop < ( scrollTop + viewportHeight ),
		visibilityBottom = elementPosYBottom >= scrollTop && elementPosYBottom < ( scrollTop + viewportHeight );
	
	if( partial ) {
		return ( visibilityTop || visibilityBottom );
	}
	else {
		return ( visibilityTop && visibilityBottom );
	}
}

/*
* Objeto usado para criar o efeito de scroll suave da tela, para usar a funcionalidade
* deste objeto, veja a função YAHOO.Smartweb.util.scrollTo
*/
YAHOO.Smartweb.util.Scroller = {
	
	// control the speed of the scroller.
	// dont change it here directly, please use Scroller.speed=50;
	speed: 10,
	inited: false,
	dom: YAHOO.util.Dom,	

	// returns the Y position of the div
	gy: function (el) {
		var viewH = this.dom.getViewportHeight(),
			docH = this.dom.getDocumentHeight(),
			elY = this.dom.getY(el);
		
		return ( elY + viewH > docH ? docH - viewH : elY );
	},

	//move the scroll bar to the particular position.
	scroll: function( d ) 
	{	
		var a = this.dom.getDocumentScrollTop(),
			diff = d - a;
		
		a += diff / ( Math.abs( diff ) < this.speed ? Math.abs( diff ) : this.speed );
			
		window.scrollTo( 0, a );
		
	  	if( a === d ) { clearInterval( this.interval ); }
	},

	// initializer that adds the renderer to the onload function of the window
	init: function() {
		YAHOO.util.Event.on( document, 'mousewheel', this.stop );
	},

	//
	scrollTo: function(element) {
		this.stop();
		this.interval = setInterval( 'YAHOO.Smartweb.util.Scroller.scroll(' + this.gy(element) + ')', 10 );
	},
	
	//
	stop: function() { 
		clearInterval( this.interval ); 
	}
}

YAHOO.Smartweb.util.removeImgOnError = function( imgId )
{
	var img = YAHOO.util.Dom.get( imgId ),
		parent = img.parentNode,
		span = document.createElement( "span" );
	
	span.innerHTML = img.alt;
	parent.insertBefore( span, img );
	parent.removeChild( img );
}

/*
* Faz um scroll suave da tela até o elemento
*/
YAHOO.Smartweb.util.scrollTo = function( el )
{
	if( !this.Scroller.inited ) { this.Scroller.init(); }
	this.Scroller.scrollTo( YAHOO.util.Dom.get( el ) );
}

// proper case string prptotype
String.prototype.toProperCase = function()
{
  return this.toLowerCase().replace(/^(.)|\s(.)/g, 
      function($1) { return $1.toUpperCase(); });
}
//**************************************************************************
//		Copyright  Sybase, Inc. 1998-1999
//						 All Rights reserved.
//
//	Sybase, Inc. ("Sybase") claims copyright in this
//	program and documentation as an unpublished work, versions of
//	which were first licensed on the date indicated in the foregoing
//	notice.  Claim of copyright does not imply waiver of Sybase's
//	other rights.
//
//	 This code is generated by the PowerBuilder HTML DataWindow generator.
//	 It is provided subjtect to the terms of the Sybase License Agreement
//	 for use as is, without alteration or modification.  
//	 Sybase shall have no obligation to provide support or error correction 
//	 services with respect to any altered or modified versions of this code.  
//
//       ***********************************************************
//       **     DO NOT MODIFY OR ALTER THIS CODE IN ANY WAY       **
//       ***********************************************************
//
//       ***************************************************************
//       ** IMPLEMENTATION DETAILS SUBJECT TO CHANGE WITHOUT NOTICE.  **
//       **            DO NOT RELY ON IMPLEMENTATION!!!!		      **
//       ***************************************************************
//
// Use the public interface only.
//**************************************************************************

// these arrays will be filled with internationalized strings based on the server
var DW_shortDayNames = new Array("Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab");
var DW_longDayNames = new Array("Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado");
var DW_shortMonthNames = new Array("Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez");
var DW_longMonthNames = new Array("Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro");

// this is dependent on the control panel setting on the server
// it indicates the order of days (this is mm/dd/yyyy)
var DW_PARSEDT_monseq = 1;
var DW_PARSEDT_dayseq = 0;
var DW_PARSEDT_yearseq = 2;

// DWItemStatus
var DW_ITEMSTATUS_NOCHANGE = 0;
var DW_ITEMSTATUS_MODIFIED = 1;
var DW_ITEMSTATUS_NEW = 2;
var DW_ITEMSTATUS_NEW_MODIFIED = 3;

// Added to determine if dates are being processed in client side JavaScript.
var bDateTimeProcessingEnabled = true;

var gMask = "";

// common utility functions

function escapeString( inString )
{
    var index;
    var outString = "";
    var tempChar;

    // force to string type or charAt will fail!
    if (typeof inString != "string")
    	inString = inString.toString();

    var strLength = inString.length;
    for ( index=0; index < strLength; index++ )
        {
        tempChar = inString.charAt( index );
        if (tempChar == "\"" || tempChar == "'") 
            outString += "~" + tempChar;
        else if (tempChar == "\r")
            outString += "~r";
        else if (tempChar == "\n")
            outString += "~n";
        else
            outString += tempChar;
        }
    return outString;
}

function convertToRGB( color )
{
	var hexValue = "000000" + eval( color ).toString(16);
	hexValue = hexValue.substr( hexValue.length - 6, 6 );
	hexValue = hexValue.substr( 4, 2 ) + hexValue.substr( 2, 2 ) + hexValue.substr( 0, 2 );
	return hexValue;
}

// default event returns to 0
function _evtDefault (value)
{
    if (value + "" == "undefined")
        return 0;
    return value;
}

// need to double up because of template expander!
function DW_parseIsSpace(theChar)
{
    return /^\s$/.test(theChar);
}

function DW_parseIsDigit(theChar)
{
    return /^\d$/.test(theChar);
}

function DW_parseIsAlpha(theChar)
{
    return /^\w$/.test(theChar) && ! /^\d$/.test(theChar);
}

// auto binding of events expect <controlName>_<eventName>
function HTDW_eventImplemented(sEventName)
{
    // check if we already have one scripted
    if (this[sEventName] == null)
        {
        // check for function with default name
        var testName = this.name + '_' + sEventName;
        if (eval ('typeof ' + testName) == 'function')
            this[sEventName] = eval(testName);
        }

    return this[sEventName] != null;
}

// utility functions
function allowInString (inString, refString)
{
    var index, tempChar;
    var strLength = inString.length;
    for (index=0; index < strLength; index++)
        {
        tempChar= inString.charAt (index);
        if (refString.indexOf (tempChar)==-1)  
            return false;
        }
    return true;
}

function DW_Trim(inString)
{
    var indexStart, indexEnd, tempChar, outString;
    var strLength = inString.length;
    // skip leading blanks
    for (indexStart=0; indexStart < strLength; indexStart++)
        {
        tempChar= inString.charAt (indexStart);
        if (tempChar != " ")
            break;
        }
    if (indexStart != strLength)
        {
        // skip trailing blanks
        for (indexEnd=strLength-1; indexEnd > 0; indexEnd--)
            {
            tempChar= inString.charAt (indexEnd);
            if (tempChar != " ")
                break;
            }
        // get all chars in between
        outString = inString.substring(indexStart, indexEnd+1);
        }
    else
        outString = "";
    return outString;
}

function DW_Round(num, decPlaces)
{
	var powTen = Math.pow(10.0,decPlaces);
	num *= powTen;
	if (num >= 0)
	    num = Math.floor(num + 0.5);
	else
	    num = Math.ceil(num - 0.5);

    return num / powTen;
}

function DW_IsNonNegativeNumber(inString, bNilIsNull)
{
	if (arguments.length < 2)
			bNilIsNull = false;
		if (inString == "")
			return bNilIsNull;
		else
		{
			var newString = DW_Trim(inString);		
			if (newString == "")								
				return false; 										
			else														
			{														
				var result = new DW_NumberClass();	
				if(DW_parseNumberStringAgainstMask(inString, result, false)) 	
				{													
					if (result >= 0) 							
						return true; 								
				}													
				
				return false; 									
			}														
		}
}

function DW_IsValidDisplayOrDataValue(inString, bNilIsNull)
{
    if (arguments.length < 2)
        bNilIsNull = false;
    if (inString == "")
        return bNilIsNull;
    else
        {
        var i;
        for(i = 0; i < this.displayValue.length; i++)
            {
            if (inString == this.displayValue[i])
                return true;		    
            if (inString == this.dataValue[i])
                return true;		    
            }
        return false;
        }
}

function DW_IsNumber(inString, bNilIsNull)
{
	if (arguments.length < 2)
			bNilIsNull = false;
		if (inString == "")
			return bNilIsNull;
		else
		{
			var newString = DW_Trim(inString);		
			if (newString == "")		
				return false;		
			else			
				return DW_parseNumberStringAgainstMask(inString, null, true); 
		}
}

// exprContext class
function HTDW_exprContextClass(dataWindow)
{
    this.dw = dataWindow;
    this.row = -1;
    this.currentText = "";
}

// Col0 class
function HTDW_Col0Class(rowId, dwItemStatus)
{
    this.colModified = new Array();
    this.rowId = rowId;
    this.itemStatus = dwItemStatus;
}

// Row class
function HTDW_RowClass(rowId)
{
    var col;

    // column 0 holds special data
    this[0] = new HTDW_Col0Class(rowId, arguments[1]);
    
    // get data values
    for (col = 1; col < arguments.length - 1; col++)
        {
        this[0].colModified[col] = false;
        this[col] = arguments[col + 1];
        }

    this.numCols = arguments.length - 1;
}

function HTDW_Row_generateChange (rowNum, rowObj)
{
    var col;
    var result;

    if (rowObj[0].itemStatus == DW_ITEMSTATUS_MODIFIED ||
        rowObj[0].itemStatus == DW_ITEMSTATUS_NEW_MODIFIED)
        {
        result = "(ModifyRow " + rowNum + " " + rowObj[0].rowId + " (";
        for (col = 1; col < rowObj.numCols; col++)
            {
            if (rowObj[0].colModified[col])
                {
                if (rowObj[col] == null)
                    result += "(" + col + " 1)";
                else
                    result += "(" + col + " 0 '" + escapeString(rowObj[col]) + "')";
                }
            }
        result += "))";
        }
    else
        result = "";

    return result;
}

function HTDW_Row_dumpRow (rowNum, rowObj)
{
    var col;
    var result;

    result = "Row " + rowNum + "\n" + 
             "Modified:" + rowObj[0].itemStatus + "\n" +
             "RowId:" + rowObj[0].rowId + "\n" + 
             "NumCols:" + (rowObj.numCols - 1) + "\n";
             
    for (col = 1; col < rowObj.numCols; col++)
        {
        result += "   Col " + col + " modified:" + rowObj[0].colModified[col] + " '" + rowObj[col] + "'\n";
        }

    // alert (result);
    
    return result;
}

// set up class functions
HTDW_RowClass.generateChange = HTDW_Row_generateChange;
HTDW_RowClass.dumpRow = HTDW_Row_dumpRow;

function HTDW_ColumnGob(name, colNum, rowInDetail, region, bRequired, bNilIsNull, bFocusRect, formatFunc, getDisplayFormatFunc, getEditFormatFunc, column)
{
	this.isDateTime = ( formatFunc == DW_FormatDate );
    this.name = name;
    this.colNum = colNum;
    this.rowInDetail = rowInDetail;
    this.region = region;
    this.bRequired = bRequired;
    this.bNilIsNull = ( bNilIsNull || this.isDateTime );
    this.bFocusRect = bFocusRect;
	this.bUseCodeTable = false;

    this.getDisplayFormat = getDisplayFormatFunc;
    this.getEditFormat = getEditFormatFunc;
    this.format = formatFunc;
    this.column = column;
	
}

function HTDW_ComputeGob(name, region, computeFunc, formatFunc, getDisplayFormatFunc)
{
    this.name = name;
    this.region = region;

    this.compute = computeFunc;
    this.getDisplayFormat = getDisplayFormatFunc;
    this.format = formatFunc;
}

// Depend classes common function
// DependCompute class
function HTDW_DependComputeUpdate(htmlDw, row, bSkipCurrent)
{
    var gob = this.gob;
    var control = htmlDw.findControl(gob.name, row, gob.region == 0);

    if (control != null && typeof gob.compute == "function")
        {
        // body
        if (gob.region == 0)
            row = row;
        // header
        else if (gob.region == 1)
            row = htmlDw.firstRow;
        // footer or summary
        else if (gob.region == 2 || gob.region == 3)
            row = htmlDw.lastRow;

        var exprCtx = htmlDw.exprCtx;
        exprCtx.row = row;
        exprCtx.currentText = "";

        var value = gob.compute(exprCtx);

        if (control.type == "hidden" || control.type == "password" || 
            control.type == "text" || control.type == "textarea")
            {
            var displayValue;
            if (gob.format != null && gob.getDisplayFormat != null)
                {
                var formatString;
                if (typeof gob.getDisplayFormat == "string")
                    formatString = gob.getDisplayFormat;
                else
                    formatString = gob.getDisplayFormat (exprCtx);
                displayValue = gob.format (formatString, value, control);
                }
            else if (value != null)
				{
                displayValue = value.toString();
				
				//Acréscimo para correção do Bug da Vírgula!
				//AUTOR: Daniel Gomes Silveira
				if (gob.format == DW_FormatNumber)
						displayValue = displayValue.replace ( ".", DW_decimalChar );				
				}
            else
                displayValue = "";
            control.value = displayValue;
            }
        }
}

function HTDW_DependCompute(gob)
{
    this.gob = gob;
    
    this.update = HTDW_DependComputeUpdate;
}

// DependColumn class
function HTDW_DependColumnUpdate(htmlDw, row, bSkipCurrent)
{
    var gob = this.gob;
    var control = htmlDw.findControl(gob.name, row, gob.region == 0);

    // don't mess with the current control if asked not to
    if (control != null && 
            ! (bSkipCurrent && control == htmlDw.currentControl))
        {
        // body
        if (gob.region == 0)
            row = row + gob.rowInDetail;
        // header
        else if (gob.region == 1)
            row = htmlDw.firstRow;
        // footer or summary
        else if (gob.region == 2 || gob.region == 3)
            row = htmlDw.lastRow;

        var value = htmlDw.rows[row][gob.colNum];
		
        if (control.type == "hidden" || control.type == "password" || 
            control.type == "text" || control.type == "textarea" ||
            control.type == "select-one")
            {
            var displayValue;
            if (gob.format != null && gob.getDisplayFormat != null)
                {
                var exprCtx = htmlDw.exprCtx;
                exprCtx.row = row;
                exprCtx.currentText = "";
                if (typeof gob.getDisplayFormat == "string")
                    formatString = gob.getDisplayFormat;
                else
                    formatString = gob.getDisplayFormat (exprCtx);
                displayValue = gob.format (formatString, value, control);
                }
            else if (value != null)
				{
                displayValue = value.toString();
				
				//Acréscimo para correção do Bug da Vírgula!
				//AUTOR: Daniel Gomes Silveira
				if (gob.format == DW_FormatNumber)
						displayValue = displayValue.replace ( ".", DW_decimalChar );							
				}
            else
                displayValue = "";
				
			if (control.type == "select-one") {
				var bExists = false;
			
				for ( var i = 0; i < control.options.length; i++ ) {
					if ( control.options[i].value == displayValue ) {
						bExists = true;
						break;
					}
				}
				
				if ( !bExists )
					control.options[control.options.length] = new Option( displayValue, displayValue );
			}	
				
            control.value = displayValue.replace(new RegExp("~~","g"), "~");
            }
       else if(control.type == "checkbox")
         {
		 if (value != null)
             {  
				var displayValue;
				displayValue = value.toString();
				if ( (control.checked==true) &&  (displayValue!=control.value.toString()))
						control.checked=false;
				else if  ((control.checked==false) && (displayValue!=control.value.toString()))
						control.checked=true;

				control.value = displayValue;		
		     }	
         }

      else if(control.length>1)
     		if(control[0].type="radio")		
		        {	
				var r;
				for (r=0;r<control.length;r++)
				{
					 displayValue = value.toString();
         				 if(control[r].value==displayValue)
         			 	{
         					control[r].checked=true;
						}
					 
				 }
			
			}
         
            
       }
}

function HTDW_DependColumn(gob)
{
    this.gob = gob;

    this.update = HTDW_DependColumnUpdate;
}

// Column class
function HTDW_Column_addDepend(depend)
{
    if (this.dependents == null)
        this.dependents = new Array();

    this.dependents[this.dependents.length] = depend;
}

function HTDW_Column_updateDependents(htmlDw, row, bSkipCurrent)
{
    if (this.dependents != null)
        {
        for (var i=0; i < this.dependents.length; ++i)
            this.dependents[i].update (htmlDw, row, bSkipCurrent);
        }
}

function HTDW_ColumnClass(colId, name, convertFromStringFunc, typeValidationFunc, itemValidateFunc, validationMessageFunc, computeFunc, displayGobName)
{
    this.colId = colId;
    this.name = name;
    this.dependents = null;
    
    this.convertFromString = convertFromStringFunc;
    this.validateByType = typeValidationFunc;
    this.validateItem = itemValidateFunc;
    this.validationError = validationMessageFunc;
    this.compute = computeFunc;
    this.displayGobName = displayGobName;
    
    // interface functions
    this.addDepend = HTDW_Column_addDepend;
    this.updateDependents = HTDW_Column_updateDependents;

    this.displayValue = new Array();
    this.dataValue = new Array()
}

// DataWindow class
function HTDW_findControl(gobName, row, bInBody)
{
    var control = null;
    var controlExists;
    var controlName = gobName;
    var controlObject;

    if (bInBody)
        controlName += "_" + row;

    if (this.dataForm + "" != "undefined")
        {
        controlObject = 'this.dataForm.' + controlName;
        controlExists = eval('typeof ' + controlObject);
        if (controlExists == "object")
            control = eval(controlObject);
        }
    else if (this.navLayerForms[0] + "" != "undefined") // try array of Netscape layered forms
        {
        var rowObj = this.rows[row];
        var index = 0;
        if (bInBody)
            index = row * (rowObj.numCols - 1); // skip over for search
        for( ; index < this.navLayerForms.length; index++)
             {
             if (this.navLayerForms[index].elements[0].name == controlName)
                 {
                 control = this.navLayerForms[index].elements[0];
                 break;
                 }
             }
        }
    else
        control = null;
        
    return control;
}

function HTDW_itemGainFocus(newRow,newCol,control,gob)
{
	this.debug ( 'itemGainFocus(' + newRow + ',' + newCol + ',' + control.name + ',' + gob.name + ')', DEBUG_ENTER );

    var bRowChanged = false;
	var bReadOnlyControl = false;
	var bNegativeTabIndexControl = false;
	
    // default arguments
    control.row = newRow;
    control.col = newCol;
    control.gob = gob;
	
    // if in the middle of trying to force focus back
    // to a control, ignore all other focus stuff
	if (this.forcingBackFocusTo != null)
	    {
	    // check if we have made it back yet
	    if (this.forcingBackFocusTo == control)
	    {
    		this.forcingBackFocusTo = null;
    		this.currentControl = control;
	    }
    	// don't do any other focus related stuff
		this.debug ( 'itemGainFocus() (1)', DEBUG_EXIT );
    	return;
    	}

    // bail if we think that the current control already has focus
    // (Could happen if a button is pressed)
    if (this.currentControl == control &&
		!(this.currentControl.type == "hidden" || this.currentControl.type == "password" ||
		this.currentControl.type == "text" || this.currentControl.type == "textarea")) {
		
		this.debug ( 'itemGainFocus() (2)', DEBUG_EXIT );
        return;
	}
    
	// check control attri
	if (control.readOnly + "" != "undefined")
		{
		bReadOnlyControl = control.readOnly;
		}
	if (control.tabIndex + "" != "undefined")
		{
		if(control.tabIndex < 0 )
			bNegativeTabIndexControl = true;
		}

	if (bNegativeTabIndexControl)
		{
		control.blur(); //don't allow focus.
		this.debug ( 'itemGainFocus() (3)', DEBUG_EXIT );
		return;
		}

    if (newRow != -1)
        {
        if (newRow != this.currRow)
            {
            bRowChanged = true;

            // row focus changing event
            if (this.eventImplemented("RowFocusChanging"))
                {
                var result = _evtDefault(this.RowFocusChanging (this.currRow+1, newRow+1));
                // if 1 returned, don't allow focus to change (leave focus in last control to have gained focus
                if (result == 1)
                    {
                    this.restoreFocus();
                    // bail out early
					this.debug ( 'itemGainFocus() (4)', DEBUG_EXIT );
                    return;
                    }
                }
			
            }
            
        this.currRow = newRow;
        }
    if (newCol != -1)
        this.currCol = newCol;

    this.currentControl = control;

    // update the displayed value to be in editible form
    if (newRow != -1 && newCol != -1 && 
	    (this.currentControl.type == "hidden" || this.currentControl.type == "password" ||
		 this.currentControl.type == "text" ||this.currentControl.type == "textarea"))
        {
        var value = this.rows[newRow][newCol];
        if (gob.format != null)
            {
            var displayValue;

            if (gob.getEditFormat != null)
                {
                var formatString;
                if (typeof gob.getEditFormat == "string")
                    formatString = gob.getEditFormat;
                else
                    {
                    var exprCtx = this.exprCtx;
                    exprCtx.row = control.row;
                    exprCtx.currentText = "";
                    formatString = gob.getEditFormat (exprCtx);
					debug ( 'exprCtx changed ( ' + exprCtx.row + ', ' + exprCtx.currentText + ')' );
                    }
					
                displayValue = gob.format (formatString, value, this.currentControl, true);
                }
            else if (value != null)
				{
	                displayValue = value.toString();
					
					//Acréscimo para correção do Bug da Vírgula!
					//AUTOR: Daniel Gomes Silveira
					if (gob.format == DW_FormatNumber)
							displayValue = displayValue.replace ( ".", DW_decimalChar );
				}
            else
                displayValue = "";
				
            this.currentControl.value = displayValue.replace(new RegExp("~~","g"), "~");
			
			if (this.currentControl.type == "text")
				this.scrollToStartControlContent ( this.currentControl );
            }
        else if ( value != null )
            {
            // Do not compare against Date/Time if no date fields have been defined
            if (!bDateTimeProcessingEnabled ||
               (value.toString != DW_DatetimeToString &&
                value.toString != DW_DateToString &&
                value.toString != DW_TimeToString))
                this.currentControl.value = value.toString( ).replace(new RegExp("~~","g"), "~");
            }
        else
            this.currentControl.value = "";
        }
    
	if ( gob.isDateTime )
		{
		control.onkeypress = DW_dateTimeEditMaskKeyPress;
		control.onkeydown = DW_dateTimeEditMaskKeyDown;		
		}
	
    // can only programatically change border on IE4
    //if (control.gob.bFocusRect && HTDW_DataWindowClass.isIE4)
	//if (HTDW_DataWindowClass.isIE4)
     //   {
	this.currentControlBackColor  = control.style.backgroundColor;
	
	if ( control.type != "select-one" ) {
		if ( this.bMarkRequired && control.gob.bRequired )
			control.style.backgroundColor = "#FFBBBB";
		else
			control.style.backgroundColor = "#E8F1D9";
	}
	
	//Imprime na barra de Status o nome do controle com focu
	self.status = gob.name;
	
    // row focus changed event
    if (bRowChanged && this.eventImplemented("RowFocusChanged"))
        this.RowFocusChanged (newRow+1)
        
    // item focus changed event
    if (newCol != -1 && this.eventImplemented("ItemFocusChanged"))
        this.ItemFocusChanged (newRow+1, this.cols[newCol].name)
	
	this.debug ( 'itemGainFocus() (5)', DEBUG_EXIT );
}

function HTDW_itemLoseFocus(control)
{
	this.debug ( 'itemLoseFocus(' + control.name + ')', DEBUG_ENTER );
	
	var bReadOnlyControl = false;
	var bNegativeTabIndexControl = false;
	
	// check control attri
	if (control.readOnly + "" != "undefined")
		{
		bReadOnlyControl = control.readOnly;
		}
	if (control.tabIndex + "" != "undefined")
		{
		if( control.tabIndex < 0 )
			bNegativeTabIndexControl = true;
		}

	if (bNegativeTabIndexControl)
		{
		this.debug ( 'itemLoseFocus( ) = 2 (1)', DEBUG_EXIT );
		return 2;
		}

    // restore border
    // can only programatically change border on IE4
    //if (control.gob.bFocusRect && HTDW_DataWindowClass.isIE4 && this.currentControl == control)
	if (this.currentControl == control)
	{
		if (this.bMarkRequired && control.gob.bRequired)
			control.style.backgroundColor = "#FFD9D9";
		else
        	control.style.backgroundColor = this.currentControlBackColor;
	}
	
    // don't do validation if in the middle of forcing focus
    // due to validation error (endless loop could happen)
    if (this.forcingBackFocusTo != null) {
		this.debug ( 'itemLoseFocus( ) = 2 (2)', DEBUG_EXIT );
        return 2;
	}
    if (this.currentControl != control)
        {
        //alert("Focus problem! Control losing focus is not current control!");
        // fake it out
		//this.currentControl = control;
		return 0;
        }

	var gob = control.gob;
	if (gob.getEditFormat != null)
	{
		if (typeof gob.getEditFormat == "string")
		gMask = gob.getEditFormat;
		else
		{
			var exprCtx = this.exprCtx;
			exprCtx.row = control.row;
			exprCtx.currentText = "";
			gMask = gob.getEditFormat (exprCtx);
			this.debug ( 'exprCtx changed ( ' + exprCtx.row + ', ' + exprCtx.currentText + ')' );
		}
		
		// code table's edit format is a dummy "CodeTable" format for info.
		if (gob.bUseCodeTable)
			gMask = "";
	}

    if (!control.bChanged)  // check if Change misfired (losing focus beyond frame?)
        {
        var newValue;
        var row = control.row;
        var col = control.col;
        var rowObj = this.rows[row];
        var colObj = this.cols[col];

        if (control.type == "select-one")
            newValue = control.options[control.selectedIndex].value;
        else
            newValue = control.value;

		if ( newValue == "null!" ) 
		{
			newValue = "";
			control.gob.bNilIsNull = true;
		}
			
        if (newValue == "")
            {
            if (control.gob.bNilIsNull)
				{
				if (rowObj[col] != null)
					control.bChanged = true;
				}
			else if (rowObj[col] != null && rowObj[col] != "")  // for inserts
				control.bChanged = true;
            }
        else if (colObj.convertFromString != null)
            {
            var convertedValue;
		    if (colObj.convertFromString == parseInt)
			{
				//Acréscimo para correção do Bug da Vírgula!
				//AUTOR: Daniel Gomes Silveira
				noComma = newValue;
				
				//Tira o separador de milhar
				var reg = new RegExp("[" + DW_thousandsChar + "]", "g");
				var noComma = noComma.replace(reg, "");

				//Muda o separador decimal por ponto
				var reg = new RegExp("[" + DW_decimalChar + "]", "g");
				var noComma = noComma.replace(reg, ".");
				
				convertedValue = colObj.convertFromString (noComma, 10);
			}
			else
				convertedValue = colObj.convertFromString (newValue);

			//if (rowObj[col] != newValue)				
            if (rowObj[col] == null || rowObj[col].toString( ) != convertedValue.toString( ))
                control.bChanged = true;
            }
        else
            {
            //if (rowObj[col] != newValue)
			if (rowObj[col] == null || rowObj[col].toString( ) != convertedValue.toString( ))
                control.bChanged = true;
            }
        }

    var result = this.AcceptText();

	gMask = "";

    if (result == 1)
        {
        // reformat the data
        var gob = control.gob;
        var value = this.rows[control.row][gob.colNum];
		
        if (control.type == "hidden" || control.type == "password" || 
            control.type == "text" || control.type == "textarea")
            {
            if (gob.format != null)
                {
                var displayValue;

                if (gob.getDisplayFormat != null)
                    {
                    var formatString;
                    if (typeof gob.getDisplayFormat == "string")
                        formatString = gob.getDisplayFormat;
                    else
                        {
                        var exprCtx = this.exprCtx;
                        exprCtx.row = control.row;
                        exprCtx.currentText = "";
                        formatString = gob.getDisplayFormat (exprCtx);
						this.debug ( 'exprCtx changed ( ' + exprCtx.row + ', ' + exprCtx.currentText + ')' );
                        }
                    displayValue = gob.format (formatString, value, this.currentControl);
                    }
                else if (value != null)
					{
	                displayValue = value.toString();
					
					//Acréscimo para correção do Bug da Vírgula!
					//AUTOR: Daniel Gomes Silveira
					if (gob.format == DW_FormatNumber)
							displayValue = displayValue.replace ( ".", DW_decimalChar );				
					}
                else
                    displayValue = "";
					
                this.currentControl.value = displayValue.replace(new RegExp("~~","g"), "~");
                }
            else if ( value != null )
                {
                // Do not compare against Date/Time if no date fields have been defined
                if (!bDateTimeProcessingEnabled ||
                    (value.toString != DW_DatetimeToString &&
                     value.toString != DW_DateToString &&
                     value.toString != DW_TimeToString))
                     this.currentControl.value = value.toString( ).replace(new RegExp("~~","g"), "~");
                }
            else
                this.currentControl.value = "";
            }
        }
      
	this.debug ( 'itemLoseFocus( ) = ' + result, DEBUG_EXIT );  
    return result;
}

function HTDW_selectControlContent(control)
{
	var bNegativeTabIndexControl = false;
	if(control != null)
		{
		if (control.tabIndex + "" != "undefined")
			{
			if( control.tabIndex < 0 )
				bNegativeTabIndexControl = true;
			}

		if(!bNegativeTabIndexControl)
			{
			control.select();
			}
		}
}

function HTDW_getChanges()
{
    var changes = "";
    var index, rowObj;
    for (index=0; index < this.rows.length; ++index)
        {
        rowObj = this.rows[index];
        if (rowObj != null)
            {
            HTDW_RowClass.dumpRow (index, rowObj);
            changes += HTDW_RowClass.generateChange (index, rowObj);
            }
        }
    return changes;
}

function HTDW_itemError(row, col, exprCtx, bIsRequired)
{
    var colObj = this.cols[col];
    var result = 0;

	
    // item error event
    if (this.eventImplemented("ItemError"))
        result = _evtDefault(this.ItemError (row+1, colObj.name, exprCtx.currentText))
	

    // map unknown results to 0
    if (result != 1 && result != 2 && result != 3)
        result = 0;
        
    if (result == 0)
        {
        var sMessage;
        if (colObj.validationError != null)
            sMessage = colObj.validationError (exprCtx);
		//Alteração MedicWare
		//Não validar campos obrigatórios
        else if (bIsRequired)
			return 2;
            //sMessage = "Campo obrigatório: '" + colObj.name + "'.";
        else
            sMessage = "Item '" + exprCtx.currentText + "' não passa no teste de validação.";

        alert (sMessage);
        }

    return result;
}

function HTDW_restoreFocus()
{ 
    if (this.currentControl != null )
    {
        var bDocHasFocus = true;
        var bIsDefined = false;
		
        if ( (document.hasFocus + "" != "undefined") && (this.currentControl.setActive + "" != "undefined") )
		{
			bIsDefined = true;
		}	

        if ( bIsDefined )
        {
            bDocHasFocus = document.hasFocus();
        }

        if(bDocHasFocus == false) 
		{
            this.currentControl.setActive(); // CR323659
		}	
        else
		{ 
            try{this.currentControl.focus();} catch (e){};
		}	
    }
}



function HTDW_setCheckboxValue(control, chkValue, unchkValue)
{
    if (control.checked)
        control.value = chkValue;
    else
        control.value = unchkValue;
}

function HTDW_acceptText()
{
	this.debug ( 'acceptText()', DEBUG_ENTER );
		
    // nothing to do if no current control
    if (this.currentControl == null) {
		this.debug ( 'acceptText() = 1 (1)', DEBUG_EXIT );
        return 1;
	}
		
    var control = this.currentControl;
    var row = control.row;
    var col = control.col;
    var bRequired = control.gob.bRequired;
    var colObj = this.cols[col];
    var bIsValid = true;
    var exprCtx = this.exprCtx;
    var validAction = 2;  // default to accept
    var newValue;
    var oldValue=exprCtx.currentText;
	
    if (control.type == "select-one")
    {
        newValue = control.options[control.selectedIndex].value;
		
		/**
		Este trecho de código estava dando erro quando se tinha uma sequência de 
		<select>´s e mudava-se o valor de todos eles com o mesmo valor navegando 
		com o TAB.
		
        if(oldValue==newValue) {
			this.debug ( 'oldValue==newValue ... ' + oldValue + ' == ' + newValue  );
			this.debug ( 'acceptText() = 1 (2)', DEBUG_EXIT );
			return 1;
		}
		*/
    }
	
    else
        newValue = control.value;

	if ( newValue == "null!" ) 
	{
		newValue = "";
		control.gob.bNilIsNull = true;
	}

    exprCtx.row = row;
    exprCtx.currentText = newValue;
	this.debug ( 'exprCtx changed (' + exprCtx.row + ',' + exprCtx.currentText + ')' );
	
    // check if value required
    if (bRequired && ! control.bChanged)
        {
        if (this.rows[row][col] == null)
            validAction = this.itemError (row, col, exprCtx, true);
        }
    else if (bRequired && control.gob.bNilIsNull && newValue == "" )
        validAction = this.itemError (row, col, exprCtx, true);

    if (control.bChanged)
        {
        if (bIsValid && colObj.validateByType != null)
            bIsValid = colObj.validateByType(newValue, control.gob.bNilIsNull);

        if (bIsValid && colObj.validateItem != null)
            bIsValid = colObj.validateItem (exprCtx);

		
        // item changed event
        if (bIsValid && this.eventImplemented("ItemChanged"))
            {
            validAction = _evtDefault(this.ItemChanged (row+1, colObj.name, newValue));
            // map unknown results to 0
            if (validAction != 1 && validAction != 2)
                validAction = 0;
            // map itemChanged action codes to itemError action codes
            if (validAction == 0) // accept value
                validAction = 2;
            else
                {
                bIsValid = false;
                if (validAction == 1) // reject value, no focus change
                    validAction = 1;
                else // reject value, allow focus change
                    validAction = 3;
                }
            }
		

        if (! bIsValid)
            validAction = this.itemError (row, col, exprCtx, false);

        if (validAction == 2)
            {
            var rowObj = this.rows[row];
            if (control.gob.bNilIsNull && newValue == "" )
                {
                if (rowObj[col] != null)
                    { 
                    rowObj[col] = null;
                    if (rowObj[0].itemStatus != DW_ITEMSTATUS_MODIFIED &&
                        rowObj[0].itemStatus != DW_ITEMSTATUS_NEW_MODIFIED)
                        this.modifiedCount++;
                    rowObj[0].colModified[col] = true;		    
                    if (rowObj[0].itemStatus == DW_ITEMSTATUS_NOCHANGE)
                        rowObj[0].itemStatus = DW_ITEMSTATUS_MODIFIED;
                    else if (rowObj[0].itemStatus == DW_ITEMSTATUS_NEW)
                        rowObj[0].itemStatus = DW_ITEMSTATUS_NEW_MODIFIED;
                    }
                }
            else if (colObj.convertFromString != null)
                {
				var convertedValue;
				if (colObj.convertFromString == parseInt)
					{
					//Acréscimo para correção do Bug da Vírgula!
					//AUTOR: Daniel Gomes Silveira
					noComma = newValue;
					
					//Tira o separador de milhar
					var reg = new RegExp("[" + DW_thousandsChar + "]", "g");
					var noComma = noComma.replace(reg, "");
	
					//Muda o separador decimal por ponto
					var reg = new RegExp("[" + DW_decimalChar + "]", "g");
					var noComma = noComma.replace(reg, ".");					
					
					convertedValue = colObj.convertFromString (noComma, 10);
					}
				else
					convertedValue = colObj.convertFromString (newValue);

                if (rowObj[col] != convertedValue)
                    {
					if( typeof convertedValue == "string" ) convertedValue = convertedValue.replace(new RegExp ('~','g'),"~~");
                    rowObj[col] = convertedValue;
                    if (rowObj[0].itemStatus != DW_ITEMSTATUS_MODIFIED &&
                        rowObj[0].itemStatus != DW_ITEMSTATUS_NEW_MODIFIED)
                        this.modifiedCount++;	    
                    rowObj[0].colModified[col] = true;		    
                    if (rowObj[0].itemStatus == DW_ITEMSTATUS_NOCHANGE)
                        rowObj[0].itemStatus = DW_ITEMSTATUS_MODIFIED;
                    else if (rowObj[0].itemStatus == DW_ITEMSTATUS_NEW)
                        rowObj[0].itemStatus = DW_ITEMSTATUS_NEW_MODIFIED;
                    }
                }
            else
                {
				if( typeof newValue == "string" ) newValue = newValue.replace(new RegExp ('~','g'),"~~");
                if (rowObj[col] != newValue)
                    {
                    rowObj[col] = newValue;
                    if (rowObj[0].itemStatus != DW_ITEMSTATUS_MODIFIED &&
                        rowObj[0].itemStatus != DW_ITEMSTATUS_NEW_MODIFIED)
                        this.modifiedCount++;	    
                    rowObj[0].colModified[col] = true;		    
                    if (rowObj[0].itemStatus == DW_ITEMSTATUS_NOCHANGE)
                        rowObj[0].itemStatus = DW_ITEMSTATUS_MODIFIED;
                    else if (rowObj[0].itemStatus == DW_ITEMSTATUS_NEW)
                        rowObj[0].itemStatus = DW_ITEMSTATUS_NEW_MODIFIED;
                    }
                }
				
            control.bChanged = false;
            // skip current control
            colObj.updateDependents(this, row, true);
            }
        }

    // force focus back if an error (focus change will happen after we return!)
    if (validAction < 2)
        {
      
        this.forcingBackFocusTo = control;
        control.focus();
        }

    var result = (validAction < 2) ? -1 : 1;

	this.debug ( 'acceptText() = ' + result + ' (3)', DEBUG_EXIT );
    return result;
	
    // this return will only be used if we are not an input form
    return 1;
}

// if false returned, don't allow focus to change or action to happen (leave focus in last control to have gained focus
function HTDW_itemClicked(row, col, objName)
{
	this.debug ( 'itemClicked(' + row + ',' + col + ',' + objName + ')', DEBUG_ENTER );	

    var evtResult = 0;
		
    // CR228156 - click on DDDW column fires a validation error in IE5.x - Partha
    if (this.currentControl != null)
    {
	if ( this.currentControl.type == "select-one" )
	{
	    if ( HTDW_DataWindowClass.isIE4 
		&& this.currentControl.gob.bRequired == true 
		&& this.currentControl.value == "" ) {
		
			this.debug ( 'itemClicked() = false (1)', DEBUG_EXIT );	
            return false ;
		}
	    else 
		if (this.AcceptText() != 1) {
		
			this.debug ( 'itemClicked() = false (2)', DEBUG_EXIT );
			return false;
		}

	}
    	else if (this.currentControl.type == "checkbox" 
		|| this.currentControl.type == "radio" 
		|| this.currentControl.type == "select-multiple" )
	{
        	if (this.AcceptText() != 1) {
			
				this.debug ( 'itemClicked() = false (3)', DEBUG_EXIT );
				return false;
			}
	}
    }
    
    if (this.eventImplemented("Clicked"))
        evtResult = _evtDefault(this.Clicked (row+1, objName));

    // prevent clicked event from bubbling up in IE4 or higher
    if (HTDW_DataWindowClass.isIE4)
        window.event.cancelBubble = true;

    this.clickedRow = row;
    this.clickedCol = col;
    
	this.debug ( 'itemClicked() = ' + (evtResult != 1) + ' (4)', DEBUG_EXIT );
    return evtResult != 1;
}

function HTDW_performAction(action, op_extraServClassMsgs)
{ 
    this.action = action;
    if (this.b4GLWeb) {
        // cause the surrounding page to be submitted
        psPage.Submit();
	}
	else { // deal with it like in 7.0
		var rc = 0;
		
	    // update start event 
	    if (action == "Update" && this.eventImplemented("UpdateStart"))
        {
    	    evtResult = _evtDefault(this.UpdateStart ());
	        // a return of 1 will cancel action
	        if (evtResult == 1)
    	        return;
        }
		
	    if (action == "DeleteRow" && this.eventImplemented("DeleteStart"))
        {
    	    evtResult = _evtDefault(this.DeleteStart ());
	        // a return of 1 will cancel action
	        if (evtResult == 1)
    	        return;
        }
		
	    if (action == "InsertRow" && this.eventImplemented("InsertStart"))
        {
    	    evtResult = _evtDefault(this.InsertStart ());
	        // a return of 1 will cancel action
	        if (evtResult == 1)
    	        return;
        }
		
   	    // OnSubmit can prevent the page from being submitted by returning 1
   	    if (this.eventImplemented("OnSubmit")) 
		{
            rc = _evtDefault(this.OnSubmit ());
			if (rc == 1)
    	        return;
		}
		
        if (rc == 0) {
       	    this.actionField.value = this.action;
   	        this.contextField.value = this.GetFullContext();
					
			if ( this.ajax ) 
				this.submitAjax( op_extraServClassMsgs );
			else
			{
				try {
					var sMsg = null;
					
					switch ( action ) {
						case "Update":
							sMsg = "Gravando... Aguarde...";
							break;
						case "DeleteRow":
							sMsg = "Excluindo... Aguarde...";
							break;
					}
					
					showMsgBox( sMsg, null, null, null, true );
				} catch (e) {}
			
				this.submitForm.submit();
			}
		}
	}
}

HTDW_DataWindowClass.prototype.submitAjax = HTDW_submitAjax;
function HTDW_submitAjax( op_extraServClassMsgs )
{
	if ( this.retrieveParams != undefined )
	{
		if ( typeof this.retrieveParams == "object" )
		{
				this.retrieveParams = this.retrieveParams.join( "\\n" );
		}
	
		var paramField = eval ( "this.submitForm." + this.name + "_params" );
		paramField.value = this.retrieveParams;
	}
	else if ( this.paramsSource != undefined )
	{
		var retrieveParamsAux = "";
		
		if ( typeof this.paramsSource == "string" )
		{
			this.paramsSource = this.paramsSource.split( "," );
		}
		
		for ( var parIdx = 0; parIdx < this.paramsSource.length; parIdx++ )
		{
			if ( parIdx > 0 )
			{
				retrieveParamsAux += "\\n";
			}
			retrieveParamsAux += this.GetItem( 1, this.paramsSource[parIdx] );
		}
		
		var paramField = eval ( "this.submitForm." + this.name + "_params" );
		paramField.value = retrieveParamsAux;
	}
	
	var dataSource = this.getDataSource( op_extraServClassMsgs );
	if ( !this.container )
		this.container = this.submitForm.parentNode.parentNode.parentNode;
	
	/**
	var posMsgBoxOnObj = function ( msgBox, win ) 
	{
		msgBox.style.left = this.container.offsetLeft + ( win.document.body.leftMargin - 0 );
		msgBox.style.top = this.container.offsetTop + ( win.document.body.topMargin - 0 ) - 5;
	}
	msg.container = container;
	*/
	showMsgBox( new MsgClass( null, this.name ), null, null, null, true );
	
	this.submitAjaxCallBack.action = this.action;
	loadHTMLDW( dataSource, this.container, this.submitAjaxCallBack );
}

HTDW_DataWindowClass.prototype.submitAjaxCallBack = HTDW_submitAjaxCallBack;
function HTDW_submitAjaxCallBack( htmldwMsg, idx )
{ 
	var htmldwName;
	
	if( idx == null ) {
		htmldwName = htmldwMsg.getMsgByID ( "htmldwName" );
	}
	else {
		htmldwName = htmldwMsg.getMsgByID ( "htmldwName_" + idx );
	}		

	var dw;
	try { dw = eval( htmldwName ); }
	catch(e){ dw = null; }
		
	if( dw ) {
		if ( dw.eventImplemented("ActionPerformed") ) {
			if( idx == null )
				dw.ActionPerformed( htmldwMsg.getMsgByID ( "action" ), htmldwMsg.getMsgByID ( "actionReturn" ), htmldwMsg );
			else
				dw.ActionPerformed( htmldwMsg.getMsgByID ( "action_" + idx ), htmldwMsg.getMsgByID ( "actionReturn_" + idx ), htmldwMsg );
		}
	}

	hideMsgBox ( htmldwName );
}

function HTDW_GetFullContext()
{
    var     result = this.context;

    result += "(";
    result += this.getChanges();
    if (this.currRow != -1)
        result += "(row " + this.currRow + ")";
    if (this.sortString != null)
        result += "(sortString '" + escapeString (this.sortString) + "')";
    result += ")";

    return result ;
}

function HTDW_buttonPress(action, row, buttonName)
{
    var evtResult;

    // false from clicked will cancel processing
    if (!this.itemClicked(row, -1, buttonName))
        return;

    // button clicking event
    if (this.eventImplemented("ButtonClicking"))
        {
        evtResult = _evtDefault(this.ButtonClicking (row+1, buttonName));
        // non-zero return will cancel processing
        if (evtResult != 0)
            return;
        }

    // make sure all changes have been recorded
    if (action != "" && this.AcceptText() != 1)
        // cancel processing if AcceptText fails
        return;

    if (action == "Print")
	    {
        window.print();
        return;
        }
    // an action of "" is a user defined button which doesn't cause a page reload
    if (action != "")
		this.performAction(action);
    else
        {
        // button clicked event
        if (this.eventImplemented("ButtonClicked"))
            this.ButtonClicked (row+1, buttonName)
        }
}

function HTDW_getColNum(col)
{
    if (typeof col == "string")
        {
        for (var i=1; i< this.cols.length; ++i)
            {
            var colObj = this.cols[i];
            if (colObj.name == col)
                return i;
            }
        }
    else
        return col;

    // if we get here, then we couldn't find it
    return -1;
}

function HTDW_DeletedCount()
{
	return this.deletedCount;
}

function HTDW_DeleteRow(row, args)
{
	if(this.AcceptText() == 1)
		{
		if (row > 0)
    		this.currRow = row-1;
		this.performAction ("DeleteRow", args);
		return ;
		}
	else
		return -1;
}

function HTDW_GetClickedColumn()
{
	return this.clickedCol;
}

function HTDW_GetClickedRow()
{
	return this.clickedRow + 1;
}

function HTDW_GetColumn()
{
	return this.currCol;
}

function HTDW_GetNextModified(startRow)
{
    var nextModified = 0;
    var index, rowObj;
 
    if (startRow == null)
        return null;

    for (index=startRow-1; index < this.rows.length; ++index)
        {
        rowObj = this.rows[index];
        if (rowObj != null)
            {
            if (rowObj[0].itemStatus == DW_ITEMSTATUS_MODIFIED ||
                rowObj[0].itemStatus == DW_ITEMSTATUS_NEW_MODIFIED)
                {
                nextModified = index+1;
                break;
                }
            }
        }
    return nextModified;
}

function HTDW_GetRow()
{
	return this.currRow + 1;
}

function HTDW_GetItem(row, col)
{
	var result;
	var colNum = this.getColNum(col);
    var rowObj = this.rows[row-1];

	if (colNum == -1 ||
	        (rowObj + "" == "undefined") || 
			rowObj[colNum] + "" == "undefined")
		result = -1;
	else
		result = rowObj[colNum];

	return result;
}

function HTDW_GetItemStatus(row, col)
{
    if (row == null || col == null)
        return null;

    var dwItemStatus = DW_ITEMSTATUS_NOCHANGE;
    var colNum = this.getColNum(col);
    var rowObj = this.rows[row-1];

    if (colNum == -1 ||
            (rowObj + "" == "undefined") || 
            (colNum > 0 && rowObj[colNum] + "" == "undefined"))
        dwItemStatus = -1;
    else if (colNum == 0)
            dwItemStatus = rowObj[0].itemStatus;
    else
        {
        if (rowObj[0].colModified[colNum])
            dwItemStatus = DW_ITEMSTATUS_MODIFIED;
        }

	return dwItemStatus;
}

function HTDW_InsertRow(row, args)
{
	if(this.AcceptText() == 1)
		{
		this.currRow = row-1;
		this.performAction ("InsertRow", args);
		return ;
		}
	else
		return -1;
}

function HTDW_ModifiedCount()
{
    return this.modifiedCount;
}

function HTDW_Retrieve()
{
	if(this.AcceptText() == 1)
		{
		this.performAction ("Retrieve");
		return 1;
		}
	else
		return -1;
}

function HTDW_RetrieveEx( params )
{
	if(!this.ajax)
	{
		alert( "This is not a WebDatawindow Ajax. Not supported!" );
		return -1;
	}
	
	this.retrieveParams = params;
	return this.Retrieve( );
}

function HTDW_RowCount()
{
	return this.rowCount;
}

function HTDW_ScrollFirstPage()
{
	if(this.AcceptText() == 1)
		{
		this.performAction ("PageFirst");
		return 1;
		}
	else
		return -1;
}

function HTDW_ScrollLastPage()
{
	if(this.AcceptText() == 1)
		{
		this.performAction ("PageLast");
		return 1;
		}
	else
		return -1;
}

function HTDW_ScrollNextPage()
{
	if(this.AcceptText() == 1)
		{
		this.performAction ("PageNext");
		return 1;
		}
	else
		return -1;
}

function HTDW_ScrollPriorPage()
{
	if(this.AcceptText() == 1)
		{
		this.performAction ("PagePrior");
		return 1;
		}
	else
		return -1;
}

function HTDW_SetItem(row,col,value)
{
	var result;
	var colNum = this.getColNum(col);
    var rowObj = this.rows[row-1];

	if (colNum == -1 ||
	        (rowObj + "" == "undefined") || 
			rowObj[colNum] + "" == "undefined")
		result = -1;
	else
		{
        if (rowObj[colNum] != value)
			{
			rowObj[colNum] = value;
            if (rowObj[0].itemStatus != DW_ITEMSTATUS_MODIFIED &&
                rowObj[0].itemStatus != DW_ITEMSTATUS_NEW_MODIFIED)
				this.modifiedCount++;	    
			rowObj[0].colModified[colNum] = true;
            if (rowObj[0].itemStatus == DW_ITEMSTATUS_NOCHANGE)
                rowObj[0].itemStatus = DW_ITEMSTATUS_MODIFIED;
            else if (rowObj[0].itemStatus == DW_ITEMSTATUS_NEW)
                rowObj[0].itemStatus = DW_ITEMSTATUS_NEW_MODIFIED;
			}

		// update them all
		this.cols[colNum].updateDependents(this, row-1, false);
		result = 1;
		}

	return result;
}

function HTDW_SetColumn(col)
{
    var result = -1;
	var colNum = this.getColNum(col);

    if (colNum != -1)
        {
        var colObj = this.cols[colNum];
        if (typeof colObj != "undefined" && colObj.displayGobName != null)
            {
            var control = this.findControl(colObj.displayGobName, this.currRow, true);
            // if we can't find a control, then we can't set the column
            if (control != null)
                {
                // force focus onto the found control
                // the onFocus event will change the currency variables
                try 
					{
					control.focus();
                	result = 1;
					}
				catch (e)
					{
					result = -1;
					}
                }
            }
        }
	return result;
}

function HTDW_SetRow(row)
{
    var result = -1;
	row -= 1;
    this.currRow = row;
	var colNum = this.currCol;

    if (colNum != -1)
        {
        var colObj = this.cols[colNum];
        if (typeof colObj != "undefined" && colObj.displayGobName != null)
            {
            var control = this.findControl(colObj.displayGobName, row, true);
            // if we can't find a control, then we can't set the row
            if (control != null)
                {
                // force focus onto the found control, 
                // the onFocus event will change the currency variables
                control.focus();
                result = 1;
                }
            }
        }
	return result;
}

function HTDW_SetSort(sortString)
{
	this.sortString = sortString;
	return 1;
}

function HTDW_Sort()
{
	if(this.AcceptText() == 1)
		{
		this.performAction ("Sort");
		return 1;
		}
	else
		return -1;
}

function HTDW_Update(args)
{
	if(this.AcceptText() == 1)
		{
		this.performAction ("Update", args);
		return ;
		}
	else
		return -1;
}

function DW_EditKeyPressed(nCase)
{
	if(nCase == 1)
	{
		event.srcElement.value += String.fromCharCode(event.keyCode).toUpperCase();
		event.returnValue = false;
	}
	else if (nCase == 2)
	{
		event.srcElement.value += String.fromCharCode(event.keyCode).toLowerCase();
		event.returnValue = false;
	}
}

function HTDW_DataWindowClass(name, submitForm, actionField, contextField)
{
    // if used in 4GL web, these will not be defined!
    if (arguments.length == 1)
        {
        submitForm = null;
        actionField = null;
        contextField = null;
        }
        
    this.name = name;
    this.submitForm = submitForm;
    this.actionField = actionField;
    this.contextField = contextField;
    this.sortString = null;
    this.action = "";
    
    // private functions
    this.buttonPress = HTDW_buttonPress;
	this.performAction = HTDW_performAction;

    this.eventImplemented = HTDW_eventImplemented;
    this.itemClicked = HTDW_itemClicked;

    // public function
    this.GetFullContext = HTDW_GetFullContext;
    
    this.currRow = -1;
    this.currCol = -1;
    this.forcingBackFocusTo = null;
    this.currentControl = null;
    this.bSingleRow = false;
    
    this.gobs = new Object();
    this.rows = new Array();
    this.cols = new Array();
    this.navLayerForms = new Array();
    this.exprCtx = new HTDW_exprContextClass(this);

    // private functions
    this.getChanges = HTDW_getChanges;
    this.itemLoseFocus = HTDW_itemLoseFocus;
    this.selectControlContent = HTDW_selectControlContent;
    this.itemError = HTDW_itemError;
    this.itemGainFocus = HTDW_itemGainFocus;
    this.restoreFocus = HTDW_restoreFocus;
    this.findControl = HTDW_findControl;
    this.setCheckboxValue = HTDW_setCheckboxValue;

    // public functions
    this.AcceptText = HTDW_acceptText;

    // private functions
    this.getColNum = HTDW_getColNum;
    
    // public functions
    this.AcceptText = HTDW_acceptText;
	this.DeletedCount = HTDW_DeletedCount;
	this.DeleteRow = HTDW_DeleteRow;
	this.GetClickedColumn = HTDW_GetClickedColumn;
	this.GetClickedRow = HTDW_GetClickedRow;
	this.GetColumn = HTDW_GetColumn;
	this.GetNextModified = HTDW_GetNextModified;
	this.GetRow = HTDW_GetRow;
	this.GetItem = HTDW_GetItem;
	this.GetItemStatus = HTDW_GetItemStatus;
	this.InsertRow = HTDW_InsertRow;
	this.ModifiedCount = HTDW_ModifiedCount;
	this.Retrieve = HTDW_Retrieve;
	this.RetrieveEx = HTDW_RetrieveEx;
	this.RowCount = HTDW_RowCount;
	this.ScrollFirstPage = HTDW_ScrollFirstPage;
	this.ScrollLastPage = HTDW_ScrollLastPage
	this.ScrollNextPage = HTDW_ScrollNextPage
	this.ScrollPriorPage = HTDW_ScrollPriorPage
	this.SetItem = HTDW_SetItem
	this.SetColumn = HTDW_SetColumn
	this.SetRow = HTDW_SetRow
	this.SetSort = HTDW_SetSort
	this.Sort = HTDW_Sort;
	this.Update = HTDW_Update;
	
	this.ajax = false;
	
	//**** atributos e funcoes referentes à paginacao e o buffer da datawindow *******

	this.bufferPaginacao = null;
	this.pageSize = 0;
	
	//*************************************
	
	if ( this.eventImplemented( "OnLoad" ) )
	{
		setTimeout( this.name + ".OnLoad( )", 0.05 );
	}
	else 
	{
		function onLoadFunc ( ) 
		{
			if ( onLoadFunc.htmldw.eventImplemented( "OnLoad" ) )
				onLoadFunc.htmldw.OnLoad( );
		}
		onLoadFunc.htmldw = this;
		
		try {
			addEventListenerFunc ( window, "onload", onLoadFunc );
		}
		catch (e) {}
	}

}

// determine the client browser
// this should be used only where ABSOLUTELY necessary
// Generic JavaScript should be used where ever possible
HTDW_DataWindowClass.isNav4 = false;
HTDW_DataWindowClass.isIE4 = false;
if (parseInt(navigator.appVersion) >= 4)
    {
    HTDW_DataWindowClass.isNav4 = (navigator.appName == "Netscape");
    HTDW_DataWindowClass.isIE4 = (navigator.appName.indexOf("Microsoft") != -1);
    }

var DW_shortDateFormat = "d/m/yy";
var DW_longDateFormat = "dd/mm/yyyy hh:mm:ss.ffffff";
var DW_timeFormat = "hh:mm:ss";

function DW_StringParse(inString)
{
    var result = new DW_StringClass();
    
    if (DW_parseStringAgainstMask(inString, result))
    {
        return result.str;
    }
    else
        return null;
}

function DW_IsString(inString)
{
    if (inString == "")
        return true;
	return DW_parseStringAgainstMask(inString, null);
}

function DW_parseStringAgainstMask(inString, outStr)
{
	var Mask = gMask;

	if (Mask == "") 
	{
		if(outStr != null)
			outStr.str = inString;
		return true;
	}

    // Get encoded format against mask
	var format = new DW_StringEncodingClass(Mask);

    // if invald mask, return false
	if (!format.bValid) return false;

	// Create a new number class
	var s = new DW_StringClass();

	var currChar;
	var charIndex = 0;
	
    var index = 0;
    var encodedFormat = format.encodedFormat;
    var action;
    
	// Create a new number class
	var s = new DW_StringClass();

	while (charIndex < inString.length && index < encodedFormat.length)
	{
		// Now extract one token from encode string
		action = 0;

		if( index < encodedFormat.length)
		{
            action = encodedFormat[index];
			index++;
		}
		
		if (typeof action == "string")
		{
			currChar = inString.substring(charIndex, charIndex+action.length); 
			charIndex = charIndex + action.length

			if (action != currChar)
				return false;
			else
				continue;
		}
		else
			currChar = inString.charAt(charIndex++);

		if(action == DWFMT_allChars)
		{
			s.str = inString;
			break;
		}
		else if(action == DWFMT_allChar)
		{
			s.str += currChar;
		}
		else if(action == DWFMT_stringChar)
		{
			if (DW_parseIsAlpha(currChar) || DW_parseIsDigit(currChar) || currChar==" ") 
				s.str += currChar;
			else
				return false;
		}
		else if(action == DWFMT_upperCaseChar)
		{
			if (DW_parseIsAlpha(currChar) || DW_parseIsDigit(currChar) || currChar==" " || currChar==DW_decimalChar) 
				s.str += currChar.toUpperCase();
			else
				return false;
		}
		else if(action == DWFMT_lowerCaseChar || currChar==" ")
		{
			if (DW_parseIsAlpha(currChar) || DW_parseIsDigit(currChar) || currChar==" " || currChar==DW_decimalChar) 
				s.str += currChar.toLowerCase();
			else
				return false;
		}
		else if(action == DWFMT_numberChar)
		{
			if (DW_parseIsDigit(currChar)) 
				s.str += currChar;
			else
				return false;
		}
	}

	if(outStr != null)
		outStr.str = s.str;

	return true;
}


//
// String formatting code
//
var DWFMT_allChars = 0;
var DWFMT_allChar = 1;
var DWFMT_stringChar = 2;
var DWFMT_upperCaseChar = 3;
var DWFMT_lowerCaseChar = 4;
var DWFMT_numberChar = 5;

function DW_StringEncodingClass(inString)
{
    var index;
    var currChar;
    var encodedFormat = new Array();
    var accum = "";
    var numInSection;
    var offset = 0;
    var bValid = true;
    
    this.encodedFormat = encodedFormat;
	this.color = "";

    var strLen = inString.length;
    for (index=0; index < strLen && bValid; )
        {
        currChar = inString.charAt(index);
        // handle keywords
        if (currChar == "[")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            for (; inString.charAt(index) != "]"; index++)
                accum += inString.charAt(index);
            index++; // skip ]
            if (accum.toUpperCase() == "GENERAL")
                encodedFormat[offset++] = DWFMT_allChars;
            else
                {
				if (!parseInt(accum)) 
					this.color = accum.toLowerCase();
				else
					this.color = eval(accum);
                this.keyword = accum;
                }
            accum = "";
            }
		else if (currChar == "X" || currChar == "x" || currChar == "@")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            encodedFormat[offset++] = DWFMT_allChar;
            }
        else if (currChar == "A" || currChar == "a")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            encodedFormat[offset++] = DWFMT_stringChar;
            }
        else if (currChar == "!")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            encodedFormat[offset++] = DWFMT_upperCaseChar;
            }
        else if (currChar == "^")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            encodedFormat[offset++] = DWFMT_lowerCaseChar;
            }
        else if (currChar == "#" || currChar == "0")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            encodedFormat[offset++] = DWFMT_numberChar;
            }
        else if (currChar == "\\")
            {
            index++;
            accum += inString.charAt(index++);
            }
        else if (currChar == "'")
            {
            index++;
            while (index < strLen)
                {
                currChar = inString.charAt(index);
                if (currChar == "'")
                    break;
                accum += currChar;
                index++;
                }
            // check if we fell off end before finding closing quotes
            if (index == strLen)
                bValid = false;

            index++; // skip trailing '
            }
        else
            {
            accum += currChar;
            index++;
            }
        }

    if (accum != "")
        encodedFormat[offset++] = accum;

	if (encodedFormat.length == 0 ) 
		bValid = false;

    this.bValid = bValid;
}

function DW_StringFormatClass(formatString)
{
    var semiOffset = formatString.indexOf(";");
    
    if (semiOffset != -1)
        {
        this.mainFormat = new DW_StringEncodingClass(formatString.substring(0, semiOffset));
        this.nullFormat = new DW_StringEncodingClass(formatString.substring(semiOffset+1, formatString.length));

        this.bValid = this.mainFormat.bValid && this.nullFormat.bValid;
        }
    else
        {
        this.mainFormat = new DW_StringEncodingClass(formatString);
        this.nullFormat = null;
        this.bValid = this.mainFormat.bValid;
        }

}

function DW_FormatString(formatString, value, control)
{
    var stringFormat = new DW_StringFormatClass(formatString);
    var result = "";
    var format;

    if (stringFormat.bValid)
        {
        if (value == null && stringFormat.nullFormat != null)
            format = stringFormat.nullFormat;
        else
            format = stringFormat.mainFormat;
            
        var index;
        var encodedFormat = format.encodedFormat;
        var action;
        var strIndex = 0;
        var strLen;

        // a length of -1 means that we will always put in " " chars
        if (value != null)
            strLen = value.length;
        else
            strLen = -1;
            
        for (index=0; index < encodedFormat.length ; index++)
            {
            action = encodedFormat[index];
            if (typeof action == "string")
                result += action;
            else if (action == DWFMT_allChars)
                {
                // get the rest
                if (strIndex < strLen)
                    {
                    result += value.substring(strIndex, strLen);
                    strIndex = strLen;
                    }
                }
            else if (action == DWFMT_allChar)
                {
                if (strIndex < strLen)
                    result += value.charAt(strIndex);
                else
                    result += " ";
				strIndex++;
                }
            else if (action == DWFMT_stringChar)
                {
                if (strIndex < strLen && (DW_parseIsAlpha(value.charAt(strIndex)) || DW_parseIsDigit(value.charAt(strIndex))))
                    result += value.charAt(strIndex);
                else
                    result += " ";
				strIndex++;
                }
            else if (action == DWFMT_upperCaseChar)
                {
                if (strIndex < strLen && (DW_parseIsAlpha(value.charAt(strIndex)) || DW_parseIsDigit(value.charAt(strIndex)) || value.charAt(strIndex)==DW_decimalChar))
                    result += value.charAt(strIndex).toUpperCase();
                else
                    result += " ";
				strIndex++;
				}
            else if (action == DWFMT_lowerCaseChar)
                {
                if (strIndex < strLen && (DW_parseIsAlpha(value.charAt(strIndex)) || DW_parseIsDigit(value.charAt(strIndex)) || value.charAt(strIndex)==DW_decimalChar))
                    result += value.charAt(strIndex).toLowerCase();
                else
                    result += " ";
				strIndex++;
				}
            else if (action == DWFMT_numberChar)
                {
                if (strIndex < strLen && DW_parseIsDigit(value.charAt(strIndex)))
                    result += value.charAt(strIndex);
                else
                    result += " ";
				strIndex++;
                }
            }
        }
    else if ( value != null )
		// Simulating a [general] format.
        result = value;
	else
		result = "";

	if (this.bStylePositioning && format && format.bValid)  
        if ( format.color == "" || typeof format.color == "string" )
            control.style.color = format.color;
        else
            control.style.color = convertToRGB( format.color );

    return result;
}

function DW_StringClass(str) 
{
    if (arguments.length == 0)
        str = "";
        
    this.str = str;
}

function DW_LeftTrim(inString)
{
    var index, tempChar, outString = "";
    var strLength = inString.length;
    // skip leading blanks
    for (index=0; index < strLength; index++)
        {
        tempChar= inString.charAt (index);
        if (tempChar != " ")
            break;
        }
    if (index < strLength)
        outString = inString.substring(index, strLength);

    return outString;
}

function DW_RightTrim(inString)
{
    var index, tempChar, outString = "";
    // skip trailing blanks
    for (index=inString.length-1; index >= 0; index--)
        {
        tempChar= inString.charAt (index);
        if (tempChar != " ")
            break;
        }
    if (index >= 0)    
        outString = inString.substring(0, index+1);

    return outString;
}

function DW_ConvertLike(inString, escapeChar)
{
    var index;
    var outString = "";
    var tempChar;
    var strLength = inString.length;

    if (arguments.length < 2)
        escapeChar = "";
        
    // force to string type or charAt will fail!
	inString = inString + "";
    for ( index=0; index < strLength; index++ )
        {
        tempChar = inString.charAt( index );
        if (tempChar == escapeChar) 
            {
            index++;
            outString += inString.charAt( index );
            }
        else if (tempChar == "%")
            outString += ".*";
        else if (tempChar == "_")
            outString += ".";
        else
            outString += tempChar;
        }
    return new RegExp(outString);
}

function DW_Fill(inString, length)
{
    var outIndex, inIndex;
    var outString = "";
    var strLength = inString.length;

    // Fill("*--", 4) = "*--*"
	inString = inString + "";
    for ( outIndex=0, inIndex=0; outIndex < length; outIndex++, inIndex++ )
        {
        // restart input string if necessary
        if (inIndex >= strLength)
            inIndex = 0;
        outString += inString.charAt( inIndex );
        }
    return outString;
}

function DW_Mid(inString, start, length)
{
    var end
    
    if (arguments.length < 3)
        end = inString.length;
    else
        end = start + length;
        
    return inString.substring(start-1,end)
}

function DW_Replace(inString, start, length, replString)
{
    var sResult = inString.substring(0, start-1);
    sResult += replString;
    sResult += inString.substring(start + length -1, inString.length);

    return sResult;
}

function DW_Right(inString, length)
{
    var strLen = inString.length
    return inString.substring(strLen - length, strLen)
}

function DW_Space(n)
{
    var sResult = "";
    for (var i=0; i < n;  i++)
        sResult += " ";

    return sResult;
}

function DW_WordCap(inString)
{
    var lowerCaseString = inString.toLowerCase();
    var outString = "";
    var index;
    var tempChar;
    var bCap = true;
    var strLength = lowerCaseString.length;
    
    for(index=0; index < strLength; index++)
        {
        tempChar = lowerCaseString.charAt( index );
        if (bCap && tempChar != " ")
            {
            outString += tempChar.toUpperCase();
            bCap = false;
            }
        else if (tempChar == " ")
            {
            bCap = true;
            outString += tempChar;
            }
        else
            outString += tempChar;
        }

    return outString;
}

//
// Date formatting code
//

// these constants are for use in date formats
var DWFMT_daynz = 0;
var DWFMT_dayz = 1;
var DWFMT_dayshortname = 2;
var DWFMT_daylongname = 3;
var DWFMT_monthnz = 4;
var DWFMT_monthz = 5;
var DWFMT_monthshortname = 6;
var DWFMT_monthlongname = 7;
var DWFMT_2digityear = 8;
var DWFMT_4digityear = 9;
var DWFMT_hournz = 10;
var DWFMT_hourz = 11;
var DWFMT_minnz = 12;
var DWFMT_minz = 13;
var DWFMT_secnz = 14;
var DWFMT_secz = 15;
var DWFMT_msec = 16;
var DWFMT_apCaps = 17;
var DWFMT_apNCaps = 18;
var DWFMT_ampmCaps = 19;
var DWFMT_ampmNCaps = 20;
var DWFMT_changeToCurrent = 21;

function DW_DateEncodingClass(inString)
{
    var index;
    var currChar;
    var encodedFormat = new Array();
    var accum = "";
    var numInSection;
    var offset = 0;
    var bValid = true;
    var bGotHour = false;
    
    this.b24hr = true;
    this.color = "";

    var strLen = inString.length;
    for (index=0; index < strLen && bValid; )
        {
        currChar = inString.charAt(index);
        // handle keywords
        if (currChar == "[")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            for (; inString.charAt(index) != "]"; index++)
                accum += inString.charAt(index);
            index++; // skip ]
            var inlineEncoding = null;
            var keyword = accum.toUpperCase();
            if (keyword == "CURRENT")
                encodedFormat[offset++] = DWFMT_changeToCurrent;
            else if (keyword == "GENERAL" || keyword == "SHORTDATE" || keyword == "DATE")
                inlineEncoding = new DW_DateEncodingClass(DW_shortDateFormat);
            else if (keyword == "LONGDATE")
                inlineEncoding = new DW_DateEncodingClass(DW_longDateFormat);
            else if (keyword == "TIME")
                inlineEncoding = new DW_DateEncodingClass(DW_timeFormat);
            else
                {
				if (!parseInt(accum)) 
					this.color = accum.toLowerCase();
				else
					this.color = eval(accum);
                this.keyword = accum;
                }
            // if we build another format, inline it into current one
            if (inlineEncoding != null && inlineEncoding.bValid)
                {
                var innerFormat = inlineEncoding.encodedFormat;
                for (var j=0; j<innerFormat.length; j++)
                    encodedFormat[offset++] = innerFormat[j];
				if (keyword == "TIME")
					this.b24hr = inlineEncoding.b24hr;
                }
            accum = "";
            }
        else if (currChar == "d" || currChar == "D")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the d's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "D"; index++, numInSection++)
                ;
            if (numInSection == 1)
                encodedFormat[offset++] = DWFMT_daynz;
            else if (numInSection == 2)
                encodedFormat[offset++] = DWFMT_dayz;
            else if (numInSection == 3)
                encodedFormat[offset++] = DWFMT_dayshortname;
            else if (numInSection == 4)
                encodedFormat[offset++] = DWFMT_daylongname;
            else
                bValid = false;
            }
        else if (currChar == "m" || currChar == "M")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the m's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "M"; index++, numInSection++)
                ;
            if (numInSection == 1)
                if ( bGotHour )
                    {
                    encodedFormat[offset++] = DWFMT_minnz;
                    bGotHour = false;
                    }
                else
                    encodedFormat[offset++] = DWFMT_monthnz;
            else if (numInSection == 2)
                if ( bGotHour )
                    {
                    encodedFormat[offset++] = DWFMT_minz;
                    bGotHour = false;
                    }
                else
                    encodedFormat[offset++] = DWFMT_monthz;
            else if (numInSection == 3)
                encodedFormat[offset++] = DWFMT_monthshortname;
            else if (numInSection == 4)
                encodedFormat[offset++] = DWFMT_monthlongname;
            else
                bValid = false;
            }
        else if(currChar == "y" || currChar == "Y")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the y's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "Y"; index++, numInSection++)
                ;
            if (numInSection == 2)
                encodedFormat[offset++] = DWFMT_2digityear;
            else if (numInSection == 4)
                encodedFormat[offset++] = DWFMT_4digityear;
            else
                bValid = false;
            }
        else if(currChar == "h" || currChar == "H")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            bGotHour = true;
            // accumulate all the h's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "H"; index++, numInSection++)
                ;
            if (numInSection == 1)
                encodedFormat[offset++] = DWFMT_hournz;
            else if (numInSection == 2)
                encodedFormat[offset++] = DWFMT_hourz;
            else
                bValid = false;
            }
        else if(currChar == "m" || currChar == "M")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the m's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "M"; index++, numInSection++)
                ;
            if (numInSection == 1)
                encodedFormat[offset++] = DWFMT_minnz;
            else if (numInSection == 2)
                encodedFormat[offset++] = DWFMT_minz;
            else
                bValid = false;
            }
        else if(currChar == "s" || currChar == "S")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the s's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "S"; index++, numInSection++)
                ;
            if (numInSection == 1)
                encodedFormat[offset++] = DWFMT_secnz;
            else if (numInSection == 2)
                encodedFormat[offset++] = DWFMT_secz;
            else
                bValid = false;
            }
        else if(currChar == "f" || currChar == "F")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            // accumulate all the f's
            for (numInSection = 1; inString.charAt(index).toUpperCase() == "F"; index++, numInSection++)
                ;
            if (numInSection <= 6)
                {
                encodedFormat[offset++] = DWFMT_msec;
                encodedFormat[offset++] = numInSection;
                }
            else
                bValid = false;
            }
        else if(currChar == "a" ||
                    currChar == "A" ||
                    currChar == "p" ||
                    currChar == "P")
            {
            if (accum != "")
                encodedFormat[offset++] = accum;
            accum = "";
            index++;
            this.b24hr = false;
            nextChar = inString.charAt(index);
            if (nextChar.toUpperCase() == "M")
                {
                index = index + 4;
                if (currChar == "A" || currChar == "P")
                    encodedFormat[offset++] = DWFMT_ampmCaps;
                else
                    encodedFormat[offset++] = DWFMT_ampmNCaps;
                }
            else
                {
                index = index + 2;
                if (currChar == "A" || currChar == "P")
                    encodedFormat[offset++] = DWFMT_apCaps;
                else
                    encodedFormat[offset++] = DWFMT_apNCaps;
                }
            }
        else if(currChar == "\\")
            {
            index++;
            accum += inString.charAt(index++);
            }
        else if(currChar == "'")
            {
            index++;
            while (index < strLen)
                {
                currChar = inString.charAt(index);
                if (currChar == "'")
                    break;
                accum += currChar;
                index++;
                }
            // check if we fell off end before finding closing quotes
            if (index == strLen)
                bValid = false;

            index++; // skip trailing '
            }
        else
            {
            accum += currChar;
            index++;
            }
        }

    if (accum != "")
        encodedFormat[offset++] = accum;

	if (encodedFormat.length == 0 ) 
		bValid = false;

    this.bValid = bValid;
    this.encodedFormat = encodedFormat;
}

function DW_DateFormatClass(formatString)
{
    var semiOffset = formatString.indexOf(";");
    
    if (semiOffset != -1)
        {
        this.mainFormat = new DW_DateEncodingClass(formatString.substring(0, semiOffset));
        this.nullFormat = new DW_DateEncodingClass(formatString.substring(semiOffset+1, formatString.length));

        this.bValid = this.mainFormat.bValid && this.nullFormat.bValid;
        }
    else
        {
        this.mainFormat = new DW_DateEncodingClass(formatString);
        this.nullFormat = null;
        this.bValid = this.mainFormat.bValid;
        }
}

function DW_FormatDate(formatString, value, control, bEdit)
{
    var dateFormat = new DW_DateFormatClass(formatString);
    var result = "";
    var givenDate = null;
    var format;
	
	if (bEdit == null)
		bEdit = false;
	
    if (value != null)
        {
        if (typeof(value) == "string")
			{
			
				givenDate = DW_DatetimeParse(value);
				if ( givenDate == null )
					{
						givenDate = DW_TimeParse(value);
					}
	         }   
        else
            givenDate = value;
        }

	if (!dateFormat.bValid)
		{
		if ( value == null )
			result = "";
		else if ( givenDate.toString == DW_DatetimeToString )
			dateFormat = new DW_DateFormatClass( "[SHORTDATE] [TIME]" );
		else if ( givenDate.toString == DW_DateToString )
			dateFormat = new DW_DateFormatClass( "[SHORTDATE]" );
		else if ( givenDate.toString == DW_TimeToString )
			dateFormat = new DW_DateFormatClass( "[TIME]" );
		}

    if (dateFormat.bValid)
        {
        if (value == null && dateFormat.nullFormat != null)
            format = dateFormat.nullFormat;
        else
            format = dateFormat.mainFormat;
	        
        var index;
        var encodedFormat = format.encodedFormat;
        var action;
        var ampm = (value == null || givenDate.hour < 12) ? 1 : 0;
        var hour, msec;
        
        for (index=0; index < encodedFormat.length ; index++)
            {
            action = encodedFormat[index];
            if (typeof action == "string")
                result += action;
            else if (action == DWFMT_changeToCurrent)
			{
                var dateCurrent = new DW_DatetimeClass2(DW_Today(), DW_Now());
				result = dateCurrent.toString();
			}
            else if (action == DWFMT_dayz || action == DWFMT_daynz)
                {
                if (action == DWFMT_dayz || bEdit)
                    {
                    if (value != null && givenDate.day < 10)
                        result += "0";
                    }
					
                if (value == null)
					{
					if (bEdit)
						result += "00";
					else
						result = "";
					}
				else
					result += givenDate.day;
                }
            else if (action == DWFMT_dayshortname)
                {
                if (value == null)
                    result = "";
                else
                    result += DW_shortDayNames[DW_dayOfWeek (givenDate.year + 1900, givenDate.month + 1, givenDate.day)];
                }
            else if (action == DWFMT_daylongname)
                {
                if (value == null)
                    result = "";
                else
                    result += DW_longDayNames[DW_dayOfWeek (givenDate.year + 1900, givenDate.month + 1, givenDate.day)];
                }
            else if (action == DWFMT_monthz || action == DWFMT_monthnz)
                {
                if (action == DWFMT_monthz || bEdit)
                    {
                    if (value != null && (givenDate.month + 1) < 10)
                        result += "0";
                    }
                if (value == null)
					{
					if (bEdit)
						result += "00";
					else
						result = "";
					}
				else
					result += (givenDate.month + 1);
                }
            else if (action == DWFMT_monthshortname)
                {
                if (value == null)
                    result = "";
                else
                    result += DW_shortMonthNames[givenDate.month];
                }
            else if (action == DWFMT_monthlongname)
                {
                if (value == null)
                    result = "";
                else
                    result += DW_longMonthNames[givenDate.month];
                }
            else if (action == DWFMT_2digityear)
                {
                if (value == null)
					{
					if (bEdit)
						result += "00";
					else
						result = "";
					}
                else
                    {
                    var tempStr = (givenDate.year + 1900).toString();
                    var startPos = tempStr.length - 2;
                    result += tempStr.substring(startPos, startPos + 2);
                    }
                }
            else if (action == DWFMT_4digityear)
                {
                if (value == null)
					{
					if (bEdit)
						result += "0000";
					else
						result = "";
					}
                else
                    result += (givenDate.year + 1900).toString();
                }
            else if (action == DWFMT_hourz || action == DWFMT_hournz)
                {
                if ( value == null )
                    hour = 0;
                else
                    hour = givenDate.hour;
				
                if (! format.b24hr && hour > 12)
                    hour -= 12;
                    
                if (action == DWFMT_hourz || bEdit)
                    {
                    if (value != null && hour < 10)
                        result += "0";
                    }
					
                if (value == null)
					{
					if (bEdit)
						result += "00";
					else
						result = "";
					}
				else				
					result += hour;
                }
            else if (action == DWFMT_minz || action == DWFMT_minnz)
                {
                if (action == DWFMT_minz || bEdit)
                    {
                    if (value != null && givenDate.min < 10)
                        result += "0";
                    }
                if (value == null)
					{
					if (bEdit)
						result += "00";
					else
						result = "";
					}
				else				
					result += givenDate.min;
                }
            else if (action == DWFMT_secz || action == DWFMT_secnz)
                {
                if (action == DWFMT_secz || bEdit)
                    {
                    if (value != null && givenDate.sec < 10)
                        result += "0";
                    }
                if (value == null)
					{
					if (bEdit)
						result += "00";
					else
						result = "";
					}
				else				
					result += givenDate.sec;
                }
            else if (action == DWFMT_msec)
                {
                index++;
                var numMsecDigits = encodedFormat[index];
                if (value == null && bEdit)
					{
					for (var j=0; j<numMsecDigits; j++)
                       	result += "0";
					}
                else
                    {
                    var tempStr = "000000" + givenDate.msec;
                    var valueStart = tempStr.length - 6;
                    
                    result += tempStr.substring(valueStart, valueStart + numMsecDigits);
                    }
                }
            else if (action == DWFMT_apCaps)
                {
                if (value == null)
                    result = "";
                else
                    result += ampm ? "A" : "P";
                }
            else if (action == DWFMT_apNCaps)
                {
                if (value == null)
                    result = "";
                else
                    result += ampm ? "a" : "p";
                }
            else if (action == DWFMT_ampmCaps)
                {
                if (value == null)
                    result = "";
                else
                    result += ampm ? "AM" : "PM";
                }
            else if (action == DWFMT_ampmNCaps)
                {
                if (value == null)
                    result = "";
                else
                    result += ampm ? "am" : "pm";
                }
            }
        }

	if (this.bStylePositioning && format && format.bValid)  
        if ( format.color == "" || typeof format.color == "string")
            control.style.color = format.color;
        else
            control.style.color = convertToRGB( format.color );

    return result;
}

function DW_FloatParse(inString)
{
    var result = new DW_NumberClass();

    if (DW_parseNumberStringAgainstMask(inString, result, true))
    {
        return result.number;
    }
    else
        return null;
}

function DW_IntParse(inString)
{
    var result = new DW_NumberClass();
    
    if (DW_parseNumberStringAgainstMask(inString, result, false))
    {
        return result.number;
    }
    else
        return null;
}

function DW_parseNumberStringAgainstMask(inString, outNumber, bFloat)
{
	var Mask = gMask;
    
	var format;
	var	bNegative = false;
	
	// try special case first
	if (Mask == "") // unformatted data
	{
		var n = 0;
		if (bFloat)
			{
			//Acréscimo para correção do Bug da Vírgula!
			//AUTOR: Daniel Gomes Silveira
			noComma = inString;
			
			//Tira o separador de milhar
			var reg = new RegExp("[" + DW_thousandsChar + "]", "g");
			var noComma = noComma.replace(reg, "");

			//Muda o separador decimal por ponto
			var reg = new RegExp("[" + DW_decimalChar + "]", "g");
			var noComma = noComma.replace(reg, ".");			
			
			n = parseFloat(noComma);
			}
		else
			n = parseInt(inString);
		
		if (isNaN(n))
			return false;

		if(outNumber != null)
			outNumber.number = n;
		
		return true;
	}		
	
	if (Mask.toLowerCase() == "[currency]")
	{
		bFloat = true; 
		if (inString.charAt(0) == DW_negCurrencyFormat.charAt(0))
		{
			format = new DW_NumberEncodingClass(DW_negCurrencyFormat, DWFMT_section_positive);
			bNegative = true;
		}
		else
			format = new DW_NumberEncodingClass(DW_posCurrencyFormat, DWFMT_section_positive);
	}
	else
    {
        var semiOffset;

        semiOffset = Mask.indexOf(";");
        if (semiOffset != -1)
            {
            format = new DW_NumberEncodingClass(Mask.substring(0, semiOffset), DWFMT_section_positive);
            Mask = Mask.substring(0, semiOffset);
            }
        else
           format = new DW_NumberEncodingClass(Mask, DWFMT_section_positive);
    }
    
    if(!format.bValid)
		return false;
	
	
	// Create a new number class
	var nm = new DW_NumberClass();

	var STATESECTION = 0;
	var STATENUMBER = 1;
	var STATEDECIMAL = 2;
	var STATEASIS = 3;

	var currChar;
	var charIndex = 0;
	var state;
	var prvState;
	var isInteger = false;

	var key;			// To hold number and strings
	var nVal;			// To store integer value
	
    var index = 0;
    var encodedFormat = format.encodedFormat;
    var action;
    
	while (charIndex < inString.length && index < encodedFormat.length)
	{

		// Initialize
		state = prvState = STATESECTION;

		key = "";
		nVal = 0;

		// Extract one token from inString
		do{
			currChar = inString.charAt (charIndex);
			if (state == STATESECTION)
			{
				if (currChar == DW_decimalChar)
					state = STATEDECIMAL;
				
				else if (allowInString(currChar, "1234567890+-"))
					state = STATENUMBER;
				
				else
					state = STATEASIS;
			}
			else if (state == STATEDECIMAL)
			{
				if(bFloat != true)
					isInteger = true;

				key += currChar;
				charIndex++;

				state = STATESECTION;       // Change state for next char
				prvState = STATEDECIMAL;
			}
			else if(state == STATENUMBER)
			{
				if((key == "") && ((currChar == '-') || (currChar == '+')))
				{
					if (currChar == '-')
						bNegative = true;

					charIndex++;
				}
				else
				{
					key += currChar;
					charIndex++;
					
					// Skip comma character
					if(inString.charAt (charIndex) == DW_thousandsChar)
					{
						charIndex++;
						
						// Next character should be a digit
						if(!DW_parseIsDigit(inString.charAt (charIndex)))
							return false;
					}
					
					if (!DW_parseIsDigit(inString.charAt (charIndex)))
					{
						state = STATESECTION;       // Change state for next char
						prvState = STATENUMBER;
						nVal = key - 0;
					}
				}
			}
			else if (state == STATEASIS)
			{
				key += currChar;
				charIndex++;

				if (allowInString (inString.charAt (charIndex), "1234567890+-" + DW_decimalChar))
				{
					state = STATESECTION;       // Change state for next char
					prvState = STATEASIS;
				}
			}
			else
			{
				return false;        // Unspecified error
			}

		}while(charIndex < inString.length && state != STATESECTION)


		// Now extract one token from encode string
		
		action = 0;

		if( index < encodedFormat.length)
		{
            action = encodedFormat[index];
			index++;
		}
		
		if ((typeof action == "string") && (prvState != STATEASIS))
		{
			// Skip ASIS Format
            action = encodedFormat[index];
			index++;
		}
		
		if ((action == DWFMT_integer || action == DWFMT_integer_comma) && (prvState == STATEDECIMAL))
		{
			// Skip Integer Action
            action = encodedFormat[index+2];
			index+=3;

			if (action != DWFMT_decimal)
				return false;
		}

        if (typeof action == "string")
		{
			if (key != action)
				return false;
		}
		else if(action == DWFMT_decimal)
		{
            if (key != DW_decimalChar)
				return false;
		}
		else if(action == DWFMT_integer || action == DWFMT_integer_comma)
		{
            numReq = encodedFormat[index];	index ++;
            numOpt = encodedFormat[index];	index ++;
            
			if (!format.bMult100 && (key.length > numReq + numOpt)) 
				return false;

			nm.number = nVal;
		}
        else if (action == DWFMT_fraction)
		{
            numReq = encodedFormat[index];	index ++;
            numOpt = encodedFormat[index];	index ++;

            if (key.length > numReq + numOpt)
				return false;
				
			var tString = "." + key;
			
			nm.number += tString;
		}
	}

	if (bNegative)
		nm.number *= -1;

 	if(nm.number == 0)
		nm.number = "0.0"

	if (format.bMult100) 
		nm.number = nm.number/100.0;

	if (isInteger)
		nm.number = Math.floor(nm.number);

	if(outNumber != null)
		outNumber.number = nm.number;

	return true;
}


//
// Number formatting code
//
var DWFMT_integer_comma = 1;
var DWFMT_integer = 2;
var DWFMT_fraction = 3;
var DWFMT_decimal = 4;
var DWFMT_exp_integer_comma = 5;
var DWFMT_exp_integer = 6;
var DWFMT_exp_fraction = 7;
var DWFMT_exp_exp = 8;
var DWFMT_exp_sign = 9;
var DWFMT_exp_sign_opt = 10;
var DWFMT_general = 11;
var DWFMT_asis_digit = 12;

var DWFMT_type_normal = 1;
var DWFMT_type_exp = 2;
var DWFMT_type_percent = 3;
var DWFMT_type_asis = 4;

var DWFMT_section_positive = 0;
var DWFMT_section_negative = 1;
var DWFMT_section_zero = 2;
var DWFMT_section_null = 3;

function DW_NumberEncodingClass(inString,section)
{
var STATE_START = 1;
var STATE_LEFTDEC = 2;
var STATE_RIGHTDEC = 3;
var STATE_TESTASIS = 4;
var STATE_ASIS = 5;

    var index;
    var currState = STATE_START;
    var currChar;
    var encodedFormat = new Array();
    var accum = "";
    var numInSection;
    var offset = 0;
    var bValid = true;
    // state flags
    var bOnLeft = true;
    var bDidLeft = false;
    var bOnExp = false;
    var bCommas = false;
    var reqDigits = 0;
    var optDigits = 0;
    var totDigits = 0;
    var numDecPlaces = 0;
    
    // misc variable
    var nextChar;
    var nextNextChar;
    
    this.encodedFormat = encodedFormat;
    this.color = "";
    this.bMult100 = false;
    this.maskType = DWFMT_type_normal;
    this.bGeneral = false;
    
    var strLen = inString.length;
    for (index=0; index <= strLen && bValid; )
        {
        if (index < strLen)
            currChar = inString.charAt(index);
        else
            currChar = "";
        if (currState == STATE_START)
            {
            // handle keywords
            if (currChar == "[")
                {
                if (accum != "")
                    encodedFormat[offset++] = accum;
                accum = "";
                index++;
                for (; inString.charAt(index) != "]"; index++)
                    accum += inString.charAt(index);
                index++; // skip ]
                var inlineEncoding = null;
                var keyword = accum.toUpperCase();
                if (keyword == "GENERAL")
                    {
                    encodedFormat[offset++] = DWFMT_general;
                    this.bGeneral = true;
                    }
                else if (keyword == "CURRENCY")
                    {
                    if (section == DWFMT_section_positive || section == DWFMT_section_null)
                        inlineEncoding = new DW_NumberEncodingClass(DW_posCurrencyFormat, section);
                    else if(section == DWFMT_section_negative)
                        inlineEncoding = new DW_NumberEncodingClass(DW_negCurrencyFormat, section);
                    else
                        bValid = false;
                    }
                else
                    {
					if (!parseInt(accum)) 
						this.color = accum.toLowerCase();
					else
						this.color = eval(accum);
                    this.keyword = accum;
                    }
                // if we build another format, inline it into current one
                if (inlineEncoding != null && inlineEncoding.bValid)
                    {
                    var innerFormat = inlineEncoding.encodedFormat;
                    for (var j=0; j<innerFormat.length; j++)
                        encodedFormat[offset++] = innerFormat[j];
                    }
                accum = "";
                }
            else if (currChar == "#")
                {
                if (accum != "")
                    encodedFormat[offset++] = accum;
                accum = "";
                if (bOnLeft && bDidLeft)
                    currState = STATE_TESTASIS;
                else if(bOnLeft)
                    currState = STATE_LEFTDEC;
                else
                    currState = STATE_RIGHTDEC;
                // reset accumulators
                reqDigits = 0;
                totDigits = 0;
                optDigits = 0;
                bCommas = false;
                }
            else if (currChar == "0")
                {
                if (accum != "")
                    encodedFormat[offset++] = accum;
                accum = "";
                if (bOnLeft && bDidLeft)
                    currState = STATE_TESTASIS;
                else if(bOnLeft)
                    currState = STATE_LEFTDEC;
                else
                    currState = STATE_RIGHTDEC;
                // reset accumulators
                reqDigits = 0;
                totDigits = 0;
                optDigits = 0;
                bCommas = false;
                }
            else if (currChar == ".")
                {
                if (accum != "")
                    encodedFormat[offset++] = accum;
                accum = "";
                index++;
                if (bOnLeft)
                    {
                    encodedFormat[offset++] = DWFMT_decimal;
                    bOnLeft = false;
                    }
                // we want only 1 period char!
                else
                    bValid = false;
                }
            else if (currChar == "e" || currChar == "E")
                {
                accum += currChar;
                index++;
                nextChar = inString.charAt(index);
                nextNextChar = inString.charAt(index+1);
                if ((nextChar == "-" || nextChar == "+") &&
                     (nextNextChar == "#" || nextNextChar == "0"))
                    {
                    bOnExp = true;
                    bOnLeft = false;
                    if (nextChar == "+")
                        encodedFormat[offset++] = DWFMT_exp_sign;
                    else
                        encodedFormat[offset++] = DWFMT_exp_sign_opt;
                    // correct prior encodings
                    for (i=0; i < encodedFormat.length;i++)
                        {
                        if (typeof encodedFormat[i] == "number")
                            {
                            var lastFormat = encodedFormat[i];
                            if (lastFormat == DWFMT_integer_comma)
                                {
                                encodedFormat[i] = DWFMT_exp_integer_comma;
                                i += 2;
                                }
                            else if (lastFormat == DWFMT_integer)
                                {
                                encodedFormat[i] = DWFMT_exp_integer;
                                i += 2;
                                }
                            else if (lastFormat == DWFMT_fraction)
                                {
                                encodedFormat[i] = DWFMT_exp_fraction;
                                i += 2;
                                }
                            }
                        }
                    }
                if (this.maskType == DWFMT_type_normal)
                    this.maskType = DWFMT_type_exp;
                else
                    bValid = false;
                }
            else if (currChar == "-")
                {
                // we will allow it to be the first char of the negative section
                if (section == DWFMT_section_negative && 
                        offset == 0 && accum == "")
                    {
                    accum += currChar;
                    index++;
                    }
                else
                    currState = STATE_TESTASIS;
                }
            else if (currChar == "%")
                {
                accum += currChar;
                index++;
                if (this.maskType == DWFMT_type_normal)
                    {
                    this.maskType = DWFMT_type_percent;
                    this.bMult100 = true;
                    }
                else
                    bValid = false;
                }
            else if (currChar == "\\")
                {
                index++;
                accum += inString.charAt(index++);
                }
            else if (currChar == "'")
                {
                index++;
                while (index < strLen)
                    {
                    currChar = inString.charAt(index);
                    if (currChar == "'")
                        break;
                    accum += currChar;
                    index++;
                    }
                // check if we fell off end before finding closing quotes
                if (index == strLen)
                    bValid = false;

                index++; // skip trailing '
                }
            else
                {
                accum += currChar;
                index++;
                }
            }
        else if (currState == STATE_LEFTDEC)
            {
            nextChar = inString.charAt(index+1);
            if (currChar == "#")
                {
                optDigits++;
                if(!bOnExp)
                    totDigits++;
                index++;
                }
            else if(currChar == "0")
                {
                reqDigits++;
                if(!bOnExp)
                    totDigits++;
                index++;
                }
            else if(currChar == "," &&
                    (nextChar == "#" || nextChar == "0"))
                {
                bCommas = true;
                index++;
                }
            else
                {
                if (bCommas)
                    encodedFormat[offset++] = DWFMT_integer_comma;
                else
                    encodedFormat[offset++] = DWFMT_integer;
                encodedFormat[offset++] = reqDigits;
                encodedFormat[offset++] = optDigits;
                currState = STATE_START;
                }
            }
        else if (currState == STATE_RIGHTDEC)
            {
            if (currChar == "#")
                {
                numDecPlaces++;
                optDigits++;
                if(!bOnExp)
                    totDigits++;
                index++;
                }
            else if(currChar == "0")
                {
                numDecPlaces++;
                reqDigits++;
                if(!bOnExp)
                    totDigits++;
                index++;
                }
            else
                {
                if (bOnExp)
                    encodedFormat[offset++] = DWFMT_exp_exp;
                else
                    encodedFormat[offset++] = DWFMT_fraction;
                encodedFormat[offset++] = reqDigits;
                encodedFormat[offset++] = optDigits;
                currState = STATE_START;
                }
            }
        else if (currState == STATE_TESTASIS)
            {
            // convert to asis form
            for (i=0; i < encodedFormat.length && bValid;i++)
                {
                if (typeof encodedFormat[i] == "number")
                    {
                    if (encodedFormat[i] == DWFMT_integer)
                        {
                        encodedFormat[i] = DWFMT_asis_digit;
                        i += 2;
                        }
                    else
                        bValid = false;
                    }
                }
            this.maskType = DWFMT_type_asis;
            currState = STATE_ASIS;
            }
        else if (currState == STATE_ASIS)
            {
            if (currChar == "#" || currChar == "0")
                {
                totDigits++;
                if (accum != "")
                    encodedFormat[offset++] = accum;
                accum = "";
                encodedFormat[offset++] = DWFMT_asis_digit;
                encodedFormat[offset++] = 1; // 1 required char
                encodedFormat[offset++] = 0; // no optional
                }
            else
                accum += currChar;
            index++;
            }
        }

    if (accum != "")
        encodedFormat[offset++] = accum;

    this.totalDigits = totDigits;

	if (encodedFormat.length == 0 ) 
		bValid = false;

    this.bValid = bValid;
    this.numDecPlaces = numDecPlaces;
}

function DW_NumberClass(number)
{
    if (arguments.length == 0)
        number = 0.0;
        
    this.number = number;
}

function DW_NumberFormatClass(formatString)
{
    this.negativeFormat = null;
    this.zeroFormat = null;
    this.nullFormat = null;

    // try special case first
    if (formatString.toLowerCase() == "[currency]")
        {
        this.positiveFormat = new DW_NumberEncodingClass(DW_posCurrencyFormat, DWFMT_section_positive);
        this.negativeFormat = new DW_NumberEncodingClass(DW_negCurrencyFormat, DWFMT_section_negative);
        this.bValid = this.positiveFormat.bValid && this.negativeFormat.bValid;
        }
    else
        {
        var bValid = true;
        var semiOffset;

        semiOffset = formatString.indexOf(";");
        if (semiOffset != -1)
            {
            this.positiveFormat = new DW_NumberEncodingClass(formatString.substring(0, semiOffset), DWFMT_section_positive);
            formatString = formatString.substring(semiOffset+1, formatString.length);
            semiOffset = formatString.indexOf(";");
            if (semiOffset != -1)
                {
                this.negativeFormat = new DW_NumberEncodingClass(formatString.substring(0, semiOffset), DWFMT_section_negative);
                formatString = formatString.substring(semiOffset+1, formatString.length);
                semiOffset = formatString.indexOf(";");
                if (semiOffset != -1)
                    {
                    this.zeroFormat = new DW_NumberEncodingClass(formatString.substring(0, semiOffset), DWFMT_section_zero);
                    this.nullFormat = new DW_NumberEncodingClass(formatString.substring(semiOffset+1, formatString.length), DWFMT_section_null);
                    bValid = bValid && this.nullFormat.bValid;
                    }
                else
                    this.zeroFormat = new DW_NumberEncodingClass(formatString, DWFMT_section_zero);
                bValid = bValid && this.zeroFormat.bValid;
                }
            else
                this.negativeFormat = new DW_NumberEncodingClass(formatString, DWFMT_section_negative);

            bValid = bValid && this.negativeFormat.bValid
            }
        else
            this.positiveFormat = new DW_NumberEncodingClass(formatString, DWFMT_section_positive);
        this.bValid = bValid && this.positiveFormat.bValid;
        }
}

function DW_FormatNumber(formatString, value, control)
{
    var numberFormat = new DW_NumberFormatClass(formatString);
    var result = "";
    var strValue, dotOffset, exponentOffset;
    var bRequireNegative = false;
    var bNegative = false;
    var format;
    
    if (numberFormat.bValid)
        {

        if (value == null)
            {
            if (numberFormat.nullFormat != null)
                format = numberFormat.nullFormat;
            else
                format = null;
            }
        else if (value < 0)
            {
            bNegative = true;
            if (numberFormat.negativeFormat != null)
                format = numberFormat.negativeFormat;
            else
                {
                format = numberFormat.positiveFormat;
                bRequireNegative = true; // mask will not contain negative
                }
            }
        else if (value > 0)
            format = numberFormat.positiveFormat;
        else // == 0
            {
            if (numberFormat.zeroFormat != null)
                format = numberFormat.zeroFormat;
            else
                format = numberFormat.positiveFormat;
            }

        // if not format, we just return ""
        if (format != null)
            {
            var index;
            var encodedFormat = format.encodedFormat;
            var action;
            var numReq, numOpt, numDigitsLeft, numDigitsRight, i, commaDigit;
            var accum;
            var asIsOffset = 0;
            
            if (format.bMult100 && value != null)
                value *= 100;

            // round to proper number of decimal places
            if (value != null && ! format.bGeneral)
                value = DW_Round (value, format.numDecPlaces);

            // convert the value to a string
            if (value != null)
                strValue = value.toString();
            else
                strValue = "";

            // strip off leading minus
            if (strValue.charAt(0) == "-")
                strValue = strValue.substring(1,strValue.length);
                
            dotOffset = strValue.indexOf(".");
            if (dotOffset == -1)
                {
                numDigitsLeft = strValue.length;
                numDigitsRight = 0;
                }
            else
                {
                numDigitsLeft = dotOffset;
                numDigitsRight = strValue.length - dotOffset - 1;
                }
            
            for (index=0; index < encodedFormat.length ; index++)
                {
                action = encodedFormat[index];
                if (typeof action == "string")
                    result += action;
                else if (action == DWFMT_integer_comma)
                    {
                    numReq = encodedFormat[index + 1];
                    numOpt = encodedFormat[index + 2];
                    index += 2;
                    if (bRequireNegative)
                        result += "-";

                    if (numDigitsLeft < numReq)
                        {
                        commaDigit = numReq - 1;
                        for (i=0;i< numReq-numDigitsLeft;i++,commaDigit--)
                            {
                            result += "0";
                            if (commaDigit % 3 == 0 && commaDigit != 0)
                                result += DW_thousandsChar;
                            }
                        }
                    else
                        commaDigit = numDigitsLeft - 1;
                                                    
                    for (i=0; i < numDigitsLeft; i++,commaDigit--)
                        {
                        result += strValue.charAt(i);
                        if (commaDigit % 3 == 0 && commaDigit != 0)
                            result += DW_thousandsChar;
                        }
                        
                    }
                else if (action == DWFMT_integer)
                    {
                    numReq = encodedFormat[index + 1];
                    numOpt = encodedFormat[index + 2];
                    index += 2;
                    if (numDigitsLeft < numReq)
                        {
                        for (i=0;i< numReq-numDigitsLeft;i++)
                            result += "0";
                        }
                    for (i=0; i < numDigitsLeft; i++)
                        result += strValue.charAt(i);
                    }
                else if (action == DWFMT_fraction)
                    {
                    numReq = encodedFormat[index + 1];
                    numOpt = encodedFormat[index + 2];
                    index += 2;
                    for (i=0; i < numDigitsRight; i++)
                        result += strValue.charAt(dotOffset + 1 + i);
                    if (numDigitsRight < numReq)
                        {
                        for (i=0; i < numReq - numDigitsRight; i++)
                            result += "0";
                        }
                    }
                else if (action == DWFMT_asis_digit)
                    {
                    numReq = encodedFormat[index + 1];
                    numReq += encodedFormat[index + 2];
                    index += 2;
                    for (i=0; i< numReq; i++)
                        {
                        result += strValue.charAt (asIsOffset);
                        asIsOffset++;
                        }
                    }
                else if (action == DWFMT_decimal)
                    {
                    result += DW_decimalChar;
                    }
                else if (action == DWFMT_general)
                    {
                    if (value != null)
                        result += value.toString();
                    }

                // won't deal with exponents for now
                else if (action == DWFMT_exp_integer_comma)
                    {
                    }
                else if (action == DWFMT_exp_integer)
                    {
                    }
                else if (action == DWFMT_exp_fraction)
                    {
                    }
                else if (action == DWFMT_exp_exp)
                    {
                    }
                else if (action == DWFMT_exp_sign)
                    {
                    }
                else if (action == DWFMT_exp_sign_opt)
                    {
                    }
                }
            }
        }
    else if ( value != null )
		{
		// Simulating a [general] format.
        result = value.toString();
		
		//Acréscimo para correção do Bug da Vírgula!
		//AUTOR: Daniel Gomes Silveira
		result = result.replace ( ".", DW_decimalChar );						
		}
	else
		result = "";

	if (this.bStylePositioning && format && format.bValid)  
        if ( format.color == "" || typeof format.color == "string" )
            control.style.color = format.color;
        else
            control.style.color = convertToRGB( format.color );

    return result;
}

// between is inclusive
function DW_Between(val, test1, test2)
{
    if (val == null || test1 == null || test2 == null)
        return false;
        
    if (test1 <= val && val <= test2)
        return true;
    else
        return false;
}

function DW_BetweenByFunc(val, test1, test2, func)
{
    return func(test1, val) >= 0 && func(val, test2) <= 0;
}

function DW_In(testValue)
{
    var bResult = false;

    for (var i=1; i < arguments.length; i++)
        {
        if (arguments[i] == testValue)
            {
            bResult = true;
            break;
            }
        }
    return bResult;
}

function DW_InByFunc(testValue, func)
{
    var bResult = false;

    for (var i=2; i < arguments.length; i++)
        {
        if (func(arguments[i],testValue) == 0)
            {
            bResult = true;
            break;
            }
        }
    return bResult;
}

//
// Date management code
//

// Added to determine if dates are being processed in client side JavaScript.
bDateTimeProcessingEnabled = true;

var DW_dayTable = new Array();
DW_dayTable[0] = new Array(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
DW_dayTable[1] = new Array(0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

var DW_cumDayTable = new Array();
DW_cumDayTable[0] = new Array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365);
DW_cumDayTable[1] = new Array(0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366);

function DW_daysInCentury(year)
{
    return ((((year) / 100) % 4 ? 24 : 25) + 36500);
}

function DW_isLeap(year)
{
    return ((year%4 == 0 && year%100 != 0) || year%400 == 0);
}

function DW_dayOfYear(year, month, day)
{
	var i, aleap;

	aleap = DW_isLeap(year) ? 1 : 0;
	for (i = 1; i < month; i++)
		day += DW_dayTable[aleap][i];
	return day;                   // Offset from 0
}

function DW_dayOfCentury(year, month, day)
{
	var days, leaps;
	var years_in_century;

	/* Get number of years in the century. */
	years_in_century = Math.floor(year % 100);

	/* Get the number of days in year */
	days = DW_dayOfYear(year, month, day);;

	/* Add number of days in previous years */
	if (years_in_century != 0)
		{
		leaps = Math.floor((years_in_century - 1) / 4);  /* num of inclusive leap years */
		leaps += (Math.floor(year / 100) % 4 ? 0 : 1); /* + 1 every 4 centuries */
		days += leaps * 366;
		days += (years_in_century - leaps) * 365;
		}
	return days;
}

function DW_daysDiff(year1, mon1, day1, year2, mon2, day2)
{
	var days = 0;
	var no_centuries;
	var temp;
	var sign = 1;
	var i;

	// Swap dates if date1 < date2
	if ( year1 < year2 || 
			(year1 == year2 && (mon1 < mon2 || 
									(mon1 == mon2 && day1 < day2) ) ) )
		{
		temp = year1; year1 = year2; year2 = temp;
		temp = mon1;  mon1 = mon2;   mon2 = temp;
		temp = day1;  day1 = day2;   day2 = temp;
		sign = -1;
		}

	// Calculate difference in dates.
	no_centuries = Math.floor(year1 / 100) - Math.floor(year2 / 100);
	for (i = 0; i < no_centuries; i++)
		days += DW_daysInCentury (year2 + i * 100);
	days += DW_dayOfCentury (year1,mon1,day1) - DW_dayOfCentury (year2,mon2,day2); 

	// Set sign of days
	days *= sign;

	return (days);
}

// Notes   :  Jan 1, 1899 was a Sunday.
function DW_dayOfWeek(year, month, day)
{
	var days_from_1899;
	var weekday;

	// Get number of days since 01/01/1899.
	days_from_1899 = DW_daysDiff (year, month, day, 1899, 1, 1);

	// Mod by 7 to get day of week.
   	weekday = days_from_1899 % 7;
	// CR 184356 - make sure we deal properly with dates less than 01/01/1899
	if (weekday < 0)
        weekday += 7;
        
	return (weekday);
}

function DW_daysInYear(year)
{
	return DW_isLeap(year) ? 366 : 365;
}

function DW_DateToString()
{
    return (this.year + 1900) + "/" + (this.month + 1)  + "/" + this.day;
}

function DW_DatetimeToString()
{
    var outStr =  (this.year + 1900) + "-" + (this.month + 1)  + "-"  + this.day  + " " + 
        this.hour + ":" + this.min + ":" + this.sec + ":";
    var tempStr = ""+ this.msec;
    var i = tempStr.length;
   while(i<6)
   {
	outStr += "0";
	i++;
   }

   return outStr + this.msec;
}

function DW_TimeToString(theTime)
{
    var outStr = this.hour + ":" + this.min + ":" + this.sec + ":";
	var inStr = "";
	
    inStr = inStr + this.msec;
    var i = inStr.length;    
    while(i<6) 
    {
     outStr = outStr +"0";
     i++;
    } 

    outStr = outStr+inStr;
    return outStr;  
}


function DW_DateClass(year, month, day)
{
    if (arguments.length == 0)
        {
        year = 0;
        month = 0;
        day = 0;
        }
        
    this.year = year;
    this.month = month;
    this.day = day;
    this.hour = 0;
    this.min = 0;
    this.sec = 0;
    this.msec = 0;

    this.toString = DW_DateToString;
}

function DW_TimeClass(hour, min, sec, msec)
{
    if (arguments.length == 0)
        {
        hour = 0;
        min = 0;
        sec = 0;
        msec = 0;
        }

    this.hour = hour;
    this.min = min;
    this.sec = sec;
    this.msec = msec;
    this.year = 0;
    this.month = 0;
    this.day = 0;

    this.toString = DW_TimeToString;
}

function DW_DatetimeClass(year,month,day,hour,min,sec,msec)
{
	if (arguments.length == 0)
		{
		year = 0;
        month = 0;
        day = 0;		
        hour = 0;
        min = 0;
        sec = 0;
        msec = 0;
        }
        
     this.year = year;
     this.month = month;
     this.day = day;
     this.hour = hour;
     this.min = min;
     this.sec = sec;
     this.msec = msec;
     
     this.toString = DW_DatetimeToString;
}

function DW_DatetimeClass2(date, time)
{
     this.year = date.year;
     this.month = date.month;
     this.day = date.day;
     this.hour = time.hour;
     this.min = time.min;
     this.sec = time.sec;
     this.msec = time.msec;
     
     this.toString = DW_DatetimeToString;
}

// These constants are used by the date parsing code
var DW_PARSEDT_DATE = 0;
var DW_PARSEDT_TIME = 1;
var DW_PARSEDT_DATETIME = 2;

// these three are dependent on localization settings
//var DW_PARSEDT_monseq = 0;
//var DW_PARSEDT_dayseq = 1;
//var DW_PARSEDT_yearseq = 2;
var DW_PARSEDT_hourseq = 3;
var DW_PARSEDT_minseq = 4;
var DW_PARSEDT_secseq = 5;
var DW_PARSEDT_msecseq = 6;

function DW_monthSearch(inMonthName)
{
    var index;
    var inMonthLC = inMonthName.toLowerCase();
    
    // check short month names
    for (index=0; index < 12; index++)
        {
        if (DW_shortMonthNames[index].toLowerCase() == inMonthLC)
            return index + 1;
        }

    // check long month names
    for (index=0; index < 12; index++)
        {
        if (DW_longMonthNames[index].toLowerCase() == inMonthLC)
            return index + 1;
        }

   // if we get here, we couldn't find the name
   return -1;
}

// The function validates data against the following masks only.
// yy, yyyy, m, mm, mmm, mmmm, d, dd, h, hh, m, mm, s, ss, f to ffffff, a/p, A/P, am/pm, AM/PM
// Validates standard formats, i.e. [SHORTDATE], [LONGDATE], [TIME], [GENERAL]
// Accepts only the following 6 delimiters as legal separator
// '-', '/', ',', '.', ' ', ':'
// The function does not do any validation against illegal masks

function DW_parseDatetimeStringAgainstMask(inString, outDatetime, parseType, Mask)
{
    // Get encoded format against mask
	var format = new DW_DateEncodingClass(Mask);

    // if invald mask, return false
	if (! format.bValid) return false;

    // Create a new date class
    var dt = new DW_DateClass(1900,1,1); 

	var STATESECTION = 0;
	var STATENUMBER = 1;
	var STATEMONSTRING = 2;
	var STATESEPARATOR = 3;

	var currChar;
	var nextChar; 
	var charIndex = 0;
	var state;

	var key;			// To hold number and strings
	var nVal;			// To store integer value
	
    var index = 0;
    var encodedFormat = format.encodedFormat;
    var action;

	while (charIndex < inString.length && index < encodedFormat.length)
	{
		// Now extract one token from encode string
		
		action = 0;

		if( index < encodedFormat.length)
		{
            action = encodedFormat[index];
			index++;
		}

		// Initialize
		state = STATESECTION;

		key = "";
		nVal = 0;

		// Extract one token from inString
		do{
			
			currChar = inString.charAt (charIndex);
			if (state == STATESECTION)
			{
				if (action == DWFMT_apCaps || action == DWFMT_apNCaps || action == DWFMT_ampmCaps || action == DWFMT_ampmNCaps) 
				{
					if (currChar == 'a' || currChar == 'A')
					{
						if((inString.charAt (charIndex+1) == 'm') || (inString.charAt (charIndex+1) == 'M'))
						{
							key = currChar + inString.charAt (charIndex+1);
							charIndex += 2;
						}
						else
						{
							key = currChar;
							charIndex ++;
						}
					
						state = STATESECTION;

					}
					else if ((currChar == 'p') || (currChar == 'P'))
					{
						if(inString.charAt (charIndex+1) == 'm' || inString.charAt (charIndex+1) == 'M')
						{
							key = currChar + inString.charAt (charIndex+1);
							charIndex += 2;
						}
						else
						{
							key = currChar;
							charIndex ++;
						}
					
						state = STATESECTION;

					}
					else
						return false;
				}

				else if (currChar == '-' ||     // New section
				currChar == '/' ||
					currChar == ',' ||
					currChar == '.' ||
					currChar == ' ' ||
					currChar == ':')
					state = STATESEPARATOR;
				
				else if (DW_parseIsDigit(currChar))
					state = STATENUMBER;
				
				else if (DW_parseIsAlpha(currChar))
					state = STATEMONSTRING;
				
				else
					return false;
			
			}
			
			else if(state == STATENUMBER)
			{
				key += currChar;

				charIndex++;

				// accumulate until next char is not a digit
				if (!DW_parseIsDigit(inString.charAt (charIndex)))
				{
					state = STATESECTION;       // Change state for next char
					
					nVal = key - 0;
				}
			}

			else if (state == STATEMONSTRING)
			{
				key += currChar;
				charIndex++;
				if (!DW_parseIsAlpha(inString.charAt (charIndex)))
				{
					nVal = DW_monthSearch(key);
					if (nVal == -1)
						return false;
					state = STATESECTION;
				}
			}

			else if (state == STATESEPARATOR) 
			{
				key += currChar;  
				charIndex++;
				nextChar = inString.charAt (charIndex);
				if (!(nextChar == '-' ||     // New section
					nextChar == '/' ||
					nextChar == ',' ||
					nextChar == '.' ||
					nextChar == ' ' ||
					nextChar == ':'))
					state = STATESECTION;
			}

			else
			{
				return false;        // Unspecified error
			}

		}while(charIndex < inString.length && state != STATESECTION)


		// If both the tokens are matching - update date class and continue.

        if (typeof action == "string")
		{
			if (key != action)
				return false;
		}
		else if(action == DWFMT_2digityear)
		{
			if(nVal < 0 || key.length != 2)
				return false;
			else if (nVal >= 50)
				nVal += 1900;
			else
				nVal += 2000;

			dt.year = nVal;
		}
        else if (action == DWFMT_4digityear)
		{
			if(nVal < 0 || (key.length != 4 && key.length != 2))
				return false;
			if (key.length == 2)
				if (nVal >= 50) 
					nVal += 1900
				else
					nVal += 2000;

			dt.year = nVal;
		}
        else if (action == DWFMT_monthz || action == DWFMT_monthnz)
		{
			if(nVal < 1 || nVal > 12 || key.length > 2)
				return false;

			dt.month = nVal;
		}
		else if (action == DWFMT_monthshortname)
        {
			if(nVal < 0 || key.length != 3)
				return false;

			dt.month = nVal;
        }
        else if (action == DWFMT_monthlongname)
        {
			if(nVal < 0)
				return false;

			if(key.length == 3 && nVal != 5) // May is only exception
				return false;

			dt.month = nVal;
        }
        else if (action == DWFMT_dayz || action == DWFMT_daynz)
		{
			if(nVal < 1 || nVal > 31 || key.length > 2)
				return false;

			dt.day = nVal;
		}
		//The following masks are invalid input mask
        else if (action == DWFMT_dayshortname || action == DWFMT_daylongname)
        {
			return false;
        }
        else if (action == DWFMT_hourz || action == DWFMT_hournz)
		{
			if(nVal < 0 || nVal > 23 || key.length > 2)
				return false;

			dt.hour = nVal;
		}
        else if (action == DWFMT_minz || action == DWFMT_minnz)
		{
			if(nVal < 0 || nVal > 59 || key.length > 2)
				return false;

			dt.min = nVal;
		}
        else if (action == DWFMT_secz || action == DWFMT_secnz)
		{
			if(nVal < 0 || nVal > 59 || key.length > 2)
				return false;

			dt.sec = nVal;
		}
        else if (action == DWFMT_msec)
		{
			if(nVal < 0 || nVal > 999999)
				return false;

			// Retreive next action
			action = 0;

			if( index < encodedFormat.length)
			{
				action = encodedFormat[index];
				index++;
			}
			else return false;

			if((action > 6) || (key.length != action))
				return false;

            var tempStr = key + "000000";
            dt.msec = tempStr.substring(0, 6) - 0;
		}
        else if (action == DWFMT_apCaps)
        {
			if ((key != "A") && (key != "P"))
				return false;
			if (dt.hour > 12)
				return false;
			
			if (key == "A")
			{
				if (dt.hour == 12)
					return false;
			}
			else 
			{
				if (dt.hour == 0)
					return false;
				else if(dt.hour < 12)
					dt.hour += 12;
			}
        }
        else if (action == DWFMT_apNCaps)
        {
			if ((key != "a") && (key != "p"))
				return false;
			if (dt.hour > 12)
				return false;
			if (key == "a")
			{
				if (dt.hour == 12)
					return false;
			}
			else 
			{
				if (dt.hour == 0)
					return false;
				else if(dt.hour < 12)
					dt.hour += 12;
			}
        }

        else if (action == DWFMT_ampmCaps)
        {
			if ((key != "AM") && (key != "PM"))
				return false;
			if (dt.hour > 12)
				return false;
			if (key == "AM")
			{
				if (dt.hour == 12)
					return false;
			}
			else 
			{
				if (dt.hour == 0)
					return false;
				else if(dt.hour < 12)
					dt.hour += 12;
			}
        }
        else if (action == DWFMT_ampmNCaps)
        {
			if ((key != "am") && (key != "pm"))
				return false;
			if (dt.hour > 12)
				return false;
			if (key == "am")
			{
				if (dt.hour == 12)
					return false;
			}
			else 
			{
				if (dt.hour == 0)
					return false;
				else if(dt.hour < 12)
					dt.hour += 12;
			}
        }
		else return false
	}

	// whether we have reached at the end of both the string
	if (charIndex < inString.length)
		return false;


	// Do additional validation of the day against month and year
	if (parseType != DW_PARSEDT_TIME)
	    {
    		var leapYear = DW_isLeap(dt.year) ? 1 : 0;
			if (dt.day > DW_dayTable[leapYear][dt.month])
				return false;
    	}

    if (outDatetime != null)
    {
    	if (parseType == DW_PARSEDT_DATE || parseType == DW_PARSEDT_DATETIME)
    	{
    		outDatetime.day = dt.day;
    		outDatetime.month = dt.month - 1;
    		outDatetime.year = dt.year - 1900;
			
			if (outDatetime.year < 0)
				outDatetime.year = 0;
    	}
    	if (parseType == DW_PARSEDT_TIME || parseType == DW_PARSEDT_DATETIME)
    	{
    		outDatetime.sec = dt.sec;
    		outDatetime.min = dt.min;
    		outDatetime.hour = dt.hour;
    		outDatetime.msec = dt.msec;
    	}
    }

	return true;
}

function DW_parseDatetimeString(inString, outDatetime, parseType)
{
	if (gMask != "")
		return DW_parseDatetimeStringAgainstMask(inString, outDatetime, parseType, gMask);

	var STATESECTION = 0;
	var STATENUMBER = 1;
	var STATEMONSTRING = 2;

	var dt = new Array();            // date time array
	var key;           // To hold number and strings
	var currChar;
	var charIndex;
	var strLen = inString.length;
	var state;
	var seq;
	var bIllegal= false;
	var section;
	var i;

	// Initialize date/time array
	for (var i=0; i<= DW_PARSEDT_msecseq; i++)
		dt[i] = -1;

	if (parseType == DW_PARSEDT_TIME)
		{
		section = DW_PARSEDT_hourseq;      // start at time section
		lastseq = DW_PARSEDT_msecseq;
		}
	else if (parseType == DW_PARSEDT_DATETIME)
		{
		section = 0;
		lastseq = DW_PARSEDT_msecseq;
		}
	else
		{
		section = 0;            // start at first section
		lastseq = 2;            // end after date segments
		}
	state = STATESECTION;

    for (charIndex = 0; charIndex < strLen && ! bIllegal;)
		{
		currChar = inString.charAt (charIndex);
		if (state == STATESECTION)
			{
			if (DW_parseIsSpace(currChar))
				charIndex++;          // skip white space
			else if ((currChar == 'a' || currChar == 'A') &&
					 (inString.charAt (charIndex+1) == 'm' || inString.charAt (charIndex+1) == 'M'))
				{
				if (dt[DW_PARSEDT_hourseq] != -1)
					{
					if (dt[DW_PARSEDT_hourseq] == 0 &&
						dt[DW_PARSEDT_minseq] <= 0)
						bIllegal = true;
					else
						{
						if (dt[DW_PARSEDT_hourseq] == 12)  // 12 a.m. = 00
							dt[DW_PARSEDT_hourseq] = 0;
						charIndex += 2;
						section = lastseq;
						}
					}
				else
					bIllegal = true;
				}
			else if ((currChar == 'p' || currChar == 'P') &&
					 (inString.charAt (charIndex+1) == 'm' || inString.charAt (charIndex+1) == 'M'))
				{
				if (dt[DW_PARSEDT_hourseq] != -1)
					{
					charIndex += 2;
					if (dt[DW_PARSEDT_hourseq] != 12)
						{
						dt[DW_PARSEDT_hourseq] += 12;
						if (dt[DW_PARSEDT_hourseq] > 23)
							bIllegal = true;
						else
							section = lastseq;
						}
					}
				else
					bIllegal = true;
				}
			else if (section > lastseq) // too many sections
				bIllegal = true;
			else if (currChar == '-' ||     // New section
					 currChar == '/' ||
					 currChar == ',' ||
					 currChar == '.' ||
					 currChar == ':')
				{
				if (section == 0 ||                 // Never done a section?
					dt[section-1] == -1)        // Missed a section?
					bIllegal = true;
				else
					charIndex++;
				}
			else if (DW_parseIsDigit(currChar))
				{
				key = "";
				state = STATENUMBER;
				}
			else if (DW_parseIsAlpha(currChar))
				{
				if (section != DW_PARSEDT_monseq)
					bIllegal = true;
				else
					state = STATEMONSTRING;
				key = "";
				}
			else
				bIllegal = true;
			}
		else if(state == STATENUMBER)
			{
			key += currChar;
			charIndex++;
			// accumulate until next char is not a digit
			if (!DW_parseIsDigit(inString.charAt (charIndex)))
				{
				state = STATESECTION;       // Change state for next char
				var n = key - 0;
                var keyLength = key.length;
                
				if (section == 0 &&  keyLength == 4)
					{           // year obviously first; force new format
					DW_PARSEDT_yearseq = 0;
					DW_PARSEDT_monseq = 1;
					DW_PARSEDT_dayseq = 2;
					}

				if (section == DW_PARSEDT_monseq)
					{
					if (n < 1 || n > 12)
					bIllegal = true;
					}
				else if (section == DW_PARSEDT_yearseq)
					{       // valid size of year

					if (n < 0 || !(keyLength == 2 || keyLength == 4))
						bIllegal = true;
					// e.g. if 01/01/50 then year is 1950
					else if (n >= 50 && keyLength == 2)
						n += 1900;
					// e.g. if 01/01/49 then year is 2049
					else if (n < 50 && keyLength == 2)
						n += 2000;
					}
				else if (section == DW_PARSEDT_dayseq)
					{
					if (n < 1 || n > 31)        // Do more validation later
						bIllegal = true;
					}
				else if (section == DW_PARSEDT_hourseq)
					{
					if (n < 0 || n > 23)
						bIllegal = true;
					}
				else if (section == DW_PARSEDT_minseq)
					{
					if (n < 0 || n > 59)
						bIllegal = true;
					}
				else if (section == DW_PARSEDT_secseq)    // seconds
					{
					if (n < 0 || n > 59)
						bIllegal = true;
					}
				else        // Micro seconds
					{
					if (n < 0 || n > 999999)
						bIllegal = true;
					else if (keyLength == 1)
						n *= 100000;
					else if (keyLength == 2)
						n *= 10000;
					else if (keyLength == 3)
						n *= 1000;
					else if (keyLength == 4)
						n *= 100;
					else if (keyLength == 5)
						n *= 10;
					}
				if (!bIllegal)
					{
					dt[section] = n;
					section++;
					}
				}
			}
        else if (state == STATEMONSTRING)
            {
			key += currChar;
			charIndex++;
			if (!DW_parseIsAlpha(inString.charAt (charIndex)))
				{
				var m;

				m = DW_monthSearch(key);
				if (m == -1)
					bIllegal = true;
				else
					dt[section] = m;
				state = STATESECTION;
				section++;
				if (inString.charAt (charIndex) == '.' &&  // Check for possible
					key.length == 3 &&  // abbreviation of month
					m != 5)         // "May" has no abbreviation
					charIndex++;
				}
			}
		else
		    {
			bIllegal = true;        // Unspecified error
			}
		}

	if (bIllegal)
		return false;


	if (parseType != DW_PARSEDT_TIME)
		{   // We require month and day and year
		if (dt[DW_PARSEDT_monseq] == -1 ||
			dt[DW_PARSEDT_yearseq] == -1 ||
			dt[DW_PARSEDT_dayseq] == -1)
			return false;
		}
	else if (dt[DW_PARSEDT_hourseq] == -1 )     // We require at least the hour
		return false;

	// Zero out uninitialized fields
	for (i=0; i <= DW_PARSEDT_msecseq; i++)
		if (dt[i] == -1)
			dt[i] = 0;

	// Do additional validation of the day and year
	if (parseType != DW_PARSEDT_TIME)
	    {
    	var leapYear = DW_isLeap(dt[DW_PARSEDT_yearseq]) ? 1 : 0;
		if (dt[DW_PARSEDT_dayseq] > DW_dayTable[leapYear][dt[DW_PARSEDT_monseq]])
    		return false;
		if (dt[DW_PARSEDT_yearseq] > 9999)
			return false;
    	}

    if (outDatetime != null)
        {
    	if (parseType == DW_PARSEDT_DATE || parseType == DW_PARSEDT_DATETIME)
    		{
    		outDatetime.day = dt[DW_PARSEDT_dayseq];
    		outDatetime.month = dt[DW_PARSEDT_monseq]-1;
    		outDatetime.year = dt[DW_PARSEDT_yearseq]-1900;
    		}
    	if (parseType == DW_PARSEDT_TIME || parseType == DW_PARSEDT_DATETIME)
    		{
    		outDatetime.sec = dt[DW_PARSEDT_secseq];
    		outDatetime.min = dt[DW_PARSEDT_minseq];
    		outDatetime.hour = dt[DW_PARSEDT_hourseq];
    		outDatetime.msec = dt[DW_PARSEDT_msecseq];
    		}
    	}

	return true;
}

function DW_DateParse(inString)
{
    var result = new DW_DateClass();
    
    if (DW_parseDatetimeString (inString, result, DW_PARSEDT_DATE))
        return result;
    else
        return null;
}

function DW_DatetimeParse(inString)
{
    var result = new DW_DatetimeClass();
    
    if (DW_parseDatetimeString (inString, result, DW_PARSEDT_DATETIME))
        return result;
    else
        return null;
}

function DW_TimeParse(inString)
{
    var result = new DW_TimeClass();
    
    if (DW_parseDatetimeString (inString, result, DW_PARSEDT_TIME))
        return result;
    else
        return null;
}

function DW_IsZeroDateTime (inString)
{
	if( inString == "00:00" || inString == "00:00:00" )
		return false;

	for ( var i=0; i < inString.length; i++ )
	{
		if ( DW_IsNumber ( inString.substr (i, 1) ) && inString.substr (i, 1) != "0" )
			return false;
	}
	
	return true;
}

function DW_IsDatetime(inString, bNilIsNull)
{
    if (arguments.length < 2)
        bNilIsNull = false;
    
	if (DW_IsZeroDateTime(inString))
        return bNilIsNull;
    else
        return DW_parseDatetimeString (inString, null, DW_PARSEDT_DATETIME);
}

function DW_IsDate(inString, bNilIsNull)
{
    if (arguments.length < 2)
        bNilIsNull = false;
    
	if (DW_IsZeroDateTime (inString))
        return bNilIsNull;
    else
        return DW_parseDatetimeString (inString, null, DW_PARSEDT_DATE);
}

function DW_IsTime(inString, bNilIsNull)
{
    if (arguments.length < 2)
        bNilIsNull = false;
    
	if (DW_IsZeroDateTime (inString))
        return true ;
    else
        return DW_parseDatetimeString (inString, null, DW_PARSEDT_TIME);
}

function DW_Now()
{
    var now = new Date();
    return new DW_TimeClass(now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds());
}

function DW_Today()
{
    var now = new Date();
    var year = now.getYear();
	if( year >= 1900 ) { year -= 1900; }
    return new DW_DateClass(year, now.getMonth(), now.getDate());
}

function DW_DatetimeCompare(date1, date2)
{
    var rc;
    
	if (date1.year != date2.year)
		rc = date1.year - date2.year;
	else if (date1.month != date2.month)
		rc = date1.month - date2.month;
	else if (date1.day != date2.day)
		rc = date1.day - date2.day;
	else if (date1.hour != date2.hour)
		rc = date1.hour - date2.hour;
	else if (date1.min != date2.min)
		rc = date1.min - date2.min;
	else if (date1.sec != date2.sec)
		rc = date1.sec - date2.sec;
	else if (date1.msec < date2.msec)
		rc = -1;
	else if (date1.msec > date2.msec)
		rc = 1;
	else
		rc = 0;
	return rc;
}

function DW_DateCompare(date1, date2)
{
    var rc;
   
	if (date1.year != date2.year)
		rc = date1.year - date2.year;
	else if (date1.month != date2.month)
		rc = date1.month - date2.month;
	else if (date1.day != date2.day)
		rc = date1.day - date2.day;
	else
		rc = 0;
	return rc;
}

function DW_DatetimeToDate(inDatetime)
{
    return new DW_DateClass(inDatetime.year, inDatetime.month, inDatetime.day);
}

function DW_DatetimeToTime(inDatetime)
{
    return new DW_TimeClass(inDatetime.hour, inDatetime.min, inDatetime.sec, inDatetime.msec);
}

function DW_DayNumber(theDate)
{
	return DW_dayOfWeek (theDate.year + 1900, theDate.month + 1, theDate.day);
}

function DW_DaysAfter(date1,date2)
{
    return DW_daysDiff (date2.year + 1900, date2.month + 1, date2.day,
                date1.year + 1900, date1.month + 1, date1.day);
}

function DW_DayName(theDate)
{
    var dayNumber = DW_dayOfWeek (theDate.year + 1900, theDate.month + 1, theDate.day);
    
	return DW_longDayNames[dayNumber];
}

function DW_Fact(n)
{
    var result = 1;

    if (n == null)
        result = null;
    else
        {
        var intN = Math.floor(n);
        // must be an integer and in range
        if (intN != n || intN <= 0 || intN >= 171)
            result = null;
        else
            {
            for (var i = 1; i <= n ; i++)
                result *= i;
            }
        }

    return result;
}

function DW_RelativeDate(inDate, numDays)
{
	var year;
	var month;
	var day;
	var yearDays;
	var aleap;

    var newDate = new DW_DateClass (inDate.year, inDate.month, inDate.day);
    
	if (numDays != 0)         // No days; then same date
	    {
    	year = inDate.year + 1900;

    	day = numDays + DW_dayOfYear(year, inDate.month+1, inDate.day) - 1;
    	while (day >= (yearDays = DW_daysInYear(year)))
    		{
    		year++;
    		day -= yearDays;
    		}
    	while (day < 0)
    		day += DW_daysInYear(--year);

    	newDate.year = year - 1900;

    	aleap = DW_isLeap(year) ? 1 : 0;
    	for (month=0; month< 12 && day >= DW_cumDayTable[aleap][month]; month++)
    	    ;

    	newDate.month = month - 1;
    	newDateday = DW_dayTable[aleap][month] - (DW_cumDayTable[aleap][month] - day) + 1;
		
		newDate.day = newDateday
    	}

    return newDate;
}

function DW_RelativeTime(inTime, numSeconds)
{
    var result;
    var totalSeconds = inTime.sec + inTime.min * 60 + inTime.hour * 3600 + numSeconds;

	if (totalSeconds < 0)// Under flow
		result = null;
	else if (totalSeconds >= 24 * 3600) // over flow
		result = null;
	else
		{
		var hours = Math.floor(totalSeconds / 3600);
		var min = Math.floor((totalSeconds - hours * 3600) / 60);
		var sec = totalSeconds - min * 60 - hours * 3600;
		
		result = new DW_TimeClass (hours, min, sec);
		}

    return result;
}

function DW_SecondsAfter(time1,time2)
{
	var    secs;

	// Calculate difference in times.
	secs = (time1.hour * 3600 + time1.min * 60 + time1.sec) - (time2.hour * 3600 + time2.min * 60 + time2.sec);

	return (secs);
}

function DW_ShowCodeTableDisplayValue(formatString, value)
{
    if (value == null)
        return "";
    var result = value.toString();
    var i;
    for (i = 0; i < this.column.displayValue.length; i++)
        if (value.toString() == this.column.dataValue[i])
            {
            result = this.column.displayValue[i];
            i = this.column.displayValue.length; 

            }

   return result;
}

function DW_Sign(n)
{
    var result;
    if (n < 0) 
        result = -1;
    else if (n == 0)
        result = 0;
    else
        result = 1;

    return result;
}

function DW_TimeCompare(time1, time2)
{
    var rc;
    
    if (time1.hour != time2.hour)
		rc = time1.hour - time2.hour;
	else if (time1.min != time2.min)
		rc = time1.min - time2.min;
	else if (time1.sec != time2.sec)
		rc = time1.sec - time2.sec;
	else if (time1.msec < time2.msec)
		rc = -1;
	else if (time1.msec > time2.msec)
		rc = 1;
	else
		rc = 0;

	return rc;
}

function DW_Truncate(num, decPlaces)
{
	var powTen = Math.pow(10.0,decPlaces);
	num *= powTen;
	if (num >= 0)
	    num = Math.floor(num + 0.000000000000005);
	else
	    num = Math.ceil(num - 0.000000000000005);

    return num / powTen;
}



//////////////////////////////////////
//
//	Funções auxliares criadas pela MEDICWARE
//
//////////////////////////////////////

//////////////////////////////////////
//	Adiciona um Evento a uma coluna
//////////////////////////////////////
HTDW_DataWindowClass.prototype.addEventListener = HTDW_addEventListener;
function HTDW_addEventListener ( col, eventType, funcHandler ) 
{
    var result = -1 ;
	var colNum = this.getColNum(col) ;

    if (colNum == -1)
		return result ;
	
	var colObj = this.cols[colNum] ;
	if (typeof colObj != "undefined" && colObj.displayGobName != null)
	{
		if ( !HTDW_DataWindowClass.isIE4 )
			eventType = eventType.replace ( "on", "" ) ;
	
		for (var row = 0; row < this.RowCount(); row++)
		{
			var control = this.findControl(colObj.displayGobName, row, true) ;
			if (control != null)
			{
				if ( HTDW_DataWindowClass.isIE4 )
					control.attachEvent ( eventType, funcHandler ) ;
				else
					control.addEventListener ( eventType, funcHandler, false ) ;
			}
		}
	}
}

//////////////////////////////////////
//	Remove um Evento a uma coluna
//////////////////////////////////////
HTDW_DataWindowClass.prototype.removeEventListener = HTDW_removeEventListener;
function HTDW_removeEventListener ( col, eventType, funcHandler ) 
{
    var result = -1 ;
	var colNum = this.getColNum(col) ;

    if (colNum == -1)
		return result ;
	
	var colObj = this.cols[colNum] ;
	if (typeof colObj != "undefined" && colObj.displayGobName != null)
	{
		if ( !HTDW_DataWindowClass.isIE4 )
			eventType = eventType.replace ( "on", "" ) ;
	
		for (var row = 0; row < this.RowCount(); row++)
		{
			var control = this.findControl(colObj.displayGobName, row, true) ;
			if (control != null)
			{
				if ( HTDW_DataWindowClass.isIE4 )
					control.detachEvent ( eventType, funcHandler ) ;
				else
					control.removeEventListener ( eventType, funcHandler, false ) ;
			}
		}
	}
}

////////////////////////////////
//	Marca de vermelhos os campos Required
////////////////////////////////
HTDW_DataWindowClass.prototype.markRequired = HTDW_markRequired;
function HTDW_markRequired ( ) 
{	
	this.bMarkRequired = true;
	var sColor;

	for (colNum = 0; colNum < this.cols.length; colNum++ )
	{
		var colObj = this.cols[colNum] ;
		if (typeof colObj != "undefined" && colObj.displayGobName != null)
		{
			if  (eval ("this.gobs." + colObj.displayGobName + ".bRequired") )
				sColor = "#FFD9D9";
			else
				sColor = "white";
			
			for (var row = 0; row < this.RowCount(); row++)
			{
				control = this.findControl(colObj.displayGobName, row, true) ;
				if (control != null)
				{
					control.style.backgroundColor = sColor;
				}
			}
		}
	}
}


////////////////////////////////
//	Marca de vermelhos os campos protegidos (TabSequence = 0)
////////////////////////////////
HTDW_DataWindowClass.prototype.markProtected = HTDW_markProtected;
function HTDW_markProtected ( ) 
{	
	this.bMarkProtected = true;
	var bReadOnlyControl = false;
	var bNegativeTabIndexControl = false;	
	
	for (colNum = 0; colNum < this.cols.length; colNum++ )
	{
		var colObj = this.cols[colNum] ;
		if (typeof colObj != "undefined" && colObj.displayGobName != null)
		{
			//if  (!eval ("this.gobs." + colObj.displayGobName + ".bRequired") )
			//	continue;
			bNegativeTabIndexControl
			
			for (var row = 0; row < this.RowCount(); row++)
			{
				control = this.findControl(colObj.displayGobName, row, true) ;
				if (control != null)
				{
					bReadOnlyControl = false;
					bNegativeTabIndexControl = false;						
					
					// check control attri
					if (control.readOnly + "" != "undefined")
						{
						bReadOnlyControl = control.readOnly;
						}
					if (control.tabIndex + "" != "undefined")
						{
						if( control.tabIndex < 0 )
							bNegativeTabIndexControl = true;
						}
										
					if (bReadOnlyControl || bNegativeTabIndexControl)
						control.style.backgroundColor = "#eaeaea";
				}
			}
		}
	}
}

//////////////////////////////////////
//	EditMask para campo tipo Date/Time/DateTime
////////////////////////////////////////
function DW_dateTimeEditMaskIsSeparatorKey (key)
{
	if ("-/,. :".indexOf (key) == -1 )
		return false;
	else
		return true;
}


function DW_dateTimeEditMaskKeyDown (evt)
{
	evt = evt ? evt : window.event ;

	if ( HTDW_DataWindowClass.isIE4 )
		return DW_dateTimeEditMaskKeyDown_IE4 (evt);
	else 
		return DW_dateTimeEditMaskKeyDown_Gecko (evt);
}

function DW_dateTimeEditMaskKeyDown_Gecko(evt)
{
	return true;
}

function DW_dateTimeEditMaskKeyDown_IE4 (evt)
{
	var editControl;
	var keyCode;
	
	editControl = evt.srcElement ;
	keyCode 	= evt.keyCode;
		
	//1. Delete
	var range = document.selection.createRange() ;
	
	if ( keyCode == 46 )
		{
		range.collapse ( true ) ; 
		range.moveEnd ( "character", 1 ) ;
		range.select ( ) ;
		
		if(!DW_dateTimeEditMaskIsSeparatorKey (range.text) && range.text != "")
			range.text = "0" ;
			
		range.collapse ( false ) ;
		range.select ( ) ;
		evt.returnValue = false ;
		return false;		
		}
		
	//2. Backspace
	else if ( keyCode == 8 )
		{
		range.collapse ( true ) ; 
		range.moveStart ( "character", -1 ) ;
		range.select ( ) ;
		
		if(!DW_dateTimeEditMaskIsSeparatorKey (range.text) && range.text != "")
			range.text = "0" ;
			
		range.moveEnd ( "character", -1 ) ;
		range.select ( ) ;
		evt.returnValue = false ;
		return false;
		}
	else
		{
		evt.returnValue = true;
		return true;				
		}
	
}

function DW_dateTimeEditMaskKeyPress (evt)
{
	evt = evt ? evt : window.event ;

	if ( HTDW_DataWindowClass.isIE4 )
		return DW_dateTimeEditMaskKeyPress_IE4 (evt);
	else 
		return DW_dateTimeEditMaskKeyPress_Gecko (evt);
}

function DW_dateTimeEditMaskKeyPress_Gecko(evt)
{
	var editControl;
	var keyPressed;

	editControl = evt.target ;	
	keyPressed	= String.fromCharCode( evt.charCode ) ;
	
	return true;
}

function DW_dateTimeEditMaskKeyPress_IE4 (evt)
{
	var editControl;
	var keyPressed;
	
	//1. Pega o Edit que disparou o evento
	//e a tecla pressionada
	editControl = evt.srcElement ;
	keyPressed	= String.fromCharCode( evt.keyCode ) ;

	//2. Caso tenha sido pressionado o ENTRE (char(13))
	//Não efetua processamento algum
	if ( evt.keyCode == 13 )
		{
		evt.returnValue = true;
		return true;			
		}
		
	//2.1. Aceita apenas números	
	else if ( "0123456789".indexOf (keyPressed) == -1 )
		{
		evt.returnValue = false;
		return;			
		}
		
	//3. Analisa os dois próximos caracteres
	var range = document.selection.createRange() ;
	range.collapse ( true );
	range.moveEnd ( "character", 2 );
	range.select ( );
	var rangeText 	= range.text;
	var nextChar	= rangeText.substr (1,1);
	var currChar	= rangeText.substr (0,1);

	//4. ByPassa Caso o caracter atual não seja um número
	var nLoopTimes = 0;
	while (DW_dateTimeEditMaskIsSeparatorKey (currChar))
		{
		range.moveEnd ( "character", 1 );
		range.moveStart ( "character", 1 );
		range.select ( );
		rangeText 	= range.text;	
		nextChar	= rangeText.substr (1,1);
		currChar	= rangeText.substr (0,1);		
		
		//4.1. Work-Around para fugir do loop infinito
		nLoopTimes += 1;
		if (nLoopTimes == 30)
			{
			evt.returnValue = false;
			return;
			}
		}
	
	//5. Caso esteja no final do Campo.
	if (currChar == "")
		{
		evt.returnValue = false;
		return;		
		}
	
	//6. Caso o próximo caracter seja um separador de data
	//move-se o cursor para depois do separador
	else if (DW_dateTimeEditMaskIsSeparatorKey (nextChar))
		{
		range.text = keyPressed + nextChar;
		range.collapse ( false );
		range.select ( );
		evt.returnValue = false;
		return;
		}
	
	//7. Caso o próximo caracter seja um número,
	//apenas sob-escreve o caracter atual
	else
		{
		range.collapse ( true );
		range.moveEnd ( "character", 1 );
		range.select ( );
		evt.returnValue = true;
		}
}


////////////////////////////////
//	Seta o focus em um determinado campo
////////////////////////////////
HTDW_DataWindowClass.prototype.SetFocus = HTDW_SetFocus;
function HTDW_SetFocus ( row, col ) 
{
	if ( row > 0 && row <= this.RowCount())
		this.currRow = row - 1;
	else
		return -1;
		
	this.SetColumn ( col );
	return this.SetColumn ( col );
}

/////////////////////////////////
//	Posiciona o cursor no início de um campo Input
/////////////////////////////////
HTDW_DataWindowClass.prototype.scrollToStartControlContent = HTDW_scrollToStartControlContent;
function HTDW_scrollToStartControlContent(control)
{
	return ;
	
	var bNegativeTabIndexControl = false;
	if(control != null)
		{
		if (control.tabIndex + "" != "undefined")
			{
			if( control.tabIndex < 0 )
				bNegativeTabIndexControl = true;
			}

		if(!bNegativeTabIndexControl)
			{
				if ( HTDW_DataWindowClass.isIE4 )
				{
					var range = document.selection.createRange() ;
					range.move ( "character", ( control.value.length * -1 ) );
					range.select ( );				
				}
				else
				{
					control.setSelectionRange(0, 0);
				}
			}
		}
}



HTDW_DataWindowClass.prototype.fixBorderDupla = HTDW_fixBorderDupla;
function HTDW_fixBorderDupla (col)
{
    var result = -1;
	var colNum = this.getColNum(col);

    if (colNum != -1)
        {
		
        var colObj = this.cols[colNum];
        if (typeof colObj != "undefined" && colObj.displayGobName != null)
       		{
			var row;
			for (row = 0; row < this.RowCount(); row++)
				{
				var tdContainer = null;
	            var control = this.findControl(colObj.displayGobName, row, true);
				
				if (control != null)
					{
					if (HTDW_DataWindowClass.isIE4)
						{
						tdContainer = control.parentElement;
						}
					
					else
						{
						alert ("Not Yet Implemented.");
						}
	
					if (tdContainer != null)
						{
							tdContainer.className = "";
						}
					}
				}
			}
		}
}


HTDW_DataWindowClass.prototype.unsetRequired = HTDW_unsetRequired;
function HTDW_unsetRequired ( col ) 
{	
	if ( col == null ) 
	{
		for (colNum = 0; colNum < this.cols.length; colNum++ )
		{
			var colObj = this.cols[colNum] ;
			if (typeof colObj != "undefined" && colObj.displayGobName != null)
			{
				eval ("this.gobs." + colObj.displayGobName + ".bRequired = false");
			}
		}
	}
	else
	{
		var colNum = this.getColNum (col);
	    if (colNum != -1)
        {
	        var colObj = this.cols[colNum];
	        if (typeof colObj != "undefined" && colObj.displayGobName != null)
	       	{
				eval ("this.gobs." + colObj.displayGobName + ".bRequired = false");
			}
		}
	}
}


HTDW_DataWindowClass.prototype.setRequired = HTDW_setRequired;
function HTDW_setRequired ( col ) 
{	
	var colNum = this.getColNum (col);
    if (colNum != -1)
    {
        var colObj = this.cols[colNum];
        if (typeof colObj != "undefined" && colObj.displayGobName != null)
       	{
			eval ("this.gobs." + colObj.displayGobName + ".bRequired = true");
		}
	}
}

//////////////////////////////////
//
// Funções para Debug
//
/////////////////////////////////
var DEBUG_ENTER = 1;
var DEBUG_EXIT = 2;

HTDW_DataWindowClass.prototype.debug = HTDW_debug;
HTDW_DataWindowClass.bDebug = true;

function HTDW_debug ( msg, type ) 
{	
	var indent = '';
	var evt;
	
	//1. Valida o debug
	if ( this.bDebug == false) {
		return;
	}
	else {
		if ( this.debugOutPut == null ) {
			this.debugOutPut = document.getElementById ( this.name + '_debug' );
			if ( this.debugOutPut == null ) {
				this.bDebug = false;
				return;
			}
			else {
				this.debugIndent = 0;
				this.debugOutPutContent = this.debugOutPut.innerHTML;
			}
		}
	}
	
	
	//2. Indentação
	if ( type == DEBUG_EXIT ) {
		this.debugIndent -= 1;
		msg = 'return ' + msg;
	}
		
	for (var i = 0; i < this.debugIndent; i++) {
		indent +=  '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'; 
	}
	msg = indent + msg;
		
	if ( type == DEBUG_ENTER ) 
		this.debugIndent += 1;
	
	//3. Imprime a mensagem de debug
	this.debugOutPutContent += '<br />(' + this.name + ') ' + msg;
	this.debugOutPut.innerHTML = this.debugOutPutContent;
}

HTDW_DataWindowClass.prototype.getGob = HTDW_getGob;
function HTDW_getGob (col)
{
	var colNum = this.getColNum (col);
    if (colNum != -1)
    {
        var colObj = this.cols[colNum];
        if (typeof colObj != "undefined" && colObj.displayGobName != null)
       	{
			return eval ("this.gobs." + colObj.displayGobName );	
		}
	}
	return null;
}

HTDW_DataWindowClass.prototype.addEditMaskDateTime = HTDW_addEditMaskDateTime;
function HTDW_addEditMaskDateTime (col, format, parseFunc)
{
	var colNum = this.getColNum (col);
    if (colNum != -1)
    {
		var colObj = this.cols[colNum];
        if (typeof colObj != "undefined" && colObj.displayGobName != null)
       	{
	        var colObj = this.cols[colNum];
	    	colObj.convertFromString = parseFunc;
		    colObj.validateByType = parseFunc;
			
			var colGob = this.getGob (col);
			if ( colGob != null ) 
			{
				colGob.format = DW_FormatDate ;
				colGob.isDateTime = true ;
				colGob.getDisplayFormat	= format ; 
				colGob.getEditFormat = format ;
			}
		}
	}
} 

HTDW_DataWindowClass.prototype.getDataSource = HTDW_getDataSource;
function HTDW_getDataSource ( op_extraServClassMsgs )
{ 
	var dataSouce = new DataSource( DataSource.HTMLDW );
	var selfArg = new Object( );
	var servMsg = new Object( );
	var form = this.submitForm;
   
	for( var i = 0; i < form.elements.length; i++ ) 
	{ 
		switch( form.elements[i].name ) 
		{ 
			case this.name + "_liblist": 
				dataSouce.dwPBDName = form.elements[i].value;
				break; 
			case this.name + "_dataobject": 
				dataSouce.dwName = form.elements[i].value;
				break; 
			case this.name + "_params": 
				dataSouce.dwParams = form.elements[i].value;
				break; 
			case this.name + "_weight": 
				dataSouce.dwWeight = form.elements[i].value;
				break; 
			case this.name + "_servclass": 
				dataSouce.dwServClass = form.elements[i].value;
				break; 
			case this.name + "_servclassmsg": 
				try {
					//
					if ( form.elements[i].value != "" ) {
						var xml = xmlParser( form.elements[i].value );
						var htmldw = callBackXml2Htmldw( xml );
						var msgObj = new JSMsg ( htmldw );
	
						for ( var j = 1; j <=  msgObj.getMsgCount ( ); j++ ) {
							servMsg[msgObj.getMsgID( j )] = msgObj.getMsg( j );
						}
					}				
				}
				catch(e){}
				break; 
			case this.name + "_action": 
				dataSouce.dwAction = form.elements[i].value;
				break; 
			case this.name + "_context": 
				dataSouce.dwContext = form.elements[i].value;
				break;
			default:
				selfArg[form.elements[i].name] = form.elements[i].value;
		} 
	} 
	
	//
	if( op_extraServClassMsgs ) { 
		servMsg = YAHOO.lang.merge( servMsg, op_extraServClassMsgs );
	}
	
	dataSouce.dwServMsg = servMsg;
	dataSouce.dwSelfLArgs = selfArg;
	dataSouce.dwSelfLlink = form.action;
	dataSouce.dwJSName = this.name;
	
	return dataSouce;
}


HTDW_DataWindowClass.prototype.SetRetrieveParamsSource = HTDW_setRetrieveParamsSource;
function HTDW_setRetrieveParamsSource ( paramsSource )
{
	if(!this.ajax)
	{
		alert( "This is not a WebDatawindow Ajax. Not supported!" );
		return -1;
	}

	this.paramsSource = paramsSource;
	return 1;
}

HTDW_DataWindowClass.prototype.SetEnable = HTDW_SetEnable;
function HTDW_SetEnable ( row, column, valor )
{ 
	var result = -1 ;
	var colNum = this.getColNum(column) ;

	if( valor == null )
		valor = false;
	
    if (colNum == -1)
		return result ;
	
	var colObj = this.cols[colNum] ;
	
	if (typeof colObj != "undefined" && colObj.displayGobName != null)
	{				
		var control = this.findControl(colObj.displayGobName, row-1, true) ;
		
		if (control != null)
		{	
			control.disabled = valor;
		}		
	}
}

HTDW_DataWindowClass.prototype.SetDisable = HTDW_SetDisable;
function HTDW_SetDisable ( row, column )
{ 
	this.SetEnable( row, column, true ); 
}

HTDW_DataWindowClass.prototype.SetVisible = HTDW_SetVisible;
function HTDW_SetVisible ( row, column, valor )
{ 
	var result = -1 ;
	var colNum = this.getColNum(column) ;

	if( valor == null )
		valor = false;
	
    if (colNum == -1)
		return result ;
	
	var colObj = this.cols[colNum] ;

	if (typeof colObj != "undefined" && colObj.displayGobName != null)
	{				
		var control = this.findControl(colObj.displayGobName, row-1, true) ;

		if (control != null)		
		{				
			control.style.visibility = (valor == true ) ? 'visible' : 'hidden';
		}		
	}
}

HTDW_DataWindowClass.prototype.getControl = HTDW_GetControl;
function HTDW_GetControl ( row, column ) {

	var result = null ;
	var colNum = this.getColNum(column) ;
	
    if (colNum == -1)
		return result ;
	
	var colObj = this.cols[colNum] ;

	if (typeof colObj != "undefined" && colObj.displayGobName != null)
	{				
		var control = this.findControl(colObj.displayGobName, row-1, true) ;

		if (control != null)		
		{	
			return control;
		}
	}	
	
	return null;
}

HTDW_DataWindowClass.prototype.isFocus = HTDW_IsFocus;
function HTDW_IsFocus ( row, column )
{ 	
	var control = this.getControl(row, column);

	if (control != null) {
	
		return control.name == this.currentControl.name ? true : false
	}
		
	return false;
}

HTDW_DataWindowClass.prototype.SetPageCtrl = HTDW_SetPageCtrl;
function HTDW_SetPageCtrl( )
{ 	
	var pageInfo = document.getElementById( this.name + "_pgIf" );

	if (pageInfo != null) 
	{
		var totalPages = Math.ceil( this.RowCount( ) / this.pageSize ),
			currPage = ( totalPages == 0 ? 0 : Math.ceil( ( this.firstRow + 1 ) / this.pageSize ) );
		
		pageInfo.innerHTML = "Página " + currPage + " de " + totalPages;
		
		document.getElementById( this.name + "_pgPr" ).style.display = ( currPage <= 1 ) ? "none" : "";
		document.getElementById( this.name + "_pgPrOff" ).style.display = ( currPage <= 1 ) ? "" : "none";
		document.getElementById( this.name + "_pgNx" ).style.display = ( currPage == totalPages ) ? "none" : "";
		document.getElementById( this.name + "_pgNxOff" ).style.display = ( currPage == totalPages ) ? "" : "none";		
	}
}

// Limpa o status e o contexto da datawindow passada por parametro
function limpaStatusContextDw( webDataWindow ) 
{		
	var qtdLinhas = webDataWindow.pageSize < webDataWindow.RowCount () ? 
					webDataWindow.pageSize : webDataWindow.RowCount ();
	
	for ( var i = 0; i < qtdLinhas; i++ ) {
				
		webDataWindow.rows[i][0].itemStatus = DW_ITEMSTATUS_NOCHANGE;	
	}	
	
	var sContext = webDataWindow.context;	

	if ( sContext.indexOf( "Modify") != -1) {
		
		webDataWindow.context = sContext.substr( 0, sContext.indexOf( "Modify") - 1) + ")";
	}	
}

// **********************************************************************************
// Metodos estaticos do objeto HTDW_DataWindowClass responsaveis por 
// realizar as requisicoes de varias datawindows de uma so vez
// **********************************************************************************

HTDW_DataWindowClass.GetFullContext = function (webDataWindow)
{
    var     result = webDataWindow.context;

    result += "(";
    result += webDataWindow.getChanges();
    if (webDataWindow.currRow != -1)
        result += "(row " + webDataWindow.currRow + ")";
    if (webDataWindow.sortString != null)
        result += "(sortString '" + escapeString (webDataWindow.sortString) + "')";
    result += ")";

    return result ;
}

HTDW_DataWindowClass.EventImplemented = function (webDataWindow, sEventName)
{
    // check if we already have one scripted
    if (webDataWindow[sEventName] == null)
        {
        // check for function with default name
        var testName = webDataWindow.name + '_' + sEventName;
        if (eval ('typeof ' + testName) == 'function')
            webDataWindow[sEventName] = eval(testName);
        }

    return webDataWindow[sEventName] != null;
}

HTDW_DataWindowClass.setParamAction = function (action, param, pos) 
{
	switch(action) {
	
		case "RetrieveEx" :
			this.arrDataWindows[pos].retrieveParams = param;
			break;
			
		case "InsertRow" :
			this.arrDataWindows[pos].currRow = param - 1;
			break;
		case "DeleteRow" :
			if ( param > 0 ) {
				this.arrDataWindows[pos].currRow = param - 1;
			}	
			break;						
	}
}

HTDW_DataWindowClass.performActionMultiplo = function (pDataWindows, pActions, pParams, op_extraServClassMsgs) 
{
	this.arrDataWindows = pDataWindows;		

	// Seta os parametros em cada webdatawindow de acordo com a action
	for (var i=0; i < this.arrDataWindows.length; i++) { 
		this.setParamAction( pActions[i], pParams[i], i );
	}
	
	this.PerformAction( pActions, null, op_extraServClassMsgs );
}

HTDW_DataWindowClass.PerformAction = function ( pActions, callback, op_extraServClassMsgs )
{  
	var action = "";
	var dw;
	
	// Seta a Action e o Context das WebDataWindows
	for (var i=0; i<this.arrDataWindows.length; i++) { 
	
		dw = this.arrDataWindows[i];
	
		// Obtem a action verificando se foi passado um array ou uma string	
		action = (typeof pActions == "string") ? pActions : pActions[i];
		
		dw.action = action;
	
		// Evento update start
		if (action == "Update" && this.EventImplemented( dw, "UpdateStart") )
    	{
    		evtResult = _evtDefault(dw.UpdateStart ());
		    
			 // Se o retorno for igual a 1 a acao deve ser cancelada
		     if (evtResult == 1)
	    	    return;
    	}	
		
		// Evento insert start
		 if (action == "InsertRow" && this.EventImplemented( dw, "InsertStart") )
        {
    	    evtResult = _evtDefault(dw.InsertStart ());
	       
		    // Se o retorno for igual a 1 a acao deve ser cancelada
	        if (evtResult == 1)
    	        return;
        }
		
		// Evento delete start
		 if (action == "DeleteRow" && this.EventImplemented( dw, "DeleteStart") )
        {
    	    evtResult = _evtDefault(dw.DeleteStart ());
	       
		    // Se o retorno for igual a 1 a acao deve ser cancelada
	        if (evtResult == 1)
    	        return;
        }
		
		// Evento OnSubmit
   	    if (this.EventImplemented( dw, "OnSubmit") )
		{
            evtResult = _evtDefault( dw.OnSubmit ());
			
     		// Se o retorno for igual a 1 a acao deve ser cancelada
			if (evtResult == 1)
    	        return;
		}
		
		dw.actionField.value = action;
		dw.contextField.value = this.GetFullContext( dw );		
	}

	this.submitAjax( callback, op_extraServClassMsgs );
}

HTDW_DataWindowClass.Update = function ( pDataWindows, callback, op_extraServClassMsgs )
{ 		
	this.arrDataWindows = pDataWindows;		
	this.PerformAction( "Update", callback, op_extraServClassMsgs );
}

HTDW_DataWindowClass.InsertRow = function (pDataWindows, pRowsInsert )
{ 
	this.arrDataWindows = pDataWindows;		
	
	// Seta a linha a ser inserida em cada webdatawindow
	for (var i=0; i < this.arrDataWindows.length; i++) { 
	
		this.arrDataWindows[i].currRow = pRowsInsert[i]-1;
	}

	this.PerformAction( "InsertRow" )	
}

HTDW_DataWindowClass.RetrieveEx  = function ( pDataWindows, params, op_extraServClassMsgs )
{
	this.arrDataWindows = pDataWindows;		
	
	// Seta os parametros das webdatawindows
	for (var i=0; i<this.arrDataWindows.length; i++) { 

		this.arrDataWindows[i].retrieveParams = params[i];
	}
	
	this.PerformAction( "Retrieve", null, op_extraServClassMsgs );	
}

HTDW_DataWindowClass.Retrieve = function ( pDataWindows, callback, op_extraServClassMsgs )
{
	this.arrDataWindows = pDataWindows;		
	this.PerformAction( "Retrieve", callback, op_extraServClassMsgs );
}

HTDW_DataWindowClass.submitAjax = function( callback, op_extraServClassMsgs )
{ 
	var lDataSource = new Array(); 
	var lContainer = new Array(); 
	var lSubmitAjaxCallBack	= new Array(); 

	// Realiza o loop nas datawindows
	for (var i=0; i<this.arrDataWindows.length; i++) { 
	
		if ( this.arrDataWindows[i].retrieveParams != undefined )
		{
			if ( typeof this.arrDataWindows[i].retrieveParams == "object" )
			{
				this.arrDataWindows[i].retrieveParams = this.arrDataWindows[i].retrieveParams.join( "\\n" );
			}

			var paramField = eval ( this.arrDataWindows[i].name + ".submitForm." + this.arrDataWindows[i].name + "_params" );
			
			paramField.value = this.arrDataWindows[i].retrieveParams;
		}
		else if ( this.arrDataWindows[i].paramsSource != undefined )
		{
			var retrieveParamsAux = "";
		
			if ( typeof this.arrDataWindows[i].paramsSource == "string" )
			{
				this.arrDataWindows[i].paramsSource = this.arrDataWindows[i].paramsSource.split( "," );
			}
		
			for ( var parIdx = 0; parIdx < this.arrDataWindows[i].paramsSource.length; parIdx++ )
			{
				if ( parIdx > 0 )
				{
					retrieveParamsAux += "\\n";
				}
				retrieveParamsAux += this.arrDataWindows[i].GetItem( 1, this.arrDataWindows[i].paramsSource[parIdx] );
			}
		
			var paramField = eval ( this.arrDataWindows[i].name + ".submitForm." + this.arrDataWindows[i].name + "_params" );
			paramField.value = retrieveParamsAux;
		}
	
		// Agrupa os DataSources
		lDataSource[i] = this.arrDataWindows[i].getDataSource( op_extraServClassMsgs );
		lDataSource[i].type = DataSource.DW
		
		if ( !this.arrDataWindows[i].container ) {
			this.arrDataWindows[i].container = this.arrDataWindows[i].submitForm.parentNode.parentNode.parentNode;
		}
		
		// Agrupa os Containers		
		lContainer[i] = this.arrDataWindows[i].container;
	
		this.arrDataWindows[i].submitAjaxCallBack.action = this.arrDataWindows[i].action;
		
		// Agrupa os CallBacks das webdatawindows	
		lSubmitAjaxCallBack[i] = this.arrDataWindows[i].submitAjaxCallBack;
		
		// Mostra o messagebox "Carregando..."
		showMsgBox();
	}		

	// Repassa os arrays para a requisicao multipla em scriptGenXMLData
	loadMultiploHTMLDW( lDataSource, lContainer, lSubmitAjaxCallBack, callback );
}

HTDW_DataWindowClass.BootStrap = function( container, libList, dataObj, objName, servClass, retriveArgs, servMsgs )
{
	HTDW_DataWindowClass.BootStrapEx( container, {
		libraryList: libList,
		dataObject: dataObj,
		serviceClasses: servClass,
		objectName: objName,
		retrievalArgs: retriveArgs,
		serviceClassMessages: servMsgs
	});
}

/**
* Carrega uma WebDatawindow na página
*
* @param container Elemento na página que irá conter a WebDatawindow
* @param dw	{Object} DataWindow que será carregada
* @param dw.libraryList	{String | Array} Lista de PBD
* @param dw.dataObject {String} DataObject
* @param dw.objectName {String} Nome do referência cliente-side da WebDatawindow
* @param dw.serviceClasses {String | Array} Lista de service classes
* @param dw.serviceClassMessages {Object} Mensagem para os service classes
* @param dw.action {String} Ação que será executada. A ação padrão é Retrieve
* @param dw.context {String} 
* @param dw.retrievalArgs {String | Array} Lista de argumentos para o retrieve
* @param dw.weight 
* @param dw.page {Number} Número da página para se deseja buscar, Caso seja especificado o número da página, os atributos context e action serão sobreescrevidos.
* @param callback {Function} Função callback que irá ser invocada após a DW ser carregada na tela
*/
HTDW_DataWindowClass.BootStrapEx = function( container, dw, callback )
{
	showMsgBox();
	
	var dataSource = new DataSource( DataSource.HTMLDW );
		dataSource.dwPBDName = dw.libraryList;
		dataSource.dwName = dw.dataObject;
 		dataSource.dwWeight = ( dw.weight ? dw.weight : "full" );
		dataSource.dwServClass = ( typeof dw.serviceClasses == "object" ? dw.serviceClasses.join(";") : dw.serviceClasses );
		dataSource.dwAction = dw.action; 
		dataSource.dwContext = dw.context; 
		dataSource.dwJSName = dw.objectName;	
		dataSource.dwSelfLArgs = dw.serviceClassMessages;
		dataSource.dwParams = ( typeof dw.retrievalArgs == "object" ? dw.retrievalArgs.join( "\\n" ) : dw.retrievalArgs );
		dataSource.dwPage = dw.page;

	var callBackFun = function( htmldwMsg ) { 
		HTDW_submitAjaxCallBack( htmldwMsg ); 
		if( callback ) {
			callback( htmldwMsg );
		}
	};
	
	callBackFun.action = ( dw.action ? dw.action : "Retrieve" );
	
	loadHTMLDW( dataSource, container, callBackFun );
}

/*********************************************************************************************/


//////////////////////////////////////
//	Fim MEDICWARE
//////////////////////////////////////
YAHOO.namespace( "Smartweb.ajax" );
YAHOO.namespace( "Smartweb.util.panel" );
YAHOO.namespace( "Smartweb.util.tabView" );

/*
function ajaxRequest ( URL, callBack, Arg )

Descrição:
Carrega um documento XML na URL especificada com os parâmetros Arg e passa para callBack o documento XML carregado.

Argumentos:
URL - endereço da página que irá gerar o documento XML
callBack - função para qual o documento XML será passado como parâmetro ao ser carregado
Arg - Argumentos para a URL [opcional]

Retorno:
true - caso a solicitação tenha sido enviada com sucesso
false - caso houve erro no envio da solicitação do servidor

OBS: Está é uma função de Base. Veja: getDBValsEx, retrieveDDDW
*/
function ajaxRequest ( URL, callBack, arg ) 
{
	var _callback = {
		success: function(o){ if(_ajaxRequestSuccess(o)) callBack(o); },
		failure: _ajaxRequestFailure
	};
	
	if( YAHOO.lang.isObject( arg ) )
		arg = YAHOO.Smartweb.util.obj2http( arg );
	
	if( arg ) 	
		YAHOO.util.Connect.asyncRequest( "POST", URL, _callback, arg );
	else
		YAHOO.util.Connect.asyncRequest( "GET", URL, _callback, null );
}

function _ajaxRequestSuccess(o)
{
	var sw_error = o.getResponseHeader["sw-error"];
	
	if(sw_error) {
		sw_error = sw_error.replace("\\n", "\n");
		alert(sw_error);
	}
	
	if(o.getResponseHeader["sw-logout"]) {
		showMsgBox();
		
		var re = new RegExp("\/smart\/([^\/]*)\/", "i"),
			m = re.exec(location.href);
		
		parent.location.href = (m ? m[0] : "/smartweb/");
		return false
	}
	
	return true
}

function _ajaxRequestFailure(o)
{
	if( o.status == 500 )
	{
		var erroStartIdx, error;				
		
		erroStartIdx = o.responseText.indexOf( "Microsoft VBScript runtime" );
		if( erroStartIdx < 0 ) erroStartIdx = o.responseText.indexOf( "PowerBuilder" );
		
		if( erroStartIdx > 0 )
		{
			error = o.responseText.substring( erroStartIdx, o.responseText.indexOf( "</li>", erroStartIdx ) - 2 );
			error = YAHOO.Smartweb.util.br2nl( error );
			error = error.replace(/\<[^\>]+\>/g, '');
		}
	}

	if ( typeof o.statusText == "undefined" )
		alert( "There was a problem retrieving the XML data. (" + o.status + ")" + ( error ? "\n----\n" + error : "" ) );
	else
		alert( "There was a problem retrieving the XML data.\n" + o.statusText + " (" + o.status + ")" + ( error ? "\n----\n" + error : "" ) );
}


/*
function loadDoc ( URL, callBack, Arg )

Descrição:
Carrega um documento na URL especificada com os parâmetros Arg e passa para callBack o documento XML carregado.

Argumentos:
URL - endereço da página que irá gerar o documento XML
callBack - função para qual o documento XML será passado como parâmetro ao ser carregado
Arg - Argumentos para a URL [opcional]

Retorno:
true - caso a solicitação tenha sido enviada com sucesso
false - caso houve erro no envio da solicitação do servidor

OBS: Está é uma função de Base. Veja: getDBValsEx, retrieveDDDW
*/
function loadDoc ( URL, callBack, Arg ) {	

	var docCallback = function( xmlHttpObj ) {		
		if( typeof callBack == 'object' )
			callBack.callBack( xmlHttpObj.responseText );
		else 
			callBack( xmlHttpObj.responseText );
			
		callBack = null;
	}
		
	ajaxRequest ( URL, docCallback, Arg );
}

/*
function loadXMLDoc ( URL, callBack, Arg )

Descrição:
Carrega um documento XML na URL especificada com os parâmetros Arg e passa para callBack o documento XML carregado.

Argumentos:
URL - endereço da página que irá gerar o documento XML
callBack - função para qual o documento XML será passado como parâmetro ao ser carregado
Arg - Argumentos para a URL [opcional]

Retorno:
true - caso a solicitação tenha sido enviada com sucesso
false - caso houve erro no envio da solicitação do servidor

OBS: Está é uma função de Base. Veja: getDBValsEx, retrieveDDDW
*/

function loadXMLDoc ( URL, callBack, Arg ) {
				
	var xmlDocCallback = function( xmlHttpObj ) {
		
		var xml = xmlHttpObj.responseXML;
		if ( xml == null ) {
			var parser = new DOMParser(); 
			xml = parser.parseFromString (xmlHttpObj.responseText, "text/xml"); 
		}
		
		if ( xml.parseError && xml.parseError.errorCode != 0 ) {
			alert(	"Erro Fatal!\nErro interpretando arquivo XML retornado!\n\n" + 
  					"reason: " + xml.parseError.reason + "\n" +
				  	"errorCode: " + xml.parseError.errorCode + "\n" +
					"filepos: " + xml.parseError.filepos + "\n" +
					"line: " + xml.parseError.line + "\n" +
					"linepos: " + xml.parseError.linepos + "\n" +
					"srcText: " + xml.parseError.srcText );
			return;
		}
		
		if( typeof callBack == 'object' )
			callBack.callBack( xml );
		else 
			callBack( xml );
	}
		
	ajaxRequest ( URL, xmlDocCallback, Arg );
}


/*
function processReqChange ( xmlHttpObj, callBack )

Descrição:
Ao fazer uma requisição ao servidor usando loadXMLDoc, está função valida a reposta do servidor e, caso a requisição tenha sido processada com sucesso, passa para callBack o objeto XML retornado.

Argumentos:
xmlHttpObj - Objeto XMLHttpRequest usado para fazer a requisição ao servidor
callBack - Função callBack para qual será passado o objeto XML retornado do servidor

OBS: Está é uma função de Base. Veja: getDBValsEx, retrieveDDDW
*/
function processReqChange ( xmlHttpObj, callBack ) {

    // only if req shows "loaded"
    if (xmlHttpObj.readyState == 4) {
	
        // only if "OK"
        if (xmlHttpObj.status == 200) {
			
            // ...processing statements go here...
			callBack ( xmlHttpObj );
			
        } else {
			
			if( xmlHttpObj.status == 500 )
			{
				var erroStartIdx, error;				
				
				erroStartIdx = xmlHttpObj.responseText.indexOf( "Microsoft VBScript runtime" );
				if( erroStartIdx < 0 ) erroStartIdx = xmlHttpObj.responseText.indexOf( "PowerBuilder" );
				
				if( erroStartIdx > 0 )
				{
					error = xmlHttpObj.responseText.substring( erroStartIdx, xmlHttpObj.responseText.indexOf( "</li>", erroStartIdx ) - 2 );
					error = YAHOO.Smartweb.util.br2nl( error );
					error = error.replace(/\<[^\>]+\>/g, '');
				}
			}

			if ( typeof xmlHttpObj.statusText == "undefined" )
	            alert( "There was a problem retrieving the XML data. (" + xmlHttpObj.status + ")" + ( error ? "\n----\n" + error : "" ) );
			else
	            alert( "There was a problem retrieving the XML data.\n" + xmlHttpObj.statusText + " (" + xmlHttpObj.status + ")" + ( error ? "\n----\n" + error : "" ) );
        }
    }
}

/*
function callBackXml2Htmldw ( xml )

Descrição:
cria um HTML_DataWindow client control a partir de um objeto XML.

Argumento:
xml - objeto XML que contém os dados

Retorna:
HTML_DataWindow client control
*/
function callBackXml2Htmldw ( xml ) 
{ 
	var htmldw	= new HTDW_DataWindowClass ( "htmldw" ),
		XMLRows = xml.lastChild.childNodes,
		XMLCols, row, col, colAux; 
	
	htmldw.name = xml.lastChild.nodeName;
	htmldw.rowCount = XMLRows.length;
	htmldw.firstRow = 0;
	htmldw.lastRow = htmldw.rowCount - 1;
	
	for ( row = 0; row < XMLRows.length; row++ ) {
		XMLCols = XMLRows[row].childNodes
		
		for ( col = 0;  col < XMLCols.length; col++ ) 
		{	
			if ( row == 0 ) {
				htmldw.cols [col+1] = new HTDW_ColumnClass ( col+1, XMLCols[col].nodeName, DW_StringParse, DW_IsString, null, null, null, XMLCols[col].nodeName );
			}
			
			if ( col == 0 ) {
				htmldw.rows[row] = new HTDW_RowClass( "()", DW_ITEMSTATUS_NOCHANGE );
				htmldw.rows[row].numCols = XMLCols.length;
				for ( colAux = 1; colAux <= XMLCols.length; colAux++ ) {
					htmldw.rows[row][colAux] = null;
				}
			}
			
			if ( HTDW_DataWindowClass.isIE4 )
				htmldw.SetItem( row+1, col+1, XMLCols[col].text );
			else
				htmldw.SetItem( row+1, col+1, XMLCols[col].textContent );
		}
		
		XMLCols = null;
	}
	
	XMLRows = null;
	
	return htmldw;
}

/**
* Cria uma WebDataWindow à partir de um objeto JSON que
* foi criado à partir de uma DW com o método nv_json.encodeRowArray(dw)
*/
YAHOO.Smartweb.ajax.json2dw = function( json )
{
	var htmldw = new HTDW_DataWindowClass ( "htmldw" ),
		json_cols = json.cols,
		json_rows = json.rows, 
		cols_length = json_cols.length, 
		i;	
	
	htmldw.rowCount = json_rows.length;
	htmldw.firstRow = 0;
	htmldw.lastRow = htmldw.rowCount - 1;
	htmldw.cols = new Array( json_cols.length );
	
	for( i = 0; i < cols_length; i++ ) 
		htmldw.cols[i + 1] = new HTDW_ColumnClass ( i + 1, json_cols[i], DW_StringParse, DW_IsString, null, null, null, json_cols[i] );
	
	for( i = 0; i < json_rows.length; i++ ) {
		json_rows[i].splice( 0, 0, new HTDW_Col0Class( "()", DW_ITEMSTATUS_NOCHANGE ) );
		json_rows[i].numCols = cols_length; 
	}
	
	htmldw.rows = json_rows;
	return htmldw;
}

function getXMLDoc()
{
	var xmlDoc
	
	//load xml file
	// code for IE
	if (window.ActiveXObject)
	{
		xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async=false;
	}
	// code for Mozilla, etc.
	else if (document.implementation &&	document.implementation.createDocument)
	{
		xmlDoc= document.implementation.createDocument ("", "", null);
	}
	
	return xmlDoc;
}

function Htmldw2Xml ( htmldw )
{
	var xmlDoc = getXMLDoc ( );
	var xmlRoot = xmlDoc.createElement( htmldw.name );
	var xmlCol;
	var xmlRow;
	 
	for ( var row = 1; row <= htmldw.RowCount( ); row++ )
	{
		xmlRow = xmlDoc.createElement( htmldw.name + "_row" );
		xmlRoot.appendChild ( xmlRow );
		
		for ( var col = 1; col < htmldw.cols.length ; col++ )
		{
			xmlCol = xmlDoc.createElement ( htmldw.cols[col].name );
			xmlCol.text = htmldw.GetItem ( row, col );
			xmlRow.appendChild ( xmlCol );
		}
	}
	
	return xmlRoot;
}

/*
Objeto DataSource

Descrição:
Objeto usada para especificar qual a fonte de dados utilizada para se fazer uma requisção usando XMLHttpRequest ao servidor.

A Fonte da dados pode ser de dois tipos:

1. DW (DataWindow)
A fonte de dados é uma DataWindow.
Neste caso o construtor de DataSource tem o seguinte formato
DataSource ( type, dwPBDName, dwName [, dwParams [, dwFilter [, dwSort [, dwContext, [, dwServClass [, dwServMsg]]]]]] )

type - DW
dwPBDName - pbd - PBD onde a DataWindow se encontra
dwName - do - Nome do DataObject 
dwParams - pr - Parâmetros para o Retrieve (opcional)
dwFilter - fl - Filtro (opcional)
dwSort - sr - Ordenação (opcional)
dwContext - ctx - Contexto gerado de htmldw.GetFullContext () (opcional)
dwServClass - sc - Service Class (opcional) 
dwServMsg - scm - Mensagem para o Service Class (opcional) 
dwAction - ac - Ação que será aplicada 
dwJSName - jn - Nome do WebDataWindow Client Control 
dwWeight - wh - SetWeight 
dwSelfLlink - sfl - SelfLink 
dwSelfLArgs - sfa - SelfLinkArgs

2. QUERY
A fonte de dados é uma query estática.
Neste caso o construtor de DataSource tem o seguinte formato
DataSource ( type, query )

type - QUERY
query - SELECT SQL usado para buscar os dados

OBS: Este objeto foi projetado para ser usado com as funções getDBValsEx e retrieveDDD
*/
function DataSource ( type ) {
	
	this.type = type;
	
	//1. Fonte de Dados
	//1.1. DataWindow
	if ( type == DataSource.DW ) {
		this.dwPBDName 		= arguments[1];
		this.dwName 		= arguments[2];
		
		//Pode ser uma String... (DataWindows com 1 parâmetro)
		if ( arguments[3] == null ){
			this.dwParams = "";
		}
		//Pode ser um Array... (DataWindows com +1 parâmetro)
		else if ( typeof arguments[3] == 'object' ) {
			this.dwParams = arguments[3].join ( "\\n" );
		}
		else if ( typeof ( arguments[3] + "" ) == 'string' ) {
			this.dwParams = arguments[3];
		}
		else {
			this.dwParams = "";
		}
			
		this.dwFilter		= arguments[4] ;
		this.dwSort			= arguments[5] ;
		this.dwContext		= arguments[6] ;
		this.dwServClass	= arguments[7] ;
		this.dwServMsg		= arguments[8] ;
		this.dwAction		= null ;
		this.dwJSName		= null ; 
		this.dwWeight		= null ; 
		this.dwSelfLlink	= null ;
		this.dwSelfLArgs 	= null ;
	}
	
	//1.2. Query
	else if ( type == DataSource.QUERY ) {
		this.query = arguments[1]; 
	}
}

DataSource.QUERY = 0;
DataSource.DW = 1;
DataSource.HTMLDW = 2;

DataSource.prototype.getArgs = function ( idxDw ) {

	var sArg;
	var sIdxDw = idxDw != null ? idxDw : "";
	
	if ( this.type == DataSource.QUERY ) {
		sArg = "query=" + escape ( this.query );
	}
	
	else if ( this.type == DataSource.DW || this.type == DataSource.HTMLDW ) {
	
		var serializeObj = function ( obj ) {
			var serial = "";
			for ( var attr in obj ) { serial += encodeURIComponent( attr + "=" + obj[attr] ) + ";"; }
			return serial;
		} 
	
		sArg = "pbd" + sIdxDw + "=" + this.dwPBDName;
		if( this.type != DataSource.HTMLDW ) { sArg += "&do" + sIdxDw + "=" + this.dwName };
		sArg += ( this.dwParams ? "&pr" + sIdxDw + "=" + escape ( this.dwParams ) : "" );			
		sArg += ( this.dwFilter ? "&fl" + sIdxDw + "=" + escape ( this.dwFilter ) : "" );
		sArg += ( this.dwSort ? "&sr" + sIdxDw + "=" + escape ( this.dwSort ) : "" );
		sArg += ( this.dwContext ? "&ctx" + sIdxDw + "=" + encodeURIComponent( this.dwContext ) : "" );
		sArg += ( this.dwServClass ? "&sc" + sIdxDw + "=" + this.dwServClass : "" );
		sArg += ( this.dwServMsg ? "&scm" + sIdxDw + "=" + serializeObj( this.dwServMsg ) : "" );
		sArg += ( this.dwAction ? "&ac" + sIdxDw + "=" + this.dwAction : "" );
		sArg += ( this.dwJSName ? "&jn" + sIdxDw + "=" + this.dwJSName : "" );
		sArg += ( this.dwWeight ? "&wh" + sIdxDw + "=" + this.dwWeight : "" );
		//sArg += ( this.dwSelfLlink ? "&sfl" + sIdxDw + "=" + this.dwSelfLlink : "" );
		sArg += ( this.dwSelfLArgs ? "&sfa" + sIdxDw + "=" + serializeObj( this.dwSelfLArgs ) : "" );
		sArg += ( this.dwPage ? "&pg" + sIdxDw + "=" + this.dwPage : "" );
	}
	
	return sArg;
}

DataSource.prototype.getUrl = function ( ) 
{
	var sUrl;

	if ( this.type == DataSource.QUERY )
		sUrl = YAHOO.Smartweb.util.getRoot() + "/select-gen/getDBXMLDataQuery.asp";
	else if ( this.type == DataSource.DW ) 
		sUrl = YAHOO.Smartweb.util.getRoot() + "/select-gen/getDBXMLDataDW.asp";
	else if ( this.type == DataSource.HTMLDW ) 
		sUrl = YAHOO.Smartweb.util.getRoot() + "/select-gen/webdatawindowxml.asp?do=" + this.dwName;
	
	return sUrl;
}

/*
Objeto DataDestination

Descrição:
Este objeto é usado para mapear os dados de um objeto DataSource com uma WebDataWindow.
Quando os dados buscados apartir de uma DataSource estiverem disponíveis, este objeto será usado para imputar estes dados numa WebDataWindow.

Argumentos:
htmldw - WebDataWindow onde os dados serão imputados
row - registro da WebDataWindow onde os dados serão imputados
colsDest - Array com os nomes das colunas de htmldw onde os dados serão imputados
colsSource - Array contendo os nomes (ou números) das colunas dos dados retornados que irão ser imputados em colsDest (opcional). Caso este parãmetros não seja passado, as primeiras colunas na ordem serão usadas para preencher colsDest.

OBS: Este objeto foi projetado para ser usado com a função getDBValsEx
*/
function DataDestination ( htmldw, row, colsDest, colsSource ) {

	this.htmldw = htmldw;
	this.row = row;
	this.colsDest = colsDest;
	this.colsSource = colsSource;
	
	if ( colsSource == null ) {
		this.colsSource = new Array ( colsDest.length );
		for ( var col = 0; col < colsDest.length; col++ )
			this.colsSource[col] = col + 1;
	}
}

/*
function getDBValsEX ( dataSource, dataDestination )

Descrição:
Busca os dados de dataSource e imputa em dataDestination.
Caso o argumento dataDestination não seja um objeto do tipo DataDestination, mas, sim, uma função, então passa como parâmetro para esta função o HTML_DataWindow client control gerado de DataSource.

OBS: Está função é assíncrona, ou seja, ao executá-la apenas está se enviando a solicitação dos dados e especificando seu posterior tratamento.
OBS: Veja DataSource e DataDestination
*/
function getDBValsEX ( dataSource, dataDestination, cache ) {

	showMsgBox();

	var sArg = dataSource.getArgs ( );
	var sUrl = dataSource.getUrl ( );
	
	var callBackMain = function ( xml ) {
		getDBValsExCallBack( xml, dataDestination );
	}
	
	if ( cache ) 
	{ 
		sUrl += "?" + sArg + "&cache=on"; 
		sArg = null;
	}
	
	loadXMLDoc ( sUrl, callBackMain, sArg );
}

function getDBValsExCallBack ( xml, dataDestination ) {

	hideMsgBox ( );

	if ( xml == null ) {
		alert ( "Erro buscando dados no banco." );
		return;
	}

	var dataDest = dataDestination;
	var htmldwSource = callBackXml2Htmldw ( xml );
	
	//1. Erro buscando dados
	if ( htmldwSource.name == "msg" )
	{
		var msgErro = new JSMsg ( htmldwSource );
		msgErro.alertMsgAll ( );
		msgErro.cleanUp()
		return ;
	}
	
	
	if ( typeof dataDest == "function" ) 
	{
		dataDest ( htmldwSource );
	}
	
	else if ( typeof dataDest == "object" ) 
	{
		var value;
		
		if ( htmldwSource.RowCount ( ) == 0 ) {
			alert ( "Dados não encontrados." );
		}
		
		for ( var colDest = 0; colDest < dataDest.colsDest.length; colDest++  ) {
		
			if ( htmldwSource.RowCount ( ) == 0 )
				value = null;
			else
				value = htmldwSource.GetItem ( 1, dataDest.colsSource[colDest] );
			
			dataDest.htmldw.SetItem ( 	dataDest.row, 
										dataDest.colsDest[colDest], 
										value );
		}
	}
	
	YAHOO.Smartweb.util.dwCleanUp( htmldwSource );
}

/*
Objeto DDDW 

Descrição:
Representa uma coluna do tipo DDDW de uma WebDataWindow 
O construtor tem o seginte formato: 
DDDW ( htmldw, row, colName, colValue, colDisplay )

htmldw - HTML_DataWindow da dddw
row - Registro da HTML_DataWindow
colName - Nome da coluna dddw em htmldw
colValue - Nome da coluna de DataSource do valor da DDDW
colDisplay - Nome da coluna de DataSource do display da DDDW

OBS: Este objeto foi projetado para ser usado com a função retrieveDDDW
*/
function DDDW ( htmldw, row, colName, colValue, colDisplay ) {

	this.colName = colName;
	this.htmldw = htmldw;
	this.row = row;
	this.colValue = colValue;
	this.colDisplay = colDisplay;
}

/*
function retrieveDDDW ( dataSource, DDDW, callBack, cache )

Descrição:
Preenche um campo tipo DDDW de uma WebDataWindow apartir dos dados de dataSource.
Executa callBack no final do processo passando como parâmetros DDDW e o HTML_DataWindow client control gerado de dataSource.

Argumentos:
dataSource - Fonte dos dados (Objeto DataSource) para a DDDW
DDDW - DropDownDataWindow (Objeto DDDW)
callBack - função que será chamada no final do processo passando como parâmetros DDDW e o HTML_DataWindow client control gerado de dataSource. (opcional)
*/
YAHOO.Smartweb.ajax.retrieveDDDW = function( dataSource, DDDW, callBack, cache ) {

	showMsgBox();

	var sArg = dataSource.getArgs ( );
	var sUrl = dataSource.getUrl ( );
	var callBackMain = function ( xml ) {
		YAHOO.Smartweb.ajax._retrieveDDDWCallBack( xml, DDDW, callBack );
	}
	
	if ( cache ) 
	{ 
		sUrl += "?" + sArg + "&cache=on"; 
		sArg = null;
	}
	
	loadXMLDoc ( sUrl, callBackMain, sArg );
}	

YAHOO.Smartweb.ajax._retrieveDDDWCallBack = function ( xml, DDDW, callBack ) 
{
	hideMsgBox ( );

	if ( xml == null ) {
		alert ( "Erro buscando dados no banco." );
		return;
	}
	
	var htmldwSource = callBackXml2Htmldw ( xml );

	//1. Erro buscando dados
	if ( htmldwSource.name == "msg" )
	{
		var msgErro = new JSMsg ( htmldwSource );
		msgErro.alertMsgAll ( );
		msgErro.cleanUp();
		return;
	}
	
	var dataValue,
		dataDisplay,
		colNum = DDDW.htmldw.getColNum(DDDW.colName),
		colObj = DDDW.htmldw.cols[colNum],
		DDDWControl ;
	
	if (typeof colObj != "undefined" && colObj.displayGobName != null) {
		DDDWControl = DDDW.htmldw.findControl ( colObj.displayGobName, DDDW.row-1, true );
	}
	else {
		alert ( "Erro buscando campo DropDown." );
		return;
	}
	
	var dddwValue = DDDW.htmldw.GetItem ( DDDW.row, DDDW.colName );
	
	clearTopicList ( DDDWControl );
	
	if ( dddwValue == null )
	{
		appendToSelect ( DDDWControl, "", "" );
		DDDW.htmldw.SetItem ( DDDW.row, DDDW.colName, "" );
	}
	
	for ( var row = 1; row <= htmldwSource.RowCount ( ); row++  ) 
	{
		dataValue = htmldwSource.GetItem ( row, DDDW.colValue );
		
		if ( typeof DDDW.colDisplay == "string" ) 
			dataDisplay = htmldwSource.GetItem ( row, DDDW.colDisplay );
		else
		{
			var idx = 0;
			dataDisplay = htmldwSource.GetItem ( row, DDDW.colDisplay[idx] );
			for ( idx = 1; idx < DDDW.colDisplay.length && ( dataDisplay == null || dataDisplay == "" ); idx++ )
				dataDisplay = htmldwSource.GetItem ( row, DDDW.colDisplay[idx] );
		}
		
        appendToSelect( DDDWControl, dataValue, dataDisplay );
	}
	
	DDDW.htmldw.SetItem ( DDDW.row, DDDW.colName, dddwValue );
	
	if ( typeof callBack == 'function' ) {
		callBack ( xml, DDDW );
	}
	
	YAHOO.Smartweb.util.dwCleanUp( htmldwSource );
}

function appendToSelect(select, value, display) 
{
	if (select == null)
		return;
		
	var opt = new Option ( display, value, false, false );
	select.options[select.options.length] = opt; 
	return opt;
}

function clearTopicList(select) 
{
    if (select == null)
		return;
	
	while (select.length > 0) {
        select.remove(0);
    }
}

/*
Carrega uma página em um container qualquer
*/
function loadPageIntoContainuer( container, url, arg ) 
{
	showMsgBox();
	loadDoc( url, function( responseText ){ loadPageIntoContainuerCallback( responseText, container ); }, arg );
}

/* */
function loadPageIntoContainuerCallback( responseText, container ) 
{
	hideMsgBox();

	var match;
	var response = YAHOO.Smartweb.util.extractStyles( responseText ),
		htmlScript = "";

	YAHOO.Smartweb.util.applyStyles( response.style );
	YAHOO.Smartweb.util.purge( container );
	container.innerHTML = response.html;
	
	var re = /<script.*?>([\s\S]*?)<\//igm;
	while ( match = re.exec( response.html ) ) {
		htmlScript += match[1] + ";";
	}
	
	try {
		evalGlobal( htmlScript ); 
	} catch( catch_e ) { }
}

/**
Funcoes relacionadas ao componente TabView do YUI!
*/

/**
Carrega uma página dentro de um Tab
*/
YAHOO.Smartweb.util.tabView.loadPage = function( tab, url, arg )
{
	if( url ) { tab._url = url };
	if( arg ) { tab._arg = arg };
	
	loadPageIntoContainuer( tab.get( "contentEl" ), tab._url, tab._arg );
}

/**
Limpa o conteúdo de Tab

@param tab {YAHOO.widget.Tab} Limpa o conteúdo do tab
@param tab {YAHOO.widget.Tab[]} Limpa o conteúdo de todos os tabs
@param tab {YAHOO.widget.TabView} Limpa o conteúdo de todos os tabs do tabView
*/
YAHOO.Smartweb.util.tabView.reset = function( tab )
{
	if ( tab.getTab ) //É um TabView
		return YAHOO.Smartweb.util.tabView.reset( tab.get( "tabs" ) );
	else if ( YAHOO.lang.isArray( tab ) ) {
		for ( var i = 0; i < tab.length; i++ ) 
			YAHOO.Smartweb.util.tabView.reset( tab[i] );
			
		return;
	}
			
	var dom = YAHOO.util.Dom, 
		tabContent, tabContentEl, contentChildren;
	
	tabContent = tab.get( "contentEl" );
	tabContentEl = new YAHOO.util.Element( tabContent );
	contentChildren = dom.getChildren( tabContent );
	
	for( var i = 0; i < contentChildren.length; i++ ) {
		tabContentEl.removeChild( contentChildren[i] );
	}
}

/**
Cria um link de uma página com um Tab.
Quando o Tab for ativado a página será carregada.
*/
YAHOO.Smartweb.util.tabView.hookPage = function( tab, url, arg, refresh ) 
{	
	if( url ) { tab._url = url; }
	if( arg ) { tab._arg = arg; }
	
	// Necessario para nao haver multiplas requisicoes desnecessarias
	tab.removeListener( "activeChange" );
	
	tab.on( "activeChange", function( eventInfo ) {
		if( eventInfo.newValue ) {
			var contentEl = this.get( "contentEl" );
			if( contentEl.childNodes.length == 0 || refresh ) {
				YAHOO.Smartweb.util.tabView.loadPage( tab, tab._url, tab._arg );
			}
		}
	});
}

/*
Compatibilidade...
*/
function loadIntoYuiTab( tab, url, arg ) { YAHOO.Smartweb.util.tabView.loadPage( tab, url, arg ); }

/**
Carrega uma nova página em um painel

@param url URL da página
@param opt Opções
@param opt.arg Argumentos para o URL
@param opt.title Título da página
@param opt.callback Callback function ao fechar a janela
@param opt.width Largura do painel
@param opt.height Altura do painel
@param opt.fullscreen FullScreen?
@param opt.r800x600 FullScreen em uma resolução de 800x600?
@param opt.r640x480 FullScreen em uma resolução de 640x480?
@param opt.close Exibe o botão close?
@param opt.noCache Guarda a página em cache?

@return Painel carregado
*/
YAHOO.Smartweb.util.panel.load = function( url, opt )
{
	var panel, dom = YAHOO.util.Dom;
	
	if( !opt ) { opt = new Object(); }
	if( !opt.title ) { opt.title = ""; }
	if( opt.close == null ) { opt.close = true };
	if( !opt.arg && opt.noCache ) { opt.arg = { dummy: "" } }
	
	if( opt.fullscreen ) {
		opt.width = dom.getViewportWidth() - 35;
		opt.height = dom.getViewportHeight() - 35;
	}
	
	try {
		panel = new YAHOO.widget.Panel( dom.generateId( null, "_panel" ), 
			{	close:opt.close,  
			    visible:false,  
			    draggable:true,
				modal:true,
		    	constraintoviewport:true,
				fixedcenter:true,
				width: opt.width + ( YAHOO.lang.isNumber( opt.width ) ? "px" : null ),
				height: opt.height + ( YAHOO.lang.isNumber( opt.height ) ? "px" : null ) } ); 
	} catch ( catch_e ) { 
		alert( "Erro criando painel!\n" + catch_e.message );
		return null;
	}

	//
	dom.addClass( document.body, "yui-skin-sam" ); 			
			
	panel.setHeader( opt.title );

	if( opt.useIframe ) {
		var iframePdf = document.createElement( "iframe" ); 
		iframePdf.style.height = ( opt.height - 52 ) + "px";
		iframePdf.style.width = "100%";
		iframePdf.frameBorder = "0";
		panel.setBody( iframePdf );
	}
	else {
		panel.setBody( '<div class="ico loading">$nbsp;</div>' );
	}
	
	panel.hideEvent.subscribe( function ( type, args, obj ) {
			YAHOO.Smartweb.util.panel.current = YAHOO.Smartweb.util.panel.panelsStack.pop();
			setTimeout( function(){ panel.destroy(); }, 0 );
			if( opt.callback ){ opt.callback( obj ) };			
		} );
		
	panel.render( document.body );
	panel.show();
	
	if( !YAHOO.lang.isArray( this.panelsStack ) ) { this.panelsStack = new Array(); }
	if( this.current ) { this.panelsStack.push( this.current ); }
	this.current = panel;
	
	if( opt.useIframe ) {
		iframePdf.src = url + ( url.indexOf( "?" ) < 0 ? "?" : "&" ) + YAHOO.Smartweb.util.obj2http( opt.arg );
	}
	else {
		loadDoc( url, function( responseText ){ YAHOO.Smartweb.util.panel._loadCallback( responseText, panel ); }, opt.arg );
	}
	
	return panel;
}

YAHOO.Smartweb.util.panel._loadCallback = function( responseText, panel ) 
{
	if( this.current != panel ) return;

	var match,
		response = YAHOO.Smartweb.util.extractStyles( responseText ),
		htmlScript = "";

	YAHOO.Smartweb.util.applyStyles( response.style );
	panel.setBody( response.html );
	panel.center( );
	
	var re = /<script.*?>([\s\S]*?)<\//igm;
	while ( match = re.exec( responseText ) ) {
		htmlScript += match[1] + ";";
	}
	
	try {
		evalGlobal( htmlScript ); 
	} catch( catch_e ) { }
}

/* Fecha o painel atual passando um argumento */
YAHOO.Smartweb.util.panel.closeCurrent = function( arg ) 
{
	var panel = this.current;
	
	if( !panel ) { return; }
	
	for( var i = 0; i < panel.hideEvent.subscribers.length; i++ ) {
		panel.hideEvent.subscribers[i].obj  = arg;
	}
	
	panel.hide();
}

/* Altera o título do Painel atual */
YAHOO.Smartweb.util.panel.changeTitleCurrent = function( title ) 
{
	var panel = this.current;
	if( !panel ) { return; }
	panel.setHeader( title );
}

/* Carrega uma página em um painel ocupando todo o viewport */
function loadIntoYuiPanelFull( url, arg, title, onHideHandler ) { return loadIntoYuiPanel( url, arg, title, null, onHideHandler, true ); }
/* Carrega uma página em um painel */
function loadIntoYuiPanel( url, arg, title, width, onHideHandler, fullscreen ) { return YAHOO.Smartweb.util.panel.load( url, { arg: arg, title: title, width: width, fullscreen: fullscreen, callback: onHideHandler } ); }
/* Fecha o painel atual passando um argumento */
function closePanel( arg ) { return YAHOO.Smartweb.util.panel.closeCurrent( arg ); }
/* Altera o título do Painel atual */
function changePanelTitle( title ) { return YAHOO.Smartweb.util.panel.changeTitleCurrent( title ); }



/* Prompt para obtenção de uma DATA */
YAHOO.Smartweb.util.promptDate = function( title, args ) { args.title = title; if( !args.width ) args.width = 340; this.panel.load( YAHOO.Smartweb.util.getRoot() + "/select-gen/get_date_panel.asp", args ); }
/* Prompt para obtenção de uma DATAHORA */
YAHOO.Smartweb.util.promptDateTime = function( title, args ) { args.title = title; if( !args.width ) args.width = 340; this.panel.load( YAHOO.Smartweb.util.getRoot() + "/select-gen/get_datetime_panel.asp", args ); }
/* Prompt para obtenção de uma HORA */
YAHOO.Smartweb.util.promptTime = function( title, args ) { args.title = title; this.panel.load( YAHOO.Smartweb.util.getRoot() + "/select-gen/get_time_panel.asp", args ); }
/* Prompt para obtenção de um TEXT  */
YAHOO.Smartweb.util.promptString = function( title, args ) { args.title = title; this.panel.load( YAHOO.Smartweb.util.getRoot() + "/select-gen/get_string_panel.asp?ini=" + ( args.initialValue ? args.initialValue : "" ), args ); }
/* Prompt para obtenção de um TEXT mult-linha  */
YAHOO.Smartweb.util.promptTextarea = function( title, args ) { args.title = title; this.panel.load( YAHOO.Smartweb.util.getRoot() + "/select-gen/get_textarea_panel.asp?ini=" + ( args.initialValue ? args.initialValue : "" ), args ); }

/**
Carrega um WebDataWindow
*/
function loadHTMLDW( dataSource, HTMLDest, callBack )
{
	var sArg = dataSource.getArgs(),
		sUrl = dataSource.getUrl(),
		sHTMLDestId = ( YAHOO.lang.isString( HTMLDest ) ? HTMLDest : YAHOO.util.Dom.generateId( HTMLDest ) );
				
	var callBackMain = function ( xml ) {		
		loadHTMLDWCallBack( xml, sHTMLDestId, callBack );
	}
	
	loadXMLDoc( sUrl, callBackMain, sArg );
}


function loadHTMLDWCallBack ( xml, HTMLDest, callBack )
{  
	hideMsgBox ( );

	if ( xml == null ) {
		alert ( "Erro buscando dados no banco." );
		return;
	}

	/** Mostra as mensagens retornadas */
	var htmldwSource = new JSMsg ( callBackXml2Htmldw ( xml ) ),
		erro = false, 
		msgType,
		dom = YAHOO.util.Dom,
		htmldwName = htmldwSource.htmldwName,
		dw, msgID, htmldwName, confirmAction, notConfirmAction;
		
	dw = ( htmldwName && htmldwName.indexOf( "d" ) != 0 ? null : eval( "( typeof " + htmldwName + " == 'undefined' ? null : " + htmldwName + " )" ) );

	for ( i = 1; i <= htmldwSource.getMsgCount ( ); i++ ) {
	
		msgType = htmldwSource.getMsgType( i );
	
		switch (msgType)
		{
			case htmldwSource.DADO: break;
			case htmldwSource.CONFIRMACAO:
				
				msgID = htmldwSource.getMsgID( i );
				
				if ( confirm ( htmldwSource.getMsg ( i ) ) )
				{
					confirmAction = htmldwSource.getMsgByID( msgID + "_CONFIRM" );
					
					if( dw.eventImplemented( confirmAction ) ) {
						eval( "dw." + confirmAction + "( );" );
					}
					else {
						dw.performAction( confirmAction );
					}
					return;
				}
				else
				{
					notConfirmAction = htmldwSource.getMsgByID( msgID + "_NOTCONFIRM" );
					if( notConfirmAction ) {
						if( dw.eventImplemented( notConfirmAction ) ) {
							eval( "dw." + notConfirmAction + "( );" );
						}
						else {
							dw.performAction( notConfirmAction );
						}
						return;
					};
				}
				break;
				
			default:
				htmldwSource.alertMsg ( i );
				erro = erro || ( msgType == htmldwSource.ERRO ) ;
		}
	}	
	
	/** Seta o WebDataWindow */
	if ( !erro )
	{
		if( dw )
			YAHOO.Smartweb.util.dwCleanUp( dw );
		
		if( YAHOO.lang.isString( HTMLDest ) )
			HTMLDest = dom.get( HTMLDest );
		
		if ( dom.inDocument( HTMLDest ) ) 
		{
			//YAHOO.Smartweb.util.disabledStyle( HTMLDest._styleId );
			YAHOO.Smartweb.util.purge( HTMLDest );
			HTMLDest._styleId = YAHOO.Smartweb.util.applyStyles( htmldwSource.style ).id;
			HTMLDest.innerHTML = htmldwSource.webdatawinow;
		}
		else { return; }
		
		/** Executa o script retornado */
		if ( htmldwSource.code ) 
		{
			try {
				evalGlobal( htmldwSource.code );
			} catch ( catch_e ) { }
		}
	}
	
	HTMLDest = null;

	/** Executa o CallBack */
	if ( callBack != null )
		callBack( htmldwSource );

	htmldwSource.cleanUp();
	htmldwSource.code = null;
	htmldwSource.style = null;
	htmldwSource.webdatawinow = null;
	htmldwSource = null;
}

function CacheHTMLDWEntry( )
{
	var expires ;
	var dataSource ;
	var HTMLDest ;
	var callBack ;
	var xml ;
}

function CacheHTMLDW( )
{ 
	this.cacheStorage = new Array( );
}

CacheHTMLDW.prototype.cache = function( dataSource, HTMLDest, callBack, expires )
{
	for ( var i = 0; i < this.cacheStorage.length; i++ )
	{
		if ( equal( this.cacheStorage[i].dataSource, dataSource ) &&
				this.cacheStorage[i].HTMLDest == HTMLDest &&
				equal( this.cacheStorage[i].callBack, callBack ) &&
				equal( this.cacheStorage[i].expires, expires ) )
		{
			return ;
		}
	}

	var sArg = dataSource.getArgs();
	var sUrl = YAHOO.Smartweb.util.getRoot() + "/select-gen/webdatawindowxml.asp";
	var callBackMain = function ( cacheSys )
	{
		this.cacheSys = cacheSys
		this.callBack = function ( xml ) {
			this.cacheSys.callback( xml, dataSource, HTMLDest, expires, callBack );
		}
	}
	callBackMain.callback = this.callback;
	
	loadXMLDoc ( sUrl, new callBackMain( this ), sArg );
}

CacheHTMLDW.prototype.clear = function( )
{
	this.cacheStorage = new Array( );
}

CacheHTMLDW.prototype.callback = function( xml, dataSource, HTMLDest, expires, callBack )
{
	var cacheEntry = new CacheHTMLDWEntry( );
	cacheEntry.expires = expires ;
	cacheEntry.dataSource = dataSource ;
	cacheEntry.HTMLDest = HTMLDest ;
	cacheEntry.callBack = callBack ;
	cacheEntry.xml = xml ;
	this.cacheStorage.push( cacheEntry );
}

/**
Ordena uma árvore XML
*/
function xmlSort ( xmlRoot, compareFunc ) 
{
	xmlQuickSort ( xmlRoot, 0, xmlRoot.childNodes.length - 1, compareFunc );
}

function xmlQuickSort ( xmlRoot, left, right, compareFunc )
{
	//1. Condição de saída da recursão
	if ( right - left <= 0 ) 
		return;
		
	//2. Escolha do pivot
	var pivotIdx = Math.round( ( left + right ) / 2 );
	
	//3. Posicionamento do pivot
	var xmlChilds = xmlRoot.childNodes;
	
	for ( var idx = left;  idx <= right; idx++ ) 
	{
		var compareRet = compareFunc ( xmlChilds[idx], xmlChilds[pivotIdx] );
		
		if ( compareRet < 0 && idx > pivotIdx ) 
		{
			xmlRoot.insertBefore ( xmlChilds[idx], xmlChilds[pivotIdx] );
			pivotIdx += 1;
		}
		else if ( compareRet > 0 && idx < pivotIdx ) 
		{
			xmlRoot.insertBefore ( xmlChilds[idx], xmlChilds[pivotIdx] );
			xmlRoot.insertBefore ( xmlChilds[pivotIdx], xmlChilds[pivotIdx - 1] );
			pivotIdx -= 1 ;
		}
	}
	
	//4. Divisão e conquista
	xmlQuickSort ( xmlRoot, left, pivotIdx - 1, compareFunc ); 
	xmlQuickSort ( xmlRoot, pivotIdx + 1, right, compareFunc );
}

/**
Class JSMsg
este objeto é equivalente ao objeto ucom_msg, contudo, client side.
*/
function JSMsg ( pdw_msg ) {

	this.CONFIRMACAO 	= 0 ;
	this.INFORMACAO		= 1 ;
	this.ERRO 			= 2 ;
	this.ATENCAO 		= 3 ;
	this.DADO			= 4 ; 
	this.SUCESSO 		= 5 ;
	this.dwMsg 			= pdw_msg;
	
	var msgCount = this.getMsgCount ( );
	for ( i = 1; i <= msgCount; i++ ) {
		var msgID = this.getMsgID(i);
		if( msgID ) {
			this[msgID] = this.getMsg(i);
		}
	}
}

JSMsg.prototype.getMsgCount = function ( ) {
	return this.dwMsg.RowCount ( );
}

JSMsg.prototype.getMsg = function ( msgNum ) {
	if ( msgNum <= 0 || msgNum > this.getMsgCount ( ) )
		return null;
		
	return this.dwMsg.GetItem ( msgNum, "tx" );
}

JSMsg.prototype.getMsgType = function ( msgNum ) {
	if ( msgNum <= 0 || msgNum > this.getMsgCount ( ) )
		return null;
		
	return ( this.dwMsg.GetItem ( msgNum, "tp" ) - 0 );
}

JSMsg.prototype.getMsgID = function ( msgNum ) {
	if ( msgNum <= 0 || msgNum > this.getMsgCount ( ) )
		return null;
		
	return this.dwMsg.GetItem ( msgNum, "id" );
}

JSMsg.prototype.getMsgNum = function ( msgID ) {
	
	var id;
	
	msgID = msgID.toUpperCase();
	
	for ( var i = 1; i <= this.getMsgCount ( ); i++ ) {
		id = this.dwMsg.GetItem( i, "id" );
		if ( id && id.toUpperCase () == msgID )
			return i;
	}

	return -1;
}

JSMsg.prototype.getMsgByID = function ( msgID ) {
	return this.getMsg ( this.getMsgNum ( msgID ) );
}

JSMsg.prototype.alertMsg = function ( msgNum ) {
	alert ( this.getMsg ( msgNum ) );
}

JSMsg.prototype.alertMsgAll = function ( msgID ) {

	for ( i = 1; i <= this.getMsgCount ( ); i++ ) {
		if ( this.getMsgType( i ) != this.DADO ) {
			this.alertMsg ( i );
		}
	}
}

JSMsg.prototype.setMsg = function ( msgNum, msg ) {
	if ( msgNum <= 0 || msgNum > this.getMsgCount ( ) )
		return null;
		
	return this.dwMsg.SetItem ( msgNum, "tx", msg );
}

JSMsg.prototype.hasMsgErro = function ( ) {
	
	for ( var i = 1; i <= this.getMsgCount ( ); i++ ) 
		if (this.getMsgType(i) == this.ERRO || this.getMsgType(i) == this.ATENCAO)
			return true;
	
	return false;
}

JSMsg.prototype.hasMsg = function ( ) {
	
	for ( var i = 1; i <= this.getMsgCount ( ); i++ ) 
		if (this.getMsgType(i) != this.DADO)
			return true;
	
	return false;
}

JSMsg.prototype.cleanUp = function() {
	YAHOO.Smartweb.util.dwCleanUp( this.dwMsg );
	this.dwMsg = null;
}

/**
* Faz uma chamada a uma função remota no servidor
*
* @param obj {String} Nome do objeto que implementa a função
* @param lib {String} PBD
* @param lib {Array} Lista de PBD's
* @param args {Object} Dados para a função
* @param callBack {function(msg)} Trigger que será disparado quando a função for executada
* @param cache {Boolean} Guarda no cache do Browser o retorno da função?
* @param async {Boolean} Executa a função de modo asincrono
*/
YAHOO.Smartweb.util.remoteCall = function( obj, lib, args, callBack, cache, async ) 
{
	var callBackMain = function ( xml ) {
		var msg = new JSMsg ( callBackXml2Htmldw ( xml ) );
		msg.alertMsgAll();
		callBack( msg );
		msg.cleanUp();
	}
	
	var argsString;
	argsString = "lib=" + ( YAHOO.lang.isArray( lib ) ? lib.join( "," ) : lib );
	argsString += "&obj=" + obj;
	if( async ) argsString += "&async=1";
	
	//
	if( args ) {
		for ( var arg in args ) {
			if( args[arg] != null && args[arg] != "undefined" )
				argsString += "&" + escape( arg ) + "=" + escape( args[arg] );
		}
	}
	
	var url = YAHOO.Smartweb.util.getRoot() + "/select-gen/obj_func_invoke.asp";
	if( cache ) {
		url += "?" + argsString;
		argsString = null;
	}
	
	loadXMLDoc ( url, callBackMain, argsString );
}

YAHOO.Smartweb.util.addAutocomplete = function( inputEl, dataSource, opt ) 
{
	if( !inputEl ) return null;
	
	//Datasource
	if( YAHOO.lang.isString( dataSource ) ) 
	{
		var dataSource = new YAHOO.util.XHRDataSource( dataSource );
	    dataSource.responseType = YAHOO.util.XHRDataSource.TYPE_TEXT;
		dataSource.responseSchema = {
	        recordDelim: "\r\n",
	        fieldDelim: "\t" 
	    };
		dataSource.maxCacheEntries = 10;
	}

	//Configura o autocomplete nos campos cidade e bairro
	var wrapperEl = document.createElement( "div" ), 
		autocompleteEl = document.createElement( "div" ),
		dom = YAHOO.util.Dom,
		autocomplete;

	if( dom.getX( inputEl ) <= 0 )  return null;
		
	dom.addClass( wrapperEl, "yui-skin-sam" );
	
	document.body.appendChild( wrapperEl );
	wrapperEl.appendChild( autocompleteEl );
	
	wrapperEl.style.position = "absolute";
	wrapperEl.style.left = dom.getX( inputEl ) + "px" ;
	wrapperEl.style.width = ( opt && opt.width ? opt.width : inputEl.offsetWidth - 2 ) + "px";
	wrapperEl.style.zIndex = 1000;
	
	//Cria o autocomplete
	autocomplete = new YAHOO.widget.AutoComplete( inputEl, autocompleteEl, dataSource );
	autocomplete.useShadow = true;
    autocomplete.minQueryLength = 1;
	autocomplete.maxResultsDisplayed = 10; 
	autocomplete.useIFrame = false;
	autocomplete.autoHighlight = false;
	autocomplete.queryDelay = 0.2;
	
	autocomplete.containerExpandEvent.subscribe( 
		function ( oSelf ) {
			wrapperEl.style.top = ( dom.getY( inputEl ) + 1 ) + "px";
		}
	);
	
	return autocomplete;
}

/**
* Adiciona o componente autocomplete do YAHOO em um campo da webdatawindow
*
* @param dw webdatawindow
* @param row registro
* @param col nome da coluna na datawindow
* @param dataSource {YAHOO.widget.DataSource} Datasource para obtenção dos dados para popular o autocomplete
* @param dataSource {String} URL da página que retornará a lista de dados. Neste caso será criado um DS_XHR, 
*							com as seguintes configurações {maxCacheEntries: 10, responseType:TYPE_FLAT, Schema:["\r\n", "\t"]}
* @param opt <{width:number}> Configurações
*/
YAHOO.Smartweb.util.addAutocompleteInHTMLDW = function( dw, row, col, dataSource, opt ) 
{
	return this.addAutocomplete( dw.findControl( col, row - 1, true ), dataSource, opt );
}

function xmlParser ( xmlStr )
{
	if (window.ActiveXObject)
	{
		var xmlDom = new ActiveXObject('Microsoft.XMLDOM'); 
		xmlDom.async = false;
		xmlDom.loadXML (xmlStr); 
		return xmlDom;
	}
	else
	{
		return new DOMParser().parseFromString( xmlStr, 'text/xml');
	}
}

/**********************************************************************************/
/* Metodos AJAX para o carregamento de varias webdatawindows
/**********************************************************************************/

function loadMultiploHTMLDW( dataSource, HTMLDest, callBacks, callBack )
{
	var sArg = '';

	// Agrupa os argumentos de todas WebDataWindows
	for (var i=0; i<dataSource.length; i++) {
		
		sArg += dataSource[i].getArgs ( i ) + "&";
	}

	sArg += "qt=" + dataSource.length;
	 
	var sUrl = YAHOO.Smartweb.util.getRoot() + "/select-gen/webmultiplodatawindowxml.asp";
	var callBackMain = function ( xml ) {
		hideMsgBox ( );
		
		if ( xml == null ) {
			alert ( "Erro buscando dados no banco." );
			return;
		} 
	
		var htmldwSource = new JSMsg ( callBackXml2Htmldw ( xml ) );
		loadMultiploHTMLDWCallBack ( htmldwSource, HTMLDest, callBacks, dataSource.length );
		
		if( callBack ) { callBack( htmldwSource ); }
		
		htmldwSource.cleanUp()
	}
	
	loadXMLDoc ( sUrl, callBackMain, sArg );
}

function loadMultiploHTMLDWCallBack ( htmldwSource, HTMLDest, callBacks, qtdWebDataWindows )
{  		
	/** Mostra as mensagens retornadas */
	var erro = false, 
		msgType, 
		currHtmldwName = null, 
		dom = YAHOO.util.Dom,
		msgID,
		htmldwName,
		dw,
		htmlCSS,
		htmlDW;

	for ( i = 1; i <= htmldwSource.getMsgCount ( ); i++ ) {

		msgType = htmldwSource.getMsgType( i );

		switch (msgType)
		{
			case htmldwSource.DADO: 
			
				var msgID = htmldwSource.getMsgID( i );
				
				if ( msgID.substr(0, 10) == 'htmldwName' ) {
					currHtmldwName = htmldwSource.getMsgByID ( msgID );
				}
					
				break;
			case htmldwSource.CONFIRMACAO:

				msgID = htmldwSource.getMsgID( i ),
				htmldwName = currHtmldwName,
				dw = eval( htmldwName );
				
				if ( confirm ( htmldwSource.getMsg ( i ) ) )
				{
					var confirmAction = htmldwSource.getMsgByID( msgID + "_CONFIRM" );
					if( dw.eventImplemented( confirmAction ) ) {
						eval( "dw." + confirmAction + "( );" );
					}
					else {
						dw.performAction( confirmAction );
					}
					return;
				}
				else
				{
					var notConfirmAction = htmldwSource.getMsgByID( msgID + "_NOTCONFIRM" );
					if( notConfirmAction ) {
						if( dw.eventImplemented( notConfirmAction ) ) {
							eval( "dw." + notConfirmAction + "( );" );
						}
						else {
							dw.performAction( notConfirmAction );
						}
					};
					return;
				}
				break;
			
			default:
				htmldwSource.alertMsg ( i );
				erro = erro || ( msgType == htmldwSource.ERRO ) ;
		}
	}

	for (var contDataSource = 0; contDataSource < qtdWebDataWindows; contDataSource++ ) {

		/** Seta a WebDataWindow na pagina HTML */
		if ( !erro ) {			
		
			htmlCSS = htmldwSource.getMsgByID( 'style_' + ( contDataSource + 1 ) );
			htmlDW = htmldwSource.getMsgByID( 'webdatawindow_' + ( contDataSource + 1 ) );
			
			if ( dom.inDocument( HTMLDest[contDataSource] ) ) 
			{	
				//YAHOO.Smartweb.util.disabledStyle( HTMLDest[contDataSource]._styleId );
				YAHOO.Smartweb.util.purge( HTMLDest[contDataSource] );
				YAHOO.Smartweb.util.applyStyles( htmlCSS );
				HTMLDest[contDataSource].innerHTML = htmlDW;
			}
			else { return; }
		
			/** Executa o script retornado */
			var script = htmldwSource.getMsgByID( 'code_' + ( contDataSource + 1 ) );
			if ( script != null ) 
			{
				try {
					eval ( script );
				} catch ( catch_e ) { 
					YAHOO.error.show( { 
						msg: catch_e.message + ", " + HTMLDest[contDataSource].id,
						notifyAdmin: true
					} );
				}
			}			
		}
		
		/** Executa o CallBack  */
		if ( callBacks[contDataSource] != null && callBacks[contDataSource] != "") {
			callBacks[contDataSource]( htmldwSource, contDataSource + 1 );
		}	
	}
}

/*
Server Events
*/
(function(){
	/*
	Gerencia eventos gerados no servidor
	*/
	var serverEvents = function() {};
	
	/*
	Inicializa o serverEvents
	*/
	serverEvents.init = function() {		
		serverEvents.eventHandles = new Array();
	};
	
	/*
	Registra um interesse em um evento
	*/
	serverEvents.register = function(evt, callback) {
		this.eventHandles.push({ evt:evt, callback:callback });
		
		if( this.eventHandles.length == 1 ) {
			this.get();
		}
	};
	
	/*
	Desregistra o interesse em um evento
	*/
	serverEvents.unregister = function(evt) {
		var evtHdlIdx = this.find(evt);
		if( evtHdlIdx >= 0 ) this.removeHandle( idx );
		
		if( this.eventHandles.length == 0 ) {
			clearInterval( this.intervalHdl );
		}
	};
	
	/*
	PRIVATE
	Obtem os eventos gerados
	*/
	serverEvents.get = function() {
		this.intervalHdl = setInterval( function() {
			var args = "", evt;
			
			for( var idx = 0; idx < serverEvents.eventHandles.length; idx++ ) {
				evt = serverEvents.eventHandles[idx].evt;
				args += "tp=" + evt.type + "&id=" + evt.id + "&";
			}
			
			loadDoc ( YAHOO.Smartweb.util.getRoot() + "/select-gen/srv_event.asp", serverEvents.getCallback, args );
		}, 15000 );
	};
	
	/*
	PRIVATE
	Trata a obtencao dos eventos gerados
	*/
	serverEvents.getCallback = function(content) {
		if( content == "" ) { return; }
		content = content.split("\r\n");
		for( var idx = 0; idx < content.length; idx++ ) {
			serverEvents.trigerEventCallbacks(content[idx]);
		}
	};
	
	/*
	PRIVATE
	Compara se dois eventos sao iguais
	*/
	serverEvents.compareEvents = function(evtA, evtB) {
		return ( evtA.type == evtB.type && evtA.id == evtB.id );
	};
	
	/*
	PRIVATE
	Remove um handle especifico
	*/
	serverEvents.removeHandle = function(idx) {
		this.eventHandles[idx] = this.eventHandles[0];
		this.eventHandles.shift();
	};
	
	/*
	PRIVATE 
	Dispara o callback do evento
	*/
	serverEvents.trigerEventCallbacks = function(evtStr) {
		evtStr = evtStr.split("#");
		var evtHdlIdx = this.find({type:evtStr[0], id:evtStr[1]});  
		if( evtHdlIdx >= 0 ) {
			this.eventHandles[evtHdlIdx].callback();
		}
	};
	
	/*
	PRIVATE
	Obtem o eventHandle do evento
	*/
	serverEvents.find = function(evt) {
		for( var idx = 0; idx < this.eventHandles.length; idx++ ) {
			if( this.compareEvents( evt, this.eventHandles[idx].evt ) ) {
				return idx;
			}
		}
		return -1;
	};
	
	serverEvents.init();
	YAHOO.Smartweb.util.serverEvents = serverEvents;
})();
/*****************************************************************************/

/**
* Abre um URL dentro de um iframe em um Painel FullScreen
*
* @param url {String} URL 
* @param title {String} Título do painel
*/
YAHOO.Smartweb.util.openMedia = function ( src, type, title, args )
{
	var dom = YAHOO.util.Dom, 
		width = dom.getViewportWidth() - 35, 
		height = dom.getViewportHeight() - 35;
	
	var panel = new YAHOO.widget.Panel( dom.generateId( null, "_panel" ), 
			{	close:true,  
			    visible:false,  
			    draggable:false,
				modal:true,
		    	constraintoviewport:true,
				fixedcenter:true,
				width:width + "px",
				height:height + "px" } );	
				
	dom.addClass( document.body, "yui-skin-sam" ); 			
	
	//var objectMedia = document.createElement( "object" ); 
	//objectMedia.style.height = ( height - 52 ) + "px";
	//objectMedia.style.width = "100%";
	//objectMedia.type = type;
	//objectMedia.data = src;
	
	var objectMedia = '<object type="' + type + '" width="100%" height="' +  ( height - 52 ) + 'px" data="' + src + '"><a href="' + src + '">clique aqui<\/a> para visualizar o documento gerado<\/object>'; 
	
	panel.setHeader( title );
	panel.setBody( objectMedia );
	panel.render( document.body );
	panel.show();
	
	return panel;
}

/**
* Abre um URL dentro de um iframe em um Painel FullScreen
*
* @param url {String} URL 
* @param title {String} Título do painel
*/
YAHOO.Smartweb.util.openNestedPage = function ( url, title, width, height )
{
	var dom = YAHOO.util.Dom;
	
	if( !width ) width = dom.getViewportWidth() - 35;
	if( !height ) height = dom.getViewportHeight() - 35;
	
	var panel = new YAHOO.widget.Panel( dom.generateId( null, "_panel" ), 
			{	close:true,  
			    visible:false,  
			    draggable:true,
				modal:true,
		    	constraintoviewport:true,
				fixedcenter:true,
				width:width + "px",
				height:height + "px" } );	
				
	dom.addClass( document.body, "yui-skin-sam" ); 			
	
	var iframePdf = document.createElement( "iframe" ); 
	iframePdf.style.height = ( height - 52 ) + "px";
	iframePdf.style.width = "100%";
	iframePdf.frameBorder = "0";
	
	panel.setHeader( title );
	panel.setBody( iframePdf );
	panel.render( document.body );
	panel.show();

	iframePdf.src = url;
	
	return panel;
}

/**
* Abre um PDF em um Painel FullScreen
*
* @param url {String} URL do PDF
* @param title {String} Título do painel
*/
YAHOO.Smartweb.util.openPdf = function ( url, title )
{
	var panel = this.openNestedPage( url + "#navpanes=0&toolbar=1", title );	
	
	//showMsgBox();
	//panel.hideEvent.subscribe( function ( type, args, obj ) { hideMsgBox();	} );	
}

/**
* Abre um PDF gerado na pasta temporária em um Painel FullScreen
*
* @param id {String} ID do documento
* @param title {String} Título do painel
*/
YAHOO.Smartweb.util.openPdfTemp = function( id, title )
{
	this.openPdf( this.getRoot() + "/scripts-gen/getTempFile.asp?type=application/pdf&id=" + id, title );
}

/**
* Inicia o download de um arquivo temporário
* 
* @param id {String} ID do arquivo 
*/
YAHOO.Smartweb.util.downloadTemp = function( id )
{
	window.location.href = this.getRoot() + "/scripts-gen/getTempFile.asp?download=1&id=" + id;
}

/**
* Abre um RTF gerado na pasta temporária em um Painel FullScreen
*
* @param id {String} ID do documento
* @param title {String} Título do painel
*/
YAHOO.Smartweb.util.openRtfTemp = function( id, title )
{
	alert( 1 );
	window.location.href = this.getRoot() + "/scripts-gen/getTempFile.asp?download=1&filename=" + escape( title ) + ".rtf&type=application/rtf&id=" + id;
	window.location.href = this.getRoot() + "/scripts-gen/getTempFile.asp?download=1&filename=" + escape( title ) + ".rtf&type=application/rtf&id=" + id;
	return;
	
	
	try { 
		var w = new ActiveXObject('Word.Application'); 	
		if (w != null) {
			w.Visible = true;
			w.Documents.Open( "http://" + window.location.host + window.location.pathname + "/../../scripts/getTempFile/" + id  ); 
		}
	}
	catch( exp_e ) {
		var iframePdf = document.createElement( "iframe" ); 
		iframePdf.style.display = "none";
		document.body.appendChild( iframePdf );
		iframePdf.src = this.getRoot() + "/scripts-gen/getTempFile.asp?download=1&filename=" + escape( title ) + ".rtf&type=application/rtf&id=" + id;
	}
	
}

YAHOO.Smartweb.util.purge = function( d ) 
{
	var i, l, n;
	
	if( YAHOO.lang.isArray( d ) ) {
		l = d.length;
		for (i = 0; i < l; i += 1) {
			this.purge( d[i] );
		}
	}
	else {

		if( d.onclick ){ d.onclick = null; }
		if( d.onchange ){ d.onchange = null; }
		if( d.onblur ){ d.onblur = null; }
		if( d.onfocus ){ d.onfocus = null; }
		if( d.onkeypress ){ d.onkeypress = null; }

		a = d.childNodes;
		if (a) {
			l = a.length;
			for (i = 0; i < l; i += 1) {
				this.purge(d.childNodes[i]);
			}
			
			try {
				if( l > 0 )
					d.innerHTML = "";
			}
			catch( catch_e ) { }
		}
	}
}

/**
* Limpa a DataWindow
*/
YAHOO.Smartweb.util.dwCleanUp = function( dw )
{
	if( !dw ) return;
	
	dw.cols = null;
	dw.rows = null;
	dw.gobs = null;
	dw.submitForm = null;
	dw.dataForm = null;
	dw.actionField = null;
	dw.contextField = null;
}


/**
Serializa os atributos de um objeto para serem enviados em uma requisição HTTP
*/
YAHOO.Smartweb.util.obj2http = function ( obj ) {
	var args = new Array();	
	for ( var attr in obj ) { 
		if( obj[attr] != null && obj[attr] != "undefined" )
			args.push( escape( attr ) + "=" + escape( obj[attr] ) ); 
	}
	return args.join( "&" );
};

/**
Parse de uma string no formato abaixo em um objeto
?v1=1{&v2=2}
*/
YAHOO.Smartweb.util.http2obj = function( http ) {
	var obj = {};
	if( !http ) http = location.search;
	if( http.charAt( 0 ) == "?" ) http = http.substring( 1 );
	http = http.split( "&" );
	
	for( var i = 0; i < http.length; i++ ) {
		http[i] = http[i].split( "=" );
		if( http[i].length > 1 )
			obj[http[i][0]] = decodeURIComponent( http[i][1] );
	}
	return obj;
}

YAHOO.namespace( "error" );

YAHOO.error.show = function( opt ) {	
	//debugger;

	var dom = YAHOO.util.Dom, 
		panel = new YAHOO.widget.Panel( dom.generateId( null, "_panel" ), 
				{	close:true,  
					visible:false,  
					draggable:false,
					modal:true,
					draggable:true,
					constraintoviewport:true,
					fixedcenter:true,
					width: "400px",
					height: null } );
					
	dom.addClass( document.body, "yui-skin-sam" ); 	
	panel.setHeader( "Ooops..." );
	panel.setBody( 
		"<div class='msg error'>Ocorreu uma falha inesperada na aplicação</div>" + 
		"<div class=frame style='padding-left: 23px;'>" + YAHOO.Smartweb.util.nl2br( opt.msg ) + "</div>" + 
		( opt.notifyAdmin ? "<ul class='ctrl panel'><li><button class=bt><div class='ico with-label mailUnread'>Reportar Falha</div></button></li></ul>" : "" ) );
	panel.render( document.body );
	panel.show( );	
	
	YAHOO.util.Event.on( 
		YAHOO.util.Selector.query( "button", panel.body, true ),
		"click",
		function() {
			YAHOO.error.notify( "xdanielgs@gmail.com;diogo@medicware.com.br", opt );
			panel.hide();
		});
		
	return true;
};

YAHOO.error.notify = function( to, opt ) {
	var iframePdf = document.createElement( "iframe" ),
		cfg_emp = YAHOO.util.Dom.get( "cfgLogo" ); 
	
	opt.cfg_emp = ( cfg_emp ? cfg_emp.alt : "n/a" );
	opt.build = YAHOO.Smartweb.util.getBuild();
	opt.login = YAHOO.Smartweb.util.getLogin();
	opt.url = location.href;
	opt.gecko = YAHOO.env.ua.gecko;
	opt.ie = YAHOO.env.ua.ie;
	opt.opera = YAHOO.env.ua.opera;
	
	if( !opt.msgNotify ) opt.msgNotify = opt.msg;
	
	iframePdf.style.display = "none";
	document.body.appendChild( iframePdf );
	iframePdf.src = YAHOO.Smartweb.util.getRoot() + "/scripts-gen/error-gen_panel.asp?id=" + YAHOO.util.Dom.generateId( iframePdf ) + "&t=" + new Date();
	iframePdf.error = opt;
}

YAHOO.error.stackTrace = function() {
	var callstack = [];
	var isCallstackPopulated = false;
	
	try { i.dont.exist+=0; } //doesn't exist- that's the point 
	catch(e) 
	{
		if (e.stack) //Firefox
		{ 
			var lines = e.stack.split("\n");
			for (var i=0, len=lines.length; i<len; i++) {
				if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
					callstack.push(lines[i]);
				}
			}
			//Remove call to printStackTrace()
			callstack.shift();
			isCallstackPopulated = true;
		}
		else if (window.opera && e.message) //Opera
		{ 
			var lines = e.message.split("\n");
			for (var i=0, len=lines.length; i<len; i++) {
				if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
					var entry = lines[i];
					//Append next line also since it has the file info
					if (lines[i+1]) {
						entry += " at " + lines[i+1];
						i++;
					}
					callstack.push(entry);
				}
			}
			//Remove call to printStackTrace()
			callstack.shift();
			isCallstackPopulated = true;
		}
	}
	if (!isCallstackPopulated) { //IE and Safari
		var currentFunction = arguments.callee.caller.caller;
		while (currentFunction) {
			var fn = currentFunction.toString();
			var fname = fn.substring(fn.indexOf("function") + 8, fn.indexOf("(")) || "anonymous";
			callstack.push( { 
					name: fname,
					script: fn,
					toString: function() { return this.name; }
				} );
			currentFunction = currentFunction.caller;
		}
	}
	
	return callstack;
}

window.onerror = function( msg, url, linenumber ) {
	
	var stackTrace = YAHOO.error.stackTrace();
		msgNotify = "";

	msgNotify = msg + " na linha " + linenumber + " at " + location.pathname;
	
	if( stackTrace.length > 0 ) {
		"\n\nSTACKTRACE:\n";
		
		for ( var i = 0; i < stackTrace.length; i++ ) {
			msgNotify += "\n0" + ( i + 1 ) + "----\n" + 
						stackTrace[i].script + "\n";	
		}
	}
	
	return YAHOO.error.show( { 
			msg: msg + " at " + location.pathname,
			msgNotify: msgNotify, 
			notifyAdmin: true
		} );
};
