
/* Globals */
 var ie5 = ( document.all && document.getElementById );
 var moz = ( !document.all && document.getElementById );
 var DEBUG = false;
/* End Globals */

/* Keycode constants */
var KEY_UP = 38;
var KEY_DOWN = 40;
var KEY_LEFT = 37;
var KEY_RIGHT = 39;
var KEY_ESCAPE = 27;
var KEY=F10 = 121;
var KEY_SPACE = 32;
var KEY_TAB = 9;
var KEY_ENTER = 13;


 /* Object definitions */
function Filter( fltrid, fltrlbl, fltrtyp ){
  this.id = fltrid;
  this.label = fltrlbl;
  this.type = fltrtyp;
}

/*
 * Represents folders.
 */
function Folder( fid, flbl ){
  this.id = fid;
  this.label = flbl;
  this.folders = new Array();
  this.filters = new Array();
  this.elements = new Array();
}

/*
 * Represents Elements.
 */
function Element( eid,desc,type, classid ){
  this.id = eid;
  this.type = type;
  this.description = desc;
  this.classid = classid;
}


///////////////////////////////////////////////////////////////////////////////
// Elments Object to provide namespacing for general purpose scripts.
///////////////////////////////////////////////////////////////////////////////
function Elements(){
}

///////////////////////////////////////////////////////////////////////////////
// StringBuilder
///////////////////////////////////////////////////////////////////////////////
function StringBuilder(){
  this.__strings__ = [];
  return this;
}
StringBuilder.prototype.append = function( str ){
  this.__strings__.push( str );
  return this;
}
StringBuilder.prototype.toString = function(){
  return this.__strings__.join("");
}


///////////////////////////////////////////////////////////////////////////////
// eDataSet
///////////////////////////////////////////////////////////////////////////////
function eDataSet(){
  this.data = [];
  this.meta = [];
  this.names = [];
  this.types = [];
}


///////////////////////////////////////////////////////////////////////////////
// eSqlList
///////////////////////////////////////////////////////////////////////////////


// NOTE!!! Take note of the default url for this object.
// If you are operating from something other than a /request  url
// you are going to have to set this, perhaps to "ws" if you are operating
// from a jsp at the root.
function eSqlList( cb ){
  this.name = "one";
  this.statements = [];
  this.callback = cb;
  this.req = DomFactory.createXmlHttp();
  this.asynch = true;
  this.url = DomFactory.checkUrl( "../ws" );
  this.error = null;
}


eSqlList.prototype.setAsynch = function( yesno ){
  this.asynch = yesno;
}

eSqlList.prototype.setUrl = function( url ){
  this.url = DomFactory.checkUrl( url );
}

eSqlList.prototype.addStatement = function( s ){
  this.statements[this.statements.length] = s;
}

eSqlList.prototype.captureMeta = function ( cols, dataSet ){
  var me = this;
  dataSet.meta.length = cols.length;
  dataSet.types.length = cols.length;
  dataSet.names.length = cols.length;
  for( var i = 0; i < cols.length; i++ ){
    try{
      var attrs = cols[i].attributes;
      var val = attrs.getNamedItem( 'meta' ).nodeValue;
      dataSet.meta[i] = val; 
      val = attrs.getNamedItem( 'type' ).nodeValue;
      dataSet.types[i] = val;
      val = attrs.getNamedItem( 'name' ).nodeValue;
      dataSet.names[i] = val;
    }catch( e ){
    }
  }

}

eSqlList.prototype.setCookie = function(){
try{
   var cookie = document.cookie;
   if( !isNull( cookie ) ){
   	  if( cookie.indexOf( "JSESSIONID" ) > -1 ){
   	 	if( cookie.indexOf( ";" ) > -1 ){
   	 	    var str = cookie.substring( cookie.indexOf( "JESSIONID" ), cookie.indexOf( ";" ) );
   	 	    this.req.setRequestHeader( "Cookie", str );
   	 	}else{
   	  		this.req.setRequestHeader( "Cookie", cookie );
   	  	}
   	  }
   }
}catch( er ){
//alert( er.message );
}
}

eSqlList.prototype.execute = function (  ) {
  var me = this;
  me.req.open( "POST", me.url, me.asynch );
//  me.setCookie();
  me.req.onreadystatechange = function (){
    if( me.req.readyState == 4 && me.req.status == 200 ) {
      var returnDom = me.req.responseXML;
      checkForException( me, returnDom );
      var sqlTags = getSqlTags( returnDom );
      
      for( var k = 0; k < sqlTags.length; k++ ){
        var metaCaptured = false;
        var rows = sqlTags[k].childNodes;
        for( var j = 0; j < rows.length; j++ ){
          var cols = rows[j].childNodes;
          if( !metaCaptured ){
            me.captureMeta( cols, me.statements[k].dataSet );
            metaCaptured = true;
            me.statements[k].columnCount = cols.length;
          }
          columnData = new Array();
          for( var i = 0; i < cols.length; i++ ){
            if( !cols[i].hasChildNodes() || cols[i].firstChild.nodeValue == null ){
              columnData[columnData.length] = "";
            }
            else{
              columnData[columnData.length] = cols[i].firstChild.nodeValue; 
            }
          }
          me.statements[k].dataSet.data[me.statements[k].dataSet.data.length] = columnData;
        }
      }
      me.callback( me );
    }
  }
  this.req.setRequestHeader( "Content-Type", "text/xml" );
  // Build the dom, and the esql components.
  var soapDom = DomFactory.createSoapDOM();
  var env = soapDom.getElementsByTagName( "SOAP-ENV:Body" );
  var sqlNode = soapDom.createElement( "esql:sql" );
  sqlNode.setAttribute( "xmlns:esql", "http://www.enterprise-elements.com/sql" );
  env[0].appendChild( sqlNode );
  
  var dsNode = soapDom.createElement( "esql:datasource" );
  sqlNode.appendChild( dsNode );
  var transNode = soapDom.createElement( "esql:transaction" );
  sqlNode.appendChild( transNode );
  // Note: Current implementation creates a single transaction per network
  // roundtrip. No limit on the number of statements in transaction tho.
  for( var i = 0; i < me.statements.length; i++ ){
    var statementNode = soapDom.createElement( "esql:statement" );
    statementNode.setAttribute( "id", i );
    transNode.appendChild( statementNode );
    var statementText = soapDom.createElement( "esql:text" );
    var text = soapDom.createTextNode( me.statements[i].statement );
    statementText.appendChild( text );
    statementNode.appendChild( statementText );
    // Add any paramters for the current statement.
    for( var j = 0; j < me.statements[i].parameters.length; j++ ){
          var p = me.statements[i].getParameter( j );
          if( p != null ){
            var parameterNode = soapDom.createElement( "esql:parameter" );
            parameterNode.setAttribute( "type", p.type );
            var tnode = soapDom.createTextNode( p.value );
            parameterNode.appendChild( tnode );
            statementNode.appendChild( parameterNode );
          }
    }
  }
  this.req.send( soapDom );
}

function getSqlTags( dom ){
     var trans = 'transaction';
     var sql = 'sql';
     if( ie5 ){
       trans = 'esql:transaction';
       sql = 'esql:sql';
     }

     var transList = dom.getElementsByTagName( trans );
     if( !isNull( transList ) && !isNull( transList[0] ) ){
       return transList[0].getElementsByTagName( sql );
     } else {
       return dom.getElementsByTagName( 'sql' );
     }
}

function checkForException( slist, dom ){
  var excep = 'exception';
  if( ie5 ){
    excep = 'esql:exception';
  }
  var enodes = dom.getElementsByTagName( excep );

  if( !isNull( enodes ) && enodes.length > 0 ){
    var attrs = enodes[0].attributes;
    //    alert( attrs.getNamedItem('message').nodeValue );
    var er =  new Error( attrs.getNamedItem('message').nodeValue );
    slist.error = er;
      alert( attrs.getNamedItem('message').nodeValue );
  }
}


///////////////////////////////////////////////////////////////////////////////
// eSqlStatement
///////////////////////////////////////////////////////////////////////////////
/*
 * Wraps the text of a sql statement, and
 * provides an array to store the parameters.
 * Bind variables should be desginated with the
 * ? character in the statement. The parameter
 * array is position dependant.
 */
function eSqlStatement( statement ){
  this.statement = statement;
  this.parameters = new Array();
  this.dataSet = new eDataSet();
  this.error = null;
  this.columnCount = null;
}
eSqlStatement.prototype.addParameter = function( p ){
  this.parameters[this.parameters.length] = p;
}
eSqlStatement.prototype.getParameter = function( p ){
  if( p < this.parameters.length && p >= 0 ){
    return this.parameters[p];
  }
  return null;
}


