function Gazetteer( callback )
{
  this._servlet = "gazetteerJson";
  this._version = "1.0";
  this._text = null;
  this._featureType = "AUTOMATIC";
  this._startRow = 0;
  this._maxRows = 10;
  this._callback = callback;
  this._onBeforeSearch = null;
  this._response = null;
};

Gazetteer.prototype.setCallback = function( fn )
{
  this._callback = fn;
};

Gazetteer.prototype.getText = function()
{
  return this._text;
};

Gazetteer.prototype.setText = function( text )
{
  this._text = text;
};

Gazetteer.prototype.getFeatureType = function()
{
  return this._featureType;
};

Gazetteer.prototype.setFeatureType = function( featureType )
{
  this._featureType = featureType;
};

Gazetteer.prototype.getStartRow = function()
{
  return this._startRow;
};

Gazetteer.prototype.getMaxRows = function()
{
  return this._maxRows;
};

Gazetteer.prototype.setMaxRows = function( maxRows )
{
  this._maxRows = maxRows;
};

Gazetteer.prototype._getUrl = function()
{
  var url = this._servlet;
  url += "?version=" + this._version;
  url += "&text=" + this._encode( this._text );
  var featureType = this._featureType;
  if( featureType != "" )
    url += "&feature_type=" + featureType;
  url += "&start_row=" + this._startRow;
  url += "&max_rows=" + this._maxRows;  
  return url;
};

Gazetteer.prototype.onBeforeSearch = function( fn )
{
  this._onBeforeSearch = fn;  
};

Gazetteer.prototype._search = function()
{
  this._response = null;
  var self = this;
  var callback = function( results )
  {
    self._response = results == null ? results : eval( '(' + self._decode( results ) + ')' );
    if( self._callback == null )
      alert( "No callback method registered." );
    else
      self._callback( self._response );
  };
    
  if( this._text == "" || this._text == null )
  {
    callback();
  }
  else
  {
    if( this._onBeforeSearch != null )
      this._onBeforeSearch();
    getDataReturnText( this._getUrl(), callback );
  }
};

Gazetteer.prototype.search = function( text, featureType, startRow )
{
  if( text != undefined )
    this._text = text;

  if( featureType != undefined )
    this._featureType = featureType;

  if( startRow != undefined )
    this._startRow = startRow;
  else
    this._startRow = 0;

  this._search();
};

Gazetteer.prototype.pageForward = function()
{
  this._startRow = this._startRow + this._maxRows;
  this._search();
};

Gazetteer.prototype.pageBackward = function()
{
  this._startRow = this._startRow - this._maxRows;
  this._search();
};

Gazetteer.prototype.getPaginationHtml = function( name )
{
  var index = this._startRow;
  var pageSize = this._maxRows;
  var total = this._response.total;

  var displayIndex = index + 1;
  var lastIndex = index + pageSize;
  if( lastIndex > total )
    lastIndex = total;

  var html = "Results " + displayIndex + " - " + lastIndex + " of " + total;
  html += "&nbsp;&nbsp;"
  if( index > 0 )
  {
    html += "<a href='javascript:" + name + ".pageBackward()'";
    html += " title='See Results " + (index - pageSize + 1) + "-" + index + "'>";
    html += "Previous</a> &nbsp;";
  }
  if( total > lastIndex )
  {
    var nextLastIndex = lastIndex + pageSize;
    if( nextLastIndex > total )
      nextLastIndex = total;
    html += "<a href='javascript:" + name + ".pageForward()'";
    html += " title='See Results " + (lastIndex + 1) + "-" + nextLastIndex + "'>";
    html += "Next</a>";
  }
  return html;
}

Gazetteer.prototype._encode = function( value )
{
  var buffer = "";
  value = value.replace( /\r\n/g, "\n" );

  for( var i = 0; i < value.length; i++ )
  {
    var c = value.charCodeAt( i );

    if( c < 128 )
    {
      buffer += String.fromCharCode( c );
    }
    else if( c > 127 && c < 2048 )
    {
      buffer += String.fromCharCode( (c >> 6) | 192 );
      buffer += String.fromCharCode( (c & 63) | 128 );
    }
    else
    {
      buffer += String.fromCharCode( (c >> 12) | 224 );
      buffer += String.fromCharCode( ((c >> 6) & 63) | 128 );
      buffer += String.fromCharCode( (c & 63) | 128 );
    }
  }

  return escape( buffer );
};


Gazetteer.prototype._decode = function( value )
{
  var buffer = "";
  value = unescape( value );

  var i = 0;
  while ( i < value.length )
  {
    var c = value.charCodeAt(i);

    if( c > 191 && c < 224 )
    {
      c = ((c & 31) << 6) | (value.charCodeAt(++i) & 63);
    }
    else if( c > 127 )
    {
      c = ((c & 15) << 12) | ((value.charCodeAt(++i) & 63) << 6)
        | (value.charCodeAt(++i) & 63);
    }
    buffer += String.fromCharCode( c );
    i++;
  }

  return buffer;
};

Gazetteer.prototype.getResponse = function()
{
  return this._response;
};

Gazetteer.prototype.setResponse = function( response )
{
  this._response = response;
};

Gazetteer.prototype.isEmpty = function()
{
  return this._response == null || this._response.total == 0;
};

Gazetteer.prototype.update = function( gazetteer )
{   
  this._text = gazetteer._text;
  this._featureType = gazetteer._featureType;
  this._startRow = gazetteer._startRow;
  this._maxRows = gazetteer._maxRows;
  this._response = gazetteer._response;
  this._callback( this._response );
};
