// Define Methods
function XmlDoc_Clear()
   {
   this.records = new Array();
   }


function XmlDoc_AddRecord( record)
   {
   this.records[this.records.length] = record;
   }


function XmlRecord_AddColumn( name, value, isKey, origValue )
   {
   for ( var i = 0; i < this.columns.length; i++)
      {
      // Got a column
      if ( this.columns[i].name == name)
         {
         // Column already exists
         if ( this.columns[i].isKey == isKey)
            {
            // Same type, ignore
            return;
            }
         break;
         }
      }

   // if we get here, the column must be new, so add it to the list
   this.columns[this.columns.length] = new Column( name, value, isKey, origValue);
   }


function XmlDoc_GetXml()
   {
   var output = '<xephr>\n';
   if ( this.name.length > 0 )
      {
      output += '   <entity name="' + this.name + '">\n';
      }
   for ( var i = 0; i < this.records.length; i++ )
      {
      output += this.records[i].getXml();
      }
   if ( this.name.length > 0 )
      {
      output += '   </entity>\n';
      }
   output += '</xephr>\n';
   return output;
   }


function XmlRecord_GetXml()
   {
   if ( ( this.name == null ) || ( this.name.length == 0 ) || ( this.columns.length == 0) )
      {
      // Nothing to do
      return '';
      }

   var output = '      <block id="' + this.name + '"';
   if ( this.action.length > 0 )
      {
      output += ' action="' + this.action + '"';
      }
   if ( this.columns.length == 0 )
      {
      output += '/>\n' ;
      }
   else
      {
      output += '>\n' ;
      for ( var i = 0; i < this.columns.length; i++ )
         {
         output += this.columns[i].getXml();
         }
      output += '      </block>\n' ;
      }
   return output;
   }


function XmlColumn_GetXml()
   {
   if ( ( this.name == null ) || ( this.name.length == 0 ) )
      {
      // Nothing to do
      return '';
      }

   var output = XmlColumn_WriteField( this);
   if ( this.isKey )
      {
      output += XmlColumn_WriteKey( this);
      }
   return output;
   }


function XmlColumn_WriteField( obj)
   {
   var output = '';
   output += '         <field id="' + obj.name + '"';
   if ( ( obj.value == null ) || ( obj.value.length == 0 ) )
      {
      output += '/>\n';
      }
   else
      {
      output += '>';
      if ( ( obj.value.indexOf( '<' ) == -1 ) && ( obj.value.indexOf( '>' ) == -1 ) && ( obj.value.indexOf( '&' ) == -1 ) )
         {
         output += obj.value;
         }
      else
         {
         // Escape data
         output += '<![CDATA[' + obj.value + ']]>';
         }
      output += '</field>\n';
      }
   return output;
   }


function XmlColumn_WriteKey( obj)
   {
   var output = '';
   output += '         <key id="' + obj.name + '"';
   if ( ( obj.origValue == null ) || ( obj.origValue.length == 0 ) )
      {
      output += '/>\n';
      }
   else
      {
      output += '>';
      if ( ( obj.origValue.indexOf( '<' ) == -1 ) && ( obj.origValue.indexOf( '>' ) == -1 ) && ( obj.origValue.indexOf( '&' ) == -1 ) )
         {
         output += obj.origValue;
         }
      else
         {
         // Escape data
         output += '<![CDATA[' + obj.origValue + ']]>';
         }
      output += '</key>\n';
      }
   return output;
   }


function XephrRestrictions_ClearRestrictions()
   {
   this.restrictions = new Array();
   }


function XephrRestrictions_AddRestriction( name, value, insensitive, wildcards, trailingWildcard,isColumn )
   {
   var i = this.restrictions.length;

   // Handle Shift betwixt DBCOL -> FIELD
   var fromCol = isColumn ? "@" : "";

   // Build Restriction
   if ( insensitive && !wildcards && !trailingWildcard)
      {
      this.restrictions[i] = fromCol + name + "^=" + escape( value);
      }
   else if (wildcards && !insensitive)
      {
      this.restrictions[i] = fromCol + name + "$=" + escape( value);
      }
   else if (wildcards && insensitive)
      {
      this.restrictions[i] = fromCol + name + "@=" + escape( value);
      }
   else if (trailingWildcard && !insensitive)
      {
      this.restrictions[i] = fromCol + name + "|=" + escape( value);
      }
   else if (trailingWildcard && insensitive)
      {
      this.restrictions[i] = fromCol + name + "~=" + escape( value);
      }
   else
      {
      this.restrictions[i] = fromCol + name + "=" + escape( value);
      }
   }


function XephrRestrictions_GetRestrictions( sep)
   {
   if ( sep == null)
      {
      sep = "?";
      }
   var output = "";
   for ( var i = 0; i < this.restrictions.length; i++ )
      {
      if ( i == 0 )
         {
         output += sep;
         }
      else
         {
         output += "&";
         }
      output += "query=" + this.restrictions[i];
      }
   this.clear();
   return output;
   }


// XML Document Handler
function XmlDocument( name)
   {
   // Setup Properties
   this.name = name;
   this.records = new Array();

   // Setup Methods
   this.clear = XmlDoc_Clear;
   this.add = XmlDoc_AddRecord;
   this.getXml = XmlDoc_GetXml;
   }


// Define Record Handler
function Record( name, action)
   {
   // Setup Properties
   this.name = name;
   this.action = action;
   this.columns = new Array();

   // Setup methods
   this.add = XmlRecord_AddColumn;
   this.getXml = XmlRecord_GetXml;
   }


// Define Column Handler
function Column( name, value, isKey, origValue)
   {
   // Setup properties
   this.name = name;
   this.value = value;
   this.isKey = isKey == "Y";
   this.origValue = origValue;

   // Setup methods
   this.getXml = XmlColumn_GetXml;
   }


function XephrRestrictions()
   {
   // Setup properties
   this.restrictions = new Array();

   // Setup methods
   this.clear = XephrRestrictions_ClearRestrictions;
   this.add = XephrRestrictions_AddRestriction;
   this.get = XephrRestrictions_GetRestrictions;
   }