///////////////////////////////////////////////////////////////////////////////
// eParameter
///////////////////////////////////////////////////////////////////////////////

function eParameter( type, value ){
  this.type = type;
  this.value = value;
}
eParameter.prototype.dump = function(){
  return this.type+", "+this.value;
}

eParameter.NUMBER = "number";
eParameter.DATE = "date";
eParameter.VARCHAR = "varchar";
//eParameter.CLOB = "clob";



/* End Object definitions */

///////////////////////////////////////////////////////////////////////////////
// EventUtils 
///////////////////////////////////////////////////////////////////////////////
var EventUtils = {};

EventUtils.addEventHandler = function( targetElement, event, handler ){
  if( targetElement && targetElement.addEventListener ){
    targetElement.addEventListener( event, handler, false );
  }else if( targetElement && targetElement.attachEvent ){
    targetElement.attachEvent( "on"+event, handler );
  }
}
EventUtils.addEventHandlerById = function( id, event, handler ){
  var el = ge( id );
  EventUtils.addEventHandler( el, event, handler );
}
EventUtils.removeEventHandler = function( element, eventName, handlerFunction, prop ){
  if( window.event )element.detachEvent( 'on'+eventName, handlerFunction );
  else element.removeEventListener( eventName, handlerFunction, prop );
}
EventUtils.removeEventHandlerById = function( id, event, handler, prop ){
  var el = ge( id );
  EventUtils.removeEventHandler( el, event, handler, prop );
}
EventUtils.getTargetElement = function(){
  if( window.event ) return window.event.srcElement;
  return EventUtils.getTargetElement.caller.arguments[0].target;
}
EventUtils.getNormalizedTargetElement = function(tagName,element)
{
    while( element.tagName != tagName )
    {
        element = element.parentNode;
    }
    return element;
}
EventUtils.convertIEEvent = function( evt ){
    evt.charCode = (evt.type == 'keypress')?evt.keyCode : 0;
    evt.eventPhase = 2;
    evt.isChar = (evt.charCode > 0 );
    evt.pageX = evt.clientX + document.body.scrollLeft;
    evt.pageY = evt.clientY + document.body.scrollTop;
    evt.preventDefault = function(){
      this.returnValue = false;
    };
    if( evt.type == 'mouseout' ){
      evt.relatedTarget = evt.toElement;
    }else if( evt.type == 'mouseover' ){
      evt.relatedTarget = evt.fromElement;
    }
    evt.stopPropagation = function(){
       this.cancelBubble = true;
    };

    evt.target = evt.srcElement;
    evt.time = (new Date).getTime();
    return evt; 
}
EventUtils.getEvent = function(){
  if( window.event ) { //Switch IE event to DOM event.
    return EventUtils.convertIEEvent(window.event);
  }
  return EventUtils.getEvent.caller.arguments[0];
}

EventUtils.getKeyCharacter = function( evt )
{
    var code = 13;
    if (evt.keyCode){code = evt.keyCode;}
    else if (evt.which){code = evt.which;}
    return String.fromCharCode(code);
}
    

EventUtils.stopEventPropagation = function ( evt ){
  if( window.event ){
    if( isNull(evt) ){ evt = window.event; }
    evt.cancelBubble = true;
    evt.returnValue = false;
  }
  else{
    if( evt.stopPropagation ){evt.stopPropagation(); }
    evt.preventDefault();
  }
}


///////////////////////////////////////////////////////////////////////////////
// FormUtils
///////////////////////////////////////////////////////////////////////////////
var FormUtils = new Object();
FormUtils.getSelectedOptions = function( list ){
  var indexes = new Array();
  for( var i = 0; i < list.options.length; i++ ){
    if( list.options[i].selected ){
      indexes.push( list.options[i].firstChild.nodeValue );
    }
  }
  return indexes;
}
FormUtils.getSelectedValues = function( list ){
 var indexes = [];
  for( var i = 0; i < list.options.length; i++ ){
    if( list.options[i].selected ){
      if( ie5 ){
        indexes.push( list.options[i].value );
      }else{
        indexes.push( list.options[i].attributes.getNamedItem("value").nodeValue );
      }
    }
  }
  return indexes;

}
FormUtils.getSelectedIndexes = function( list ){
  var indexes = new Array();
  for( var i = 0; i < list.options.length; i++ ){
    if( list.options[i].selected ){
      indexes.push( i );
    }
  }
  return indexes;
}
FormUtils.addHiddenInput = function( frm_id, hidden_name, hidden_value ){
  // Note that if the input is added to the document, you cannot set the type.
  var ip = ee.ce( "input" );
  ip.type = "hidden";
  ip.value = hidden_value;
  ip.name = hidden_name;
  ip.id = hidden_name;
  ee.ge( frm_id ).appendChild( ip );
}
FormUtils.removeHiddenInput = function( frm_id, hidden_name ){
  var inputList = ee.getn( ee.ge( frm_id ), "input" );
  for( var i = 0; i < inputList.length; i++ ){
      if( hidden_name == inputList[i].name ){
        ee.ge( frm_id ).removeChild( inputList[i] );      
        break;
      }
  }
}

FormUtils.containsInputById = function( frm_id, id ){
  var inputList = ee.getn( ee.ge( frm_id ), "input" );
  for( var i = 0; i < inputList.length; i++ ){
    if( id == inputList[i].id ){ return true;}
  }
  return false;
}

FormUtils.addOptions = function( select, optionsList ){
  Array.forEach(optionsList, function(item)
  {
     var opt = ee.ceAsChild("option",select);
     ee.addText(opt,item.label);
     if(item.value)
     {
         opt.setAttribute("value",item.value);
     }
     if(item.selected)
     {
         opt.setAttribute("selected", "selected");
     }
  });
}

///////////////////////////////////////////////////////////////////////////////
// Helper Functions in the global namespace.
///////////////////////////////////////////////////////////////////////////////
function isNull( obj ){
  return ((typeof(obj) == "undefined") || (obj == null));
}

function instanceOf(object, constructor) { 
   while (object != null) { 
      if (object == constructor.prototype) 
         return true; 
      object = object.__proto__; 
   } 
   return false; 
}

function ge( id ){
  return document.getElementById( id );
}

function getn( nde, tagName ){
  return nde.getElementsByTagName( tagName );
}

function gecn( searchClass, node, tag ){
    var classElements = new Array();
    if( node == null ){
        node = document;
    }
    if( tag == null ){
        tag = '*';
    }
    var els = getn( node, tag );
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
    for(  i = 0, j = 0; i < elsLen; i++ ){
        if( pattern.test( els[i].className ) ){
            classElements[j++] = els[i];
        }
    }
    return classElements;
}

// <meta name="id" content="1135">
function getMetaTagMappedValue( id ){
    var metaList = document.getElementsByTagName( 'meta' );
    for( var i = 0; i < metaList.length; i++ ){
        if( !isNull( metaList[i].attributes['name'] ) && metaList[i].attributes['name'].nodeValue == id ){
            return metaList[i].attributes['content'].nodeValue;
        }
    }
    return null;
}

function normalizeEvent( ){
  if( window.event )return window.event;
  else return normalizeEvent.caller.arguments[0];
}

function addEventHandler( element, eventName, handlerFunction, prop ){
   if( window.event )element.attachEvent( 'on'+eventName, handlerFunction );
    else element.addEventListener( eventName, handlerFunction, prop );
}

function removeEventHandler( element, eventName, handlerFunction, prop ){
  if( window.event )element.detachEvent( 'on'+eventName, handlerFunction );
  else element.removeEventListener( eventName, handlerFunction, prop );
}

/*
function addToFavorites( id, type ){
  var sql = new eSqlStatement("INSERT INTO tuple (type_id, parent_id, child_id, name, validation_dt) VALUES(?, (-1 * UID), ?, \'\',SYSDATE)");
  sql.addParameter( new eParameter( 'number',type ) );
  sql.addParameter( new eParameter( 'number',id ) );
  sqlList = new eSqlList( function(){} );
  sqlList.addStatement( sql );
  sqlList.execute();
  window.status = "Added ";
}
*/
// Sql Functions...
function tupleToFolder( parentId, childId, typeId, func ){
  var sql = new eSqlStatement("INSERT INTO tuple (type_id, parent_id, child_id, name, validation_dt) VALUES(?, ?, ?, \'\',SYSDATE)");
  sql.addParameter( new eParameter( 'number',typeId ) );
  sql.addParameter( new eParameter( 'number',parentId ) );
  sql.addParameter( new eParameter( 'number',childId ) );
  sqlList = new eSqlList( func );
  sqlList.addStatement( sql );
  sqlList.execute();
  window.status = "Added ";
}

function removeTupleFromFolder( parentId, childId, typeId, func ){
  var sql = new eSqlStatement( "DELETE FROM tuple WHERE type_id = ? AND parent_id = ? AND child_id = ?" );
  sql.addParameter( new eParameter( 'number',typeId ) );
  sql.addParameter( new eParameter( 'number',parentId ) );
  sql.addParameter( new eParameter( 'number',childId ) );
  sqlList = new eSqlList( func );
  sqlList.addStatement( sql );
  sqlList.execute();
  window.status = "Removed ";
}

function updateUserWorkspace( wid, cb ){
  alert( "Workspaces are not supported in this version of Elements." );
}


eUrl = function(urlstr)
{
    this.base = "";
    this.queryString = {};
    this.build(urlstr);
}

eUrl.prototype.build = function(url)
{
    var uc = url.split('?');
    var uqs = [];
    if( uc )
    { 
        this.base = uc[0];
        if(  uc.length > 1 )
        {
            uqs = uc[1].split('&');
            for( var i = 0; i < uqs.length; i++ )
            {
                var kv = uqs[i].split('=');
                if( kv[0] && kv[1] )
                {
                    this.queryString[kv[0]] = kv[1];
                }
            }
        }
    }
};

eUrl.prototype.toString = function()
{
    var urlComp = [];
    urlComp[0] = this.base;
    for( var i in this.queryString )
    {
        urlComp[urlComp.length] = encodeURIComponent(i)+"="+encodeURIComponent(this.queryString[i]);
    }
        
    return DomFactory.buildUrl(urlComp);

};

eUrl.prototype.addValue = function( name,value )
{
    this.queryString[name] = value;
}; 

eUrl.prototype.containsValue = function( name )
{
    for( var i in this.queryString )
    {
        if( i == name ){ return true; }
    }
    return false;
};


function newElement( cid, url, refreshOpener, lid )
{
    if( isNull( url ) )
    {
        url =  "../request/elementForm?CLASS.CLASS_ID="+cid+"&verb=New";
    }
    else
    {
        var tmp = new eUrl(url);
        
        tmp.addValue( "CLASS.CLASS_ID",cid );
        tmp.addValue("verb", "New");
        if( !isNull(lid) ){ tmp.addValue("lid",lid); }
        
        url = tmp.toString();
    }   
        
    if (cid !=213) {
    	if( !refreshOpener ) 
    	{    
        	ee.popNoRefresh(url,800,500);
    	}
   	 else
   	 {
        	ee.popAndRefresh(url,800,500);
    	}
    } 
    else {
	document.location = url;
    }
             
}

function copyAttributes( sourceNode, targetNode ){
    if( sourceNode.nodeType != 1 ) return;
    if( !isIE ){
      for( var i = 0; i < sourceNode.attributes.length; i++ ) {
        var nde = sourceNode.attributes[i];
        targetNode.attributes.setNamedItem( nde.cloneNode( false ) );
      }
    }
    else{
      for( var i = 0; i < sourceNode.attributes.length; i++ ) {
        var nde = sourceNode.attributes[i];
        if( nde.nodeName.toLowerCase() == 'onclick' ){
          if( targetNode.attachEvent )
              targetNode.attachEvent( 'onclick', expand );
        }
        else if( nde.nodeName.toLowerCase() == 'class' ){
          targetNode.setAttribute( "className", nde.nodeValue );
        }
        else{
          targetNode.setAttribute( nde.nodeName, nde.nodeValue );
          //alert( nde.nodeName + " = " + nde.nodeValue );
        }
      }
    }
}

function setPage(){
  if( self != top && (self.name=='contentFrame'||self.name=='treeView')){ // loaded in frames
    var soapDom = DomFactory.createSoapDOM();
    var env = soapDom.getElementsByTagName( "SOAP-ENV:Body" );
    var bNode = soapDom.createElement( "ejs:browserState" );
    bNode.setAttribute( "xmlns:ejs", "http://www.enterprise-elements.com/js" );
    bNode.setAttribute( "frame", self.name );
    bNode.setAttribute( "url", location.href );
    bNode.setAttribute( "width", getWindowWidth() );
    env[0].appendChild( bNode );
    
    var req = DomFactory.createXmlHttp();
    var url = DomFactory.checkUrl( "../ws" );
    
    req.open( "POST", url, true );
    req.onreadystatechange = function (){
        if( req.readyState == 4 && req.status == 200 ) {

        }
    }
    req.setRequestHeader( "Content-Type", "text/xml" );
    req.send( soapDom );
 }
}

var goWin;
function go( url, w, h ){
  if( isNull( w ) ){ w = 450;}
  if( isNull( h ) ){ h = 450; }
  w += 32;	// Chrome constants.
  h += 96
  var x = (screen.width-w)/2;
  var y = (screen.height-h)/2;
  var options = "menubar=no,toolbar=no,height="+h+",width="+w+",titlebar=no,scrollbars=yes,resizable=yes,left="+x+",top="+y; 
  goWin = window.open( url,"_blank", options );
  if( goWin )
  {
  	goWin.moveTo( x,y );
  	goWin.focus();
  }
  return goWin;
}

function reload(){
  location.replace( location.href );
}

function toggleDiv( objectName ){
  var obj = document.getElementById( objectName );
  if ( obj.style.display == "none" ){
      obj.style.display = "block";
  }
  else {
  	obj.style.display = "none";
  }
}

function toggleDivImg( objName, imgObj ){
    var obj = document.getElementById( objName );
    if( obj.style.display == "none" ){
        obj.style.display = "block";
        imgObj.src = "../images/icon_collapse.gif";
        imgObj.alt = "Hide";
        imgObj.title = "Hide";
    }
    else{
        obj.style.display = "none";
        imgObj.src = "../images/icon_expand.gif";
        imgObj.alt = "Show";
        imgObj.title = "Show";
    }
}

// TODO: Fix the diffs between 5.5 and 6.0.
function handCursor( elem ){
  if( elem != null ){
    try{
      if( ie5 ){
        if( elem.style.cursor == "hand" ) {
  	      elem.style.cursor = "auto";
        } else {
          elem.style.cursor = "hand";
        }
      }else{
        if( elem.style.cursor == 'pointer' ){
          elem.style.cursor = 'auto';
        }else{
          elem.style.cursor = 'pointer';
        }
      }
    }catch( exception ){alert( exception.message );}
  }
}

function pointer( ){
  var elem = EventUtils.getTargetElement();
  if( elem != null ){
    try{
      if( ie5 ){
        if( elem.style.cursor == "hand" ) {
  	      elem.style.cursor = "auto";
        } else {
          elem.style.cursor = "hand";
        }
      }else{
        if( elem.style.cursor == 'pointer' ){
          elem.style.cursor = 'auto';
        }else{
          elem.style.cursor = 'pointer';
        }
      }
    }catch( exception ){alert( exception.message );}
  }
}

function checkFrame()
{
    var rt = true;
    
    // check for content-start anchor.
    var cs = ee.ge('content-start');
    if( isNull(cs) )
    {
        cs = ee.ce("a");
        cs.name = "content-start";
        cs.id = "content-start";
        cs.href ="#content-start";
        cs.accesskey ="2";
        
        document.body.insertBefore( cs, document.body.firstChild );
    
    
    }
    
    if( self == top && isNull(window.opener))
    {
        // not loaded frames
        addCloseLink();
            
        var a = ee.ce("a");
        a.href = "../index.html";
        a.title = "Returns to my Home Page.";
         
        var img = ee.ce("img");
        img.src = "../images/logo.gif";
        img.id = "bannerT"
        img.alt = "Elements Logo";
        img.height = 48;
        img.width = 115;
        img.border = 0;
        img.setAttribute("style", "position:absolute; top:0em; left:0em;");
        a.appendChild(img);
            
      //  document.body.insertBefore( a, document.body.lastChild );
        rt = false;
  //      try{ee.ge("content-start").focus();}catch(e){}
    }
    return rt;
}

function addCloseLink()
{
    var closer = ee.ce("a");
    closer.href="javascript:window.close();";
    EventUtils.addEventHandler( closer, "click", window.close, false );
    closer.innerHTML = "Close this window."
    closer.setAttribute( "style", "text-align:right;" );
    closer.setAttribute( "accesskey", "C" );
    closer.setAttribute( "id", "closer" );
            
  //  document.body.insertBefore( closer, document.body.lastChild );
}

function closeWin()
{
    window.close();
}

function checkTextArea( oid ){
  var ta = documentGetElementById( oid );
    // Get the string and check the length,
    // if greater than 4k, raise error.
}


function getWindowWidth() {
    var windowWidth=0;
    if( typeof(window.innerWidth)=='number' ) {
        windowWidth = window.innerWidth;
    }
    else {
        if( document.documentElement && document.documentElement.clientWidth ) {
            windowWidth = document.documentElement.clientWidth;
        }
        else {
            if( document.body && document.body.clientWidth ) {
                windowWidth = document.body.clientWidth;
            }
        }
    }
    return windowWidth;
}

function getWindowHeight() {
    var windowHeight=0;
    if( typeof(window.innerHeight) == 'number' ) {
        windowHeight=window.innerHeight;
    }
    else {
        if( document.documentElement && document.documentElement.clientHeight ) {
            windowHeight = document.documentElement.clientHeight;
        }
        else {
            if( document.body&&document.body.clientHeight ) {
                windowHeight = document.body.clientHeight;
            }
        }
    }
    return windowHeight;
}


function getIcon( name ){
  var img = document.createElement( "img" );
  img.setAttribute( "src", "../images/"+name );
  return img;
}

function getAnchor( href, text, clazz, id ){
  var a = document.createElement( "a" );
  a.setAttribute( "href", href );
  if( ie5 )a.setAttribute( "className", clazz );
  else a.setAttribute( "class", clazz );
  a.setAttribute( "id", id );
  var t = document.createTextNode( text );
  a.appendChild( t );
  return a;
}

function getComplexAnchor( href, clazz, id, target ){
  var a = document.createElement( "a" );
  a.setAttribute( "href", href );
  if( ie5 )a.setAttribute( "className", clazz );
  else a.setAttribute( "class", clazz );
  a.setAttribute( "id", id );
  a.setAttribute( "target", target );

  return a;
}

function parseId( did ){
  return did.substr( 2, did.length - 2 );
}

function childElementCount( node ){
  var c = 0;
  for( var i = 0; i < node.childNodes.length; i++ ){
    if( node.childNodes[i].nodeType == 1 ) c++;
  }
  return c;
}

function removeChildren( node ){
    while( node.childNodes.length > 0 ){
        node.removeChild( node.firstChild );
    }
}

function getNodeById(element, id) {
    var children = element.childNodes
    for (var i=0;i<children.length;i++) {
        if (children[i].id) {
            if (children[i].id == id) {
                return children[i];
            }
        }
        var child = getNodeById(children[i], id);
        if (child != null) {
            return child;
        }
    }
    return null;    
}






///////////////////////////////////////////////////////////////////////////////
// DomFactory
///////////////////////////////////////////////////////////////////////////////

function DomFactory(){
}

DomFactory.createXmlHttp = function xmlHttpCreateInstance() {
  var xmlhttp = false;
  var arrNames = ["MSXML2.XMLHTTP.5.0", "MXSML2.XMLHTTP.4.0", "MXSML2.XMLHTTP.3.0",
                    "MXSML2.XMLHTTP", "Microsoft.XMLHTTP"];
  for( var i = 0; i < arrNames.length; i++ ){
    try{
      xmlhttp = new ActiveXObject( arrNames[i] );
      return xmlhttp;
    }catch( ignore ){}
  }
  xmlhttp = false;
  if( !xmlhttp && typeof XMLHttpRequest!='undefined' ){
    xmlhttp = new XMLHttpRequest();
  }
  return xmlhttp;
}

DomFactory.createXmlHttp2 = function(){
	var xmlhttp = false;
    /*@cc_on @*/
	/*@if (@_jscript_version >= 5)
	// JScript gives us Conditional compilation, we can cope with old IE versions.
	// and security blocked creation of the objects.
	 try {
	  xmlhttp = new ActiveXObject( "Msxml2.XMLHTTP" );
	 }catch( e ){
	  try {
	   xmlhttp = new ActiveXObject( "Microsoft.XMLHTTP" );
	  }catch( E ){
	   xmlhttp = false;
	  }
	 }
	@end @*/
    
	if( !xmlhttp && typeof XMLHttpRequest!='undefined' )
    {
	  xmlhttp = new XMLHttpRequest();
	}
	return xmlhttp;
}

DomFactory.createDOM = function createDOM( rootNS, root ){
  var dom = null;
  if( window.ActiveXObject ){
    var arrNames = ["MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0",
                    "MSXML2.DOMDocument", "Microsoft.XmlDom"];
    for( var i = 0; i < arrNames.length; i++ ){
      try{
        dom = new ActiveXObject( arrNames[i] );
        if( rootNS != null && root != null ){
          var e = dom.createNode( 1, root, rootNS );
          if( e == null ) alert( "Unable to create root node" );
          dom.documentElement = e;
	}
        return dom;
      }catch( ignore ){}
    }
  }
  else if( document.implementation && document.implementation.createDocument ){
    dom = document.implementation.createDocument( rootNS, root, null );
  }
  if( dom == null ) alert( "The dom is null. " );
  return dom;
}

DomFactory.createSoapDOM = function createSOAPDOM(){
  var dom = DomFactory.createDOM( "http://schemas.xmlsoap.org/soap/envelope/", "SOAP-ENV:Envelope" );
  var root = dom.documentElement;
  // Add namespace declarations.
  root.setAttribute( "xmlns:xsi", "http://www.w3.org/1999/XMLSchema-instance" );
  root.setAttribute( "xmlns:xsd", "http://www.w3.org/1999/XMLSchema" );
  // what about SOAP-Head??
  var envelope = dom.createElement( "SOAP-ENV:Body" );
  envelope.setAttribute("xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/" );
  root.appendChild( envelope );
  return dom;
}

DomFactory.createElement = function( dom, ns, name ){
  var node = null;
  if( ie5 ){
  
  }
  else{
  
  }
  return node;
}

DomFactory.createAttribute = function( dom, node, name, value ){
  var attr = null;
  attr = dom.createAttribute( name );
  attr.nodeValue = value;
  node.setAttributeNode( attr );
  return attr;
}

DomFactory.setValue = function( dom, node, value ){
  switch( node.nodeType ){
    case 1:{
      var tn = dom.createTextNode( value );
      node.appendChild( tn );
      break;
    }
    case 2:{
      node.nodeValue = value;
      break;
    }
  }
}
/*
DomFactory.setCookie = function( xmlReq ){
try{
   var cookie = document.cookie;
   if( !isNull( cookie ) ){
   	  if( cookie.indexOf( "JSESSIONID" ) > -1 ){
   	 	if( cookie.indexOf( ";" ) > -1 ){
   	 	    var str = cookie.substring( cookie.indexOf( "JESSIONID" ), cookie.indexOf( ";" ) );
   	 	    xmlReq.setRequestHeader( "Cookie", str );
   	 	}else{
   	  		xmlReq.setRequestHeader( "Cookie", cookie );
   	  	}
   	  }
   }
}catch( er ){
//alert( er.message );
}
}
*/

DomFactory.getSessionCookie = function( ){
var str = null;
try{
   var cookie = document.cookie;
   if( !isNull( cookie ) ){
   	  if( cookie.indexOf( "JSESSIONID" ) > -1 ){
   	 	if( cookie.indexOf( ";" ) > -1 ){
   	 	    str = cookie.substring( cookie.indexOf( "JESSIONID="+10 ), cookie.indexOf( ";" ) );
   	 	    xmlReq.setRequestHeader( "Cookie", str );
   	 	}else{
   	  		var a = cookie.split( "=" );
   	  		if( !isNull( a ) && a.length > 1 ){
   	  		  str = a[1];
   	  		}
   	  	}
   	  }
   }
}catch( er ){
//alert( er.message );
}
return str;
}

DomFactory.checkUrl = function( url ){
   var urlStr = window.location.toString();
   var sessionLoc = urlStr.indexOf( ";jsessionid=" );
   var queryBegins = urlStr.indexOf( "?" );
   if( sessionLoc > -1 ){
     try{
       var sessionid = urlStr.substring( sessionLoc, queryBegins );
       url = url + sessionid;
       }catch( eatit ){}
   }else{
       var sessionid = DomFactory.getSessionCookie();
       if( !isNull( sessionid ) ){
         url = url + ";jsessionid=" + sessionid;
       }
   }
   return url;
}

/**
 * Argument is a string array. First element must be the url (w/o query string)
 * Additional elements can be name value pairs of the form name=value, these will 
 * be formed into a query string and the complete url is returned.
 */
 //TODO: Escape the string.
DomFactory.buildUrl = function( urlComponents )
{
    var sessionid = DomFactory.getSessionCookie();
    var rval = new StringBuilder();
    rval.append( urlComponents[0] ).append( ";jsessionid=");
    rval.append( DomFactory.getSessionCookie() );
    for( var i = 1; i < urlComponents.length; i++ )
    {
        if( i == 1){ rval.append( "?" ); }
        else{ rval.append( "&" ); }
        rval.append( urlComponents[i] );
    }
    
    return rval.toString();
}

/* 
 * Takes the url for the request, and the callback function.
 * The callback function is passed the xmlhttp.responseText as its only
 * parameter.
 */
DomFactory.htmlGet = function( url, callback, qs ){
   var xmlhttp = DomFactory.createXmlHttp();
   if( !isNull( qs ) ){
     url = DomFactory.checkUrl( url );
     url += qs;
   }else{
     url = DomFactory.checkUrl( url ) ;
   }
   xmlhttp.open( "GET", url );
   xmlhttp.onreadystatechange = function() {
     if( xmlhttp.readyState == 4 && xmlhttp.status == 200 ){
        callback( xmlhttp.responseText );
     }
   }
   xmlhttp.send(null);
}


DomFactory.getXml = function( url, callback ){
   var xmlhttp = DomFactory.createXmlHttp2();
   xmlhttp.open( "GET", url );
   xmlhttp.onreadystatechange = function() {
     if( xmlhttp.readyState == 4 && xmlhttp.status == 200 ){
        callback( xmlhttp );
     }
   }
   xmlhttp.send(null);
}

DomFactory.getXmlAsynch = function( url ){
    var xmlhttp = DomFactory.createXmlHttp();
   xmlhttp.open( "GET",  url, false );
   xmlhttp.send(null);
   return xmlhttp.responseXml;
}

DomFactory.getTextSynchronous = function( url ){
    var xmlhttp = DomFactory.createXmlHttp();
   xmlhttp.open( "GET",  url, false );
   xmlhttp.send(null);
   return xmlhttp.responseText;
}

DomFactory.checkForError = function( dom ){
  var excep = 'exception';
  if( ie5 ){
    excep = 'esql:exception';
  }
  var enodes = null;
  try{
    enodes = dom.documentElement.getElementsByTagName( excep );
  }catch( error ){
    window.status ='There was a problem with the return document.'; 
    return true;  
  }
  if( !isNull( enodes ) && enodes.length > 0 ){
    var attrs = enodes[0].attributes;
    window.status = attrs.getNamedItem('message').nodeValue;
    return true;
  }
  
  return false;
}

DomFactory.getETableModel = function( id, callback ){
   var xmlhttp = DomFactory.createXmlHttp();
   var url = "../request/filter?xform=json&id="+id;
   xmlhttp.open( "GET",  url );
   xmlhttp.onreadystatechange = function() {
     if( xmlhttp.readyState == 4 && xmlhttp.status == 200 ){
        callback( xmlhttp.responseText );
     }
   }
   xmlhttp.send(null);
}

///////////////////////////////////////////////////////////////////////////////
// eTransformContent: Tagging to replace a DOM element with dynamic content.
// Implements command pattern w/execute method.
///////////////////////////////////////////////////////////////////////////////

function eTransformContent( src, element, queryString, callback ){
  this.src = DomFactory.checkUrl( src )+'?'+eTransformContent.checkQueryString( queryString );
  this.element = element;
  this.callback = callback;
  return this;
}

eTransformContent.prototype.execute = function(){
	this.getContent();
}

eTransformContent.prototype.getContent = function(){
	var me = this;
	var xmlhttp = DomFactory.createXmlHttp();
    xmlhttp.open( "GET", me.src );
    xmlhttp.onreadystatechange = function() 
    {
       if( (xmlhttp.readyState == 4) && (/^(200|304)$/.test(xmlhttp.status.toString())) )
       {
          me.setContent( xmlhttp.responseText );
       }
    };
   xmlhttp.send(null);
}
  
eTransformContent.prototype.setContent = function( content ){
    document.getElementById( this.element ).innerHTML = content;
    if( !isNull(this.callback) )
    {
        this.callback();
    }
}

eTransformContent.checkQueryString = function( qstr ){
    var len = qstr.split( '&amp;' );
    if( len.length > 1 ){
        var t = new StringBuilder();
        for( var i = 0; i < len.length; i++ ){
            t.append( len[i] ).append( '&' );
        }
        qstr = t.toString();
    }
    return qstr;
}



/*
function getClassDataLists(){
  var lists = new Array();
  if( top.symbolList ){
    lists.push( top.symbolList );
    lists.push( top.typeList );
    lists.push( top.classList );
  }
  else {
    var win = self;
    while( win.opener ){
      if( win.opener.top.symbolList ){
        lists[lists.length] = win.opener.top.symbolList;
        lists[lists.length] = win.opener.top.typeList;
        lists[lists.length] = win.opener.top.classList;
        break;
      }
      else if( win.opener.symbolList ){
        lists[lists.length] = win.opener.top.symbolList;
        lists[lists.length] = win.opener.top.typeList;
        lists[lists.length] = win.opener.top.classList;
        break;
      }
      else{
        win = win.opener;
      }
    }
  }
  return lists;
}  
*/


///////////////////////////////////////////////////////////////////////////////
// ee is a namespace function for utilities that do not naturally fit 
// in another class.
///////////////////////////////////////////////////////////////////////////////
function ee(){
}
// get element by id.
ee.ge = function( id ){
	return document.getElementById( id );
}
// get element by tag name.
ee.getn = function( nde, tagName ){
  if( nde ) return nde.getElementsByTagName( tagName );
  else return document.getElementsByTagName( tagName );
}

// create element.
ee.ce = function( type, attrs )
{
	return ee.addAttributes(document.createElement( type ), attrs);
}
// create text node.
ee.ct = function ( text ){
	return document.createTextNode( text );
}

// write debug message to current page.
ee.dm = function( t ){
    if( !DEBUG ){ return; }
	if( !ee.ge( 'debug-panel' ) ){
	  var bd = ee.ge( 'body-contents' );
	  var d = ee.ceAsChild( 'div', bd );
	  d.appendChild( ee.ce( 'div' ).appendChild( ee.ct( 'Debug Info' ) ) );
	  d.id = 'debug-panel';
	  var s = ee.ce( 'ul' );
	  d.appendChild( s );
	  d.add = function( text ){
		  var l = ee.ce( "li" );
		  s.appendChild( l );
		  l.appendChild( ee.ct( text ) );
	  };
	}
	try{
	ee.ge('debug-panel').add( t );
	}catch( error ){}
}

// find the position of an element. returns [left,top]
ee.pos = function findPos( obj )
{
    var curleft = curtop = 0;
    if ( obj.offsetParent )
    {
        curleft = obj.offsetLeft
        curtop = obj.offsetTop
        while ( obj = obj.offsetParent )
        {
            curleft += obj.offsetLeft
            curtop += obj.offsetTop
        }
    }
    return [curleft, curtop];
}

// give an element the style of a hyperlink
ee.linkStyleMouseOver = function( evt ){
    var el = EventUtils.getTargetElement();
    el.style.cursor = 'pointer';
    el.style.textDecoration = "underline";
    EventUtils.addEventHandler( el, "mouseout", ee.autoLinkMouseOut );

}
// change "hyperlink style" back to normal.
ee.autoLinkMouseOut = function( evt ){
    var el = EventUtils.getTargetElement();
    el.style.cursor = 'auto';
    el.style.textDecoration = "none";
    EventUtils.removeEventHandler( el, "mouseout", ee.autoLinkMouseOut );
}

// create elem as a child of prnt
ee.ceAsChild = function( elem, prnt, attrs ){
    var e = document.createElement( elem );
    prnt.appendChild( e );
    if( attrs ){ ee.addAttributes(e,attrs); }
    return e;
}

ee.addAttributes = function(elem, attrObj)
{
    if( !isNull(elem) && !isNull(attrObj) )
    {
        for( a in attrObj )
        {
           elem.setAttribute(a, attrObj[a]);
        }
    }
    return elem;
}

ee.addText = function(prnt, text){
    prnt.appendChild( document.createTextNode(text) );
}

// cross browser method of adding a cell to a table row.
ee.addCell = function( row ){
    if( ie5 ){
        return row.insertCell();
    }else{
        return ee.ceAsChild( "td", row );
    }
}
  
// cross browser method of adding a row to a table (for IE)
// or to the tablebody (for all others).
ee.addRow = function( tbl ){
    if( ie5 ){
        return tbl.insertRow();
    }else{
        return ee.ceAsChild( "tr", tbl );
    }
}

// open in new window and refresh caller.
ee.popAndRefresh = function( url, w, h )
{
    var win = ee.popNoRefresh(url,w,h);
    EventUtils.addEventHandler( win, "unload", function(evt)
    {
        window.location.replace( location.href );
        setTimeout( function(){win.focus();}, 300 );
    });
}

ee.popNoRefresh = function( url, w, h )
{
    var sw = self.screen.width;
    var sh = self.screen.height;
 
    var left = (sw - w)/2;
    var top = (sh - h)/2;
    
    var opts = "height="+h+",width="+w+",left="+left+",top="+top+",menubar=no,toolbar=no,resizable=yes,scrollbars=yes,locationbar=no";
    var win = window.open( url, "_blank", opts, false );
   
    return win;
}

// open in new window.
ee.pop = function( href, w, h ){
   go( href, w, h );
}

// go to new url.
ee.nav = function(url)
{
	if(ie5){window.navigate(url);}
	else{window.location = url;}
}

// wait cursor.
ee.wc = function( onoff ){
   if( onoff ){
       ee.getn( null, "body" )[0].style.cursor = "wait";
   }else{
       ee.getn( null, "body" )[0].style.cursor = "auto";
   }
}

// handler for onclick paired to onkeypress to toggle/open a hidden div,
// can be used on a div (w/tabindex=0/-1/n) or an anchor. If on anchor
// the href should be set to the id of the inner div.
ee.activateHidden = function(evt, id)
{
    evt = EventUtils.getEvent();
    if( (evt.type == 'keypress') && (evt.keyCode != 13) ){ return false; }
    var opt = ee.ge(id)
    if ( opt.style.display == "block" )
    {
        opt.style.display = "none";
    }
    else 
    {
        opt.style.display = "block";
    }
    EventUtils.stopEventPropagation(evt);
}


ee.hotkey = function(evt)
{
    evt = EventUtils.getEvent();
    alert( evt.altKey +" hotkey");
    if( evt.type == 'keypress' && evt.altKey )
    {
        var code = 0;
        if (evt.keyCode){code = evt.keyCode;}
        else if (evt.which){code = evt.which;}
        var character = String.fromCharCode(code);
        if( character == 'h' )
        {
            frames['treeView'].focus();
            alert( 'focused treeView' );
        }
        else if( character == 'c' )
        {
            frames['contentFrame'].focus();
            alert( 'contentFrame focused.' );
        }
    
    }
}

ee.createEmbed = function( parent_id, src, width, height, altText )
{
    if( ee.ge(parent_id) )
    {
        ee.ge( parent_id ).innerHTML = ee.getEmbedString( src, width, height, altText );
    }
}

ee.getEmbedString = function( src, width, height, titleText ){
    var c = new StringBuilder();
    if( isNull( titleText ) ) { titleText = ""; }
    c.append('<embed src="').append( src ).append( '" type="image/svg+xml" ' );
    c.append( ' width="' ).append( width ).append('px" ');
    if( height != null ){c.append( '  height="' ).append( height );}
//    c.append( '" title="').append(titleText);
    c.append( '" alt="').append(titleText);
    c.append( '" pluginspage="http://www.adobe.com/svg/viewer/install/"');
    if(ie5){ c.append( ' wmode="transparent" '); }
    
    c.append(' ></embed>' );
    return c.toString();
}

ee.popSqlPickListDetails = function( id, title ){


}

ee.changeSystemEmail = function( val ){
      var sqld = new eSqlStatement( "delete from parameter where id = 1 and parameter = 'PROCESS_EMAIL' and type_id = 52" );
      var sqli = new eSqlStatement("insert into parameter ( id, parameter, value, type_id ) values ( 1, 'PROCESS_EMAIL', ?, 52 )");
      sqli.addParameter( new eParameter( 'varchar',val ) );
      sqlList = new eSqlList( ee.emailChanged );
      sqlList.addStatement( sqld );
      sqlList.addStatement( sqli );
      if( val == '1' )sqlList.emailState = 'On';
      else sqlList.emailState = 'Off';
      sqlList.execute();
      return false;
};

ee.changeDynamicRefresh = function( val ){
      var sqld = new eSqlStatement( "delete from parameter where id = 0 and parameter = 'TEMPLATE_CACHE_DYNAMIC' and type_id = 52" );
      var sqli = new eSqlStatement("insert into parameter ( id, parameter, value, type_id ) values ( 0, 'TEMPLATE_CACHE_DYNAMIC', ?, 52 )");
      sqli.addParameter( new eParameter( 'varchar',val ) );
      sqlList = new eSqlList( function()
      {
          DomFactory.htmlGet( '../request/cacheReload', function(){alert("Dynamic Cache Settings Changed.");}, '?cn=xslt' );
      });
      sqlList.addStatement( sqld );
      sqlList.addStatement( sqli );
      sqlList.execute();
      return false;
};
  
ee.emailChanged = function ( list ){
      window.status = "Email turned "+list.emailState;
      alert( "Email turned "+list.emailState );
      return false;
};

ee.validateElementFormUrl = function( url ){
    if( isNull( url ) )
    {
        url =  "../request/elementForm?id=";
    }
    return url;
    
};


ee.reversePurple = function( elem, v )
{
return;
/*
    var c,b; 
    if( v == 'over' )
    {
       c = '#ffffff';
       b = '#aa44bb';
    }
    else
    {
       c = '#4080D4';
       b = '#ffffff';
    }
    elem.style.backgroundColor = b;
    var e = elem;
    while( elem ){ if(elem.style){elem.style.color = c;} elem = elem.firstChild; }
    */
 };

///////////////////////////////////////////////////////////////////////////////
// Allows transform content to be used similarly to other library ajaxUpdate functions.
// url is the source of plain text (always html).
// element_id is the id of the element which will have its innerHTML set as a result.
// queryString is any required http query string that will be appended to the url.
// callback is the (optional) function that will be called on completion of the process.
///////////////////////////////////////////////////////////////////////////////
ee.ajaxUpdate = function( url, element_id, queryString, callback )
{
    new eTransformContent( url, element_id, queryString, callback ).execute();
};

///////////////////////////////////////////////////////////////////////////////
// eDialog -- a JS equivalent to JDialog? Someday maybe.
//
///////////////////////////////////////////////////////////////////////////////
function eDialog( parentElement, showCloseButton ){
	this.containingNode = parentElement;
	this.height = 400;
	this.width = 600;
	this.__base__ = document.createElement( 'div' );
	this.containingNode.appendChild( this.__base__ );
	var b = this.__base__;
	b.style.position = "absolute";
	b.style.display = 'none';
	b.style.height =  this.height+"px";
	b.style.width = this.width+"px";
	b.style.zIndex = 1000;
	
	if( document.all ){
	    this.__ifr__ = ee.ceAsChild( 'iframe', this.__base__ );
		var ifr = this.__ifr__;
		ifr.tabIndex = '-1';
		ifr.src = 'javascript:false;';
		ifr.style.position = "absolute";
		ifr.style.position.top = this.__base__.style.top;
		ifr.style.position.left = this.__base__.style.left;
		ifr.style.width = "100%";
		ifr.style.height = "100%";
		ifr.style.zIndex = 1010;
		ifr.frameBorder = 0;
//		ifr.style.padding = "7px";
		
		/*b.style.filter = "progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')"
		               + "progid:DXImageTransform.Microsoft.Alpha(Opacity=95)"; */

	}
    this.__createTitleBar__( showCloseButton );
	this.__createPanel__();
	this.listeners = new Array();
}
eDialog.prototype.__createTitleBar__ = function( showClose ){
	this.titleBar = ee.ceAsChild( 'div', this.__base__ );
	var tb = this.titleBar.style;
	tb.position = "absolute";
	tb.top = this.__base__.style.top
	tb.left = this.__base__.style.left
	tb.height = "16px";
	tb.width = "100%";
	tb.backgroundColor = "#4080d4";
//    tb.backgroundColor = "#bbbbff";
	tb.color = "white";
	tb.display = "block";
    tb.borderRight = "2px solid #bbbbbb";
	tb.borderTop = "2px solid #e0e0e0";
	tb.borderLeft = "2px solid #e0e0e0";
	tb.zIndex = 1022;
	if( showClose ){
	    var cb = ee.ceAsChild( 'img', this.titleBar );
	    cb.src = "../images/close-box.gif";
   	    cb.style.position = "absolute";
	    cb.style.top = "1px";
	    cb.style.right = "1px";
	    var me = this;
	    cb.onclick = function(){
	        eDialog.releaseDialog( me );
	    }
	}
}

eDialog.prototype.__createPanel__ = function(){
    this.panel = ee.ceAsChild( 'div', this.__base__ );
    this.panel.id = "eDialog-panel";
    this.panel.tabindex = 0;
    var s = this.panel.style;
	s.position = "absolute";
	s.height = "100%";
	s.width = "100%";
	s.top = "18px";
	s.left = "0px";
	s.zIndex = 1020;
	s.overflow = "auto";
	
	s.backgroundColor = "#ffffbb";
	s.borderBottom = "2px solid #bbbbbb";
	s.borderRight = "2px solid #bbbbbb";
	s.borderTop = "2px solid #e0e0e0";
	s.borderLeft = "2px solid #e0e0e0";
	
}

eDialog.prototype.release = function(){
	eDialog.releaseDialog( this );
}

eDialog.releaseDialog = function( dialog ){
  try{
      dialog.containingNode.removeChild( dialog.__base__ );
  }catch( error ){}
  for( var i = 0; i < dialog.listeners.length; i++ ){
      dialog.listeners[i] = null;
  }
}

eDialog.prototype.setTitle = function( title ){
   var h = ee.ceAsChild( "span", this.titleBar );
   h.style.textAlign = "center";
   h.appendChild( ee.ct( title ) );
}

eDialog.prototype.add = function( node ){
	this.panel.appendChild( node );
	
}

eDialog.prototype.set = function( node ){
	this.panel.importNode( node, true );
}

eDialog.prototype.show = function(){
	var vp = eDialog.viewPortSize();
	var left = (vp[0]/2)-(this.width/2);
	var tp = (vp[1]/2)-(this.height/2)-(vp[1]*.12);
	if( left + this.width > vp[0] ){
		left = vp[0]-(this.width + 20 );	
	}
	ee.dm( left+", "+tp+", "+vp.join(',' )+' ,'+(left+this.width));
	this.__show__( left, tp );
}

eDialog.prototype.showAt = function( left, tp ){
	this.__show__( left, tp );
}

eDialog.prototype.setZIndex = function( index ){
	this.__base__.style.zIndex = index;
}

eDialog.prototype.__show__ = function( left,tp ){
	var vp = eDialog.viewPortSize();
	if( this.containingNode.offsetLeft +left +this.width  > vp[0] ){
		left -= vp[0]-(this.containingNode.offsetLeft +left +this.width + 15 );
	}
    
    this.__dosize__();
    var con = this.__base__;
	con.style.top = tp+"px";
	con.style.left = left+"px";
	con.style.display = 'block';
   
   for( var i = 0; i < this.listeners.length; i++ ){
        if( this.listeners[i] && this.listeners[i].notify ){
            this.listeners[i].notify( this );
        }
    }
}

eDialog.prototype.setBackgroundClassName = function( bk ){
    if( bk ){
		this.panel.className = bk;
	}
}

eDialog.prototype.setHeight = function( h ){
	this.height = h;
	this.__dosize__();
}

eDialog.prototype.__dosize__ = function(){
    this.__base__.style.height =  this.height+"px";
	this.__base__.style.width = this.width+"px";
	this.panel.style.height = (this.height-18)+"px";
    this.panel.style.width = (this.width)+"px";
	if( this.__ifr__ ){
	    this.__ifr__.style.height = this.__base__.style.height;
	    this.__ifr__.style.width = this.__base__.style.width;
	}
}

eDialog.prototype.setWidth = function( w ){
	this.width = w;
	this.__dosize__();
}

eDialog.prototype.getPanel = function(){
	return this.panel;
}

eDialog.prototype.addListener = function( node ){
	this.listeners.push( node );
}

eDialog.viewPortSize = function(){
	var size = [0,0];
	if( typeof window.innerWidth != 'undefined' ){
		size[0] = window.innerWidth;
		size[1] = window.innerHeight;
	}
	else if( typeof document.documentElement != 'undefined' 
	         && typeof document.documentElement.clientWidth != 'undefined' 
			 && document.documentElement.clientWidth != 0 ){
		size[0] = document.documentElement.clientWidth;
		size[1] = document.documentElement.clientHeight;
	}
	else{
		size[0] = document.body.clientWidth;
		size[1] = document.body.clientHeight;
	}
	return size;
}

eDialog.loadContentFromUrl = function( url, dialog, x, y ){
	var xmlhttp = null;
	if( window.ActiveXObject ){
		xmlhttp = new ActiveXObject( "Microsoft.XMLHTTP" );
	}else if( window.XMLHttpRequest ){
		xmlhttp = new XMLHttpRequest();
	}
	xmlhttp.onreadystatechange = function()
    {
		if( xmlhttp.readyState == 4 ){
			var d = document.createElement( "div" );
			d.innerHTML = xmlhttp.responseText;
			dialog.add( d );
			if( x != null && y != null ){ dialog.showAt( x, y ); }
			else{ dialog.loaded(); }
		}
    };
	xmlhttp.open( "GET", url, true );
	xmlhttp.send( null );
}



function eElementsEmailTask(){
	this.receiver_list = new Array();
	this.subject = null;
	this.message = null;
	window.emailTask = this;
}

eElementsEmailTask.prototype.execute = function( recip_id_list ){
   ee.wc( true );
   var dialog = new eDialog( ee.getn( null, 'body' )[0], true );
   var me = this;
   dialog.setWidth( 485 );
   
   dialog.setTitle( "Email" );
   if( isNull( recip_id_list ) ){
     dialog.setHeight( 405 );
     DomFactory.getETableModel( 3, function( text ){
        // Load the user list.
        var model = null;
        try{
            model = eTableModel.jsonLoad( eval( "("+text+")" ) );
        }catch( error ){
            alert( "An unexpected event has occurred.\nUnable to retrieve a list of potential email recipients.\nCheck with your administrator." );
            eDialog.releaseDialog( dialog ); 
            return;
        }
        model.maxHeight = 200;
   		var table = new eTable( model.name, model );
   		table.setSelector( true, "ELEMENT.ELEMENT_ID" );
   		
        // Create the html structure for the user list.
   		var div = ee.ce( 'div' );
   		dialog.add( div );
   		div.style.height = "200px";
   		div.style.width = "450px";
   		var str = new StringBuilder();
   		str.append("<div id='" ).append(table.id).append("tableDiv' class='tableDiv'><table class='dataTable' id='");
   		str.append(table.id).append("' style='border-style:none;'><caption id='").append(table.id);
   		str.append("Caption'></caption><thead class='dataThead' id='").append(table.id);
   		str.append("Head'></thead><tfoot id='").append(table.id)
   		str.append("Foot'></tfoot><tbody class='dataTbody' id='").append(table.id).append("Body'></tbody></table></div>");
        div.innerHTML = str.toString();
   		
   		me.createMessageForm( dialog, table, null );

	    dialog.show();
        try{ ee.ge("email-subj").focus(); } catch(e){}
	    ee.dm( "Email task executed" );
   		table.renderTable();
        ee.wc( false );
     });
   }else{
        dialog.setHeight( 200 );
        me.createMessageForm( dialog, null, recip_id_list );
	    dialog.show();
        try{ ee.ge("email-subj").focus(); } catch(e){}
	    ee.dm( "Email task executed from recipient list." );
        ee.wc( false );
   }

}

eElementsEmailTask.prototype.createMessageForm = function( dialog, table, recip_id_list ){
   		var d = ee.ce( 'div' );
   		dialog.add( d );
   		d.style.width = "450px";
   		d.style.height = "180px";
   		d.style.padding = "5px";
   		var p1 = ee.ceAsChild( "div", d );
   		p1.style.width = "100%";
   		var leg = ee.ceAsChild( "label", p1 );
        leg.setAttribute( "for", "email-subj" );
   		leg.appendChild( ee.ct( "Subject:" ) );
   		   		
   		var subj = ee.ceAsChild( 'input', p1 );
   		subj.type = "text";
   		subj.style.width = "440px";
   		subj.id = 'email-subj';
   		
   		var p2 = ee.ceAsChild( "div", d );
   		p2.style.width = "100%";
   		var leg2 = ee.ceAsChild( "label", p2 );
        leg2.setAttribute("for", "email-mess" );
   		leg2.appendChild( ee.ct( "Message:" ) )
        
   		var taholder = ee.ceAsChild( "div", p2 );
   		var s = new StringBuilder();
   		s.append( "<textarea id='email-mess' cols='40' rows='6' style='width:440px;' ></textarea>" );
   		taholder.innerHTML = s.toString();
   		
        var bbox = ee.ceAsChild( "div", d );
		var cancel = ee.ceAsChild( "button", bbox );
		cancel.appendChild( ee.ct( "Cancel" ) );
		EventUtils.addEventHandler( cancel, "click", function(){ eDialog.releaseDialog( dialog ); } );
		
		var save = ee.ceAsChild( "button", bbox );
		save.appendChild( ee.ct( "Send" ) );
		EventUtils.addEventHandler( save, "click", function(){ 
		var title = document.getElementsByTagName( "title" )[0];
		var link = new StringBuilder();
		link.append( "\nEmail relates to: " ).append( title.innerText ).append( " at ").append( window.location.href );
		        if( isNull( recip_id_list ) ){
		            window.emailTask.receiver_list = table.getSelectedItems();
		        }else{
		            window.emailTask.receiver_list = recip_id_list;
		        }
		        window.emailTask.subject = ee.ge( 'email-subj' ).value;
		        window.emailTask.message = ee.ge( 'email-mess' ).value +link.toString();
		        window.emailTask.save();
		        eDialog.releaseDialog( dialog ); 
		      } );
}

eElementsEmailTask.prototype.save = function(){
ee.dm( "preparing to send email" );
	sqlList = new eSqlList( function(){window.status = "Email Sent";window.emailTask = null;} );
    var detail = window.emailTask;
    var sql = new StringBuilder();
    sql.append( "INSERT INTO email_detail (recipient_id, sender_id, post_tm, subject, message, status_id, priority) " );
    sql.append( "VALUES (?, Sys_Context('ELEMENTS_CTX','USER_ID')," );
    sql.append( "  SYSDATE, ?, ?, (SELECT Status_Id FROM Status WHERE State_Machine_Id = ");
    sql.append( " (SELECT State_Machine_Id FROM State_Machine WHERE Name = 'Email States') and Name = 'Pending'), 0) " );
    
    var count = detail.receiver_list.length;
	for( var i = 0; i < count; i++ ){
	    var ss = new eSqlStatement( sql.toString() );
      	ss.addParameter( new eParameter( 'number', detail.receiver_list[i] ) );
	   	ss.addParameter( new eParameter( 'varchar', detail.subject ) );
	    ss.addParameter( new eParameter( 'varchar', detail.message ) );
	    sqlList.addStatement( ss );
	}
    sqlList.execute();
}


///////////////////////////////////////////////////////////////////////////////
// eSearch: Form helpers for the search box.
///////////////////////////////////////////////////////////////////////////////
function eSearch(){
}

eSearch.verifySubmit = function()
{
  var text = ge( "query" );
  var rval = false;
  if( text.value == '?' )
  {
      text.value = "";
      ee.pop( "../searchtips.html", 600, 480 );
  }
  else if( text.value.length > 0 ) 
  {
      rval = true;
  }
  if( !rval )
  {
     EventUtils.stopEventPropagation( EventUtils.getEvent() );
  }
  return rval;

}

/*
eSearch.doSearch = function ()
{
  if( eSearch.verifySubmit() )
  {
	document.forms['search'].submit();    
  }
  return true;
}

eSearch.activate = function(evt)
{
    evt = EventUtils.getEvent();
    if( (evt.type == 'keydown') && (evt.keyCode == KEY_ENTER) )
    {
        eSearch.doSearch();
    }
}
*/
eSearch.showOptions = function(evt)
{
    evt = EventUtils.getEvent();
    if( (evt.type == 'keydown') && (evt.keyCode != KEY_ENTER) ){ return false; }
    var opt = ee.ge('srchOptions')
    if ( opt.style.display == "block" )
    {
        opt.style.display = "none";
    }
    else 
    {
        opt.style.display = "block";
    }
    EventUtils.stopEventPropagation(evt);

}
    







///////////////////////////////////////////////////////////////////////////////
// Following functions should be in a class. Used to "decorate" http(s) urls
// found in text, as hyperlinks.
///////////////////////////////////////////////////////////////////////////////

function checkListForUrls( tlist ){
    for( var i = 0; i < tlist.length; i++ ){
       for( var j = 0; j < tlist[i].childNodes.length; j++ ){
           traverse( tlist[i].childNodes[j], checkNodeForHttpUrl );
       }
	}
}

function decorateUrl( val ){
  return val.replace(/\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]/ig, "<a href=\"$&\">$&</a>");
}


var wrdre = new RegExp( "\\s+" );
function checkNodeForHttpUrl( node ){
	if( node.nodeType != 3 ) return;
	if( node.nodeValue ){
      var words = node.nodeValue.split( wrdre );
      var matches = new Array();
      if( words ){
	    for( var i = 0; i < words.length; i++ ){
           if( (words[i].indexOf( "http://" ) > -1) || (words[i].indexOf( "http://" ) > -1) ){
               matches.push( i );
           }
        }
        if( matches.length > 0 ){
          var last = 0;
          var tnode = document.createDocumentFragment();
          for( var j = 0; j < matches.length; j++ ) {
             var index = last>0 ? last+1 : last;
             var str = words.slice( index, matches[j] );
             tnode.appendChild( document.createTextNode( str.join( " " )+' ' ) );
             var val = words[matches[j]];
             var a = document.createElement( "a" );
             a.href = val;
             a.appendChild( document.createTextNode( val ) );
             tnode.appendChild( a );
             tnode.appendChild( document.createTextNode( ' ' ) );
             last = matches[j];
          }
          var parent = node.parentNode;
          try{
             tnode.appendChild( document.createTextNode(  words.slice( last+1 ).join( ' ' ) ) );
             parent.replaceChild( tnode, node );
          }catch( e ){
          }
        }
	  }
    }
}

function traverse( node, callback ){
    if( node.nodeType == 1 && node.nodeName == 'A' ){ return; }
    callback( node );
    for( var c = node.firstChild; c != null; c = c.nextSibling ) {
      traverse( c, callback );
    }
} 

///////////////////////////////////////////////////////////////////////////////
// Handy little addon for iterating arrays.
// list = an array (result of getElementsByTagName, for example)
// func = some function to be applied to each element of list (list item is passed to func).
// Array.forEach( list, func );
// NOTE: Recent version of Mozilla browsers have this builtin, so don't add if it is there.
///////////////////////////////////////////////////////////////////////////////

if (!Array.forEach) 
{ 
	Array.forEach = function(object, block, context) 
	{
		for (var i = 0; i < object.length; i++) 
		{
            if( object[i] != undefined ){block.call(context, object[i], i, object);}
		}
	};
}


/**
  Map
  Takes a list, and a function. Applies the function to each item in the list,
  and saves the return value to a new list. The first function arg is the item in the 
  array and the second is the index of that item in the array.
  Map then returns the list of return values.
  Example:
  var t = [1,2,3];
  var r = Array.map(t, function(item,i)
  {
    return '{'+item+', '+i+'}';
  });
  alert(r.join());
 
*/
if(!Array.map)
{
    Array.map = function (arr, func)
    {
        var narr = [];
        for (var i = 0; i < arr.length; i++) narr.push(func(arr[i],i));
        return narr;
    };
}


if(!Array.filter)
{
    Array.filter = function (arr, func)
    {
        var narr = [];
        for (var i = 0; i < arr.length; i++)
        {
          var item = arr[i];
          var r = func(item,i);
          if( r ){narr.push(item);}
        }
        return narr;
    };
}

String.prototype.trim = function()
{
    var re = /^\s+(.?)\s+$/;
    return this.replace(re,"$1");
}  






///////////////////////////////////////////////////////////////////////////////
// Displays the error pop-up window with the mailto form.
///////////////////////////////////////////////////////////////////////////////
function errorHandler( msg, url, line ){
  var win = window.open("","Error","resizable,width=680,height=600" );
  var doc = win.document;
  
  doc.write('<style>body{margin:0px;padding:0px;font-size:7pt;font-family:arial,helvetica,sans-serif;}');
  doc.write('#errorDiv{font-style:italic;margin-bottom:45px;}#splash{position:absolute;top:0px;left:0px;margin-left:-20px;margin-top:-20px;}');
  doc.write('#content{position:relative;top:45px;left:180px;height:440px;width:420px;background:white;padding:20px;margin:0px;overflow:auto;}');
  doc.write('#backPlane{padding:0px;position:absolute;top:40px;background:#a5a5d6;height:540px;width:640px;left:30px;font-size:8pt;}</style>');
  doc.write('<div id="backPlane"><img id="splash" src="../images/exception_panel.gif"/><div id="content"><h1 style="color:red;">Error</h1>');
  doc.write( '<h2>An error has occurred on this page.</h2>');
  doc.write( '<h3 style="color:red">'+msg+'</h3>' );
  doc.write('<h3>You can submit this error to Enterprise Elements by clicking the Send button below.</h3>' );
  doc.write('<form action="mailto:mark@enterprise-elements.com" method="post" enctype="text/plain">');
  doc.write('<div id="errorDiv"><table border="0"><tr><td>Your email (optional)</td><td><input size="40" type="text" name="email" value=""></td></tr>');
  doc.write('<tr><td>Error Message</td><td><input size="40" type="text" name="error" value="'+msg+'"></td></tr>');
  doc.write('<tr><td>Page</td><td><input size="40" type="text" name="page" value="'+url+'"></td></tr>');
  doc.write('<tr><td>Line</td><td><input size="40" type="text" name="line" value="'+line+'"></td></tr>');
  doc.write('<tr><td>Browser Info</td><td><input size="40" type="text" name="browser" value="'+navigator.userAgent+'"></td></tr>');
  doc.write('<tr><td>Product Version</td><td><input size="40" type="text" name="browser" value="'+3.0+'"></td></tr>');
  doc.write('</table><input type="submit" value="Send"><input type="button" value="Close" onclick="self.close();">');
  doc.write('</form></div></div></div>');
  doc.close();
  return false;
}
//window.onerror = errorHandler;

