// ---------------------------------------------------------------------------
// (c) 2002 KystAtlas AS, Hans Martin Mohn
// ---------------------------------------------------------------------------
// Utility class to aid constructing urls and reading and writing parameters from them
//
// Dependencies:
//    None
//


function gtUrl(url)
{
  this.m_map     = new Object();
  this.m_symbols = new Object();  // Map of gtUrl's to support several sym= parameters (for PrintMap). Indexed on id (or if no id, '[' + symbol + ']')
  this.m_service = "";
  this.setFromUrl(url);
} // end gtURL Constructor



// Parse a general URL
gtUrl.prototype.setFromUrl = function(url)
{
  this.clearSymbols();
  if (url && url.length > 0)
  {
    // Avoid decoding escape sequences, but because of the parsing we must handle "&amp;" !
    url = url.replace(/&amp;/g, "&");
    url = url.replace(/&#38;/g, "&"); // Safari (thanks...)

    var params;
    var spliturl = url.split("?");
    if (spliturl.length >= 2)
    {
      params = spliturl[1].split("&");
      this.m_service = spliturl[0];
    }
    else
    {
      params = spliturl[0].split("&");
      if (params.length == 1)
        this.m_service = params[0];
    }

    for (i = 0; i < params.length; i++)
    {
      var arg = params[i];
      var pos = arg.indexOf('=');
      if (pos > 0)
      {
        var name = arg.substring(0, pos);
        var value = arg.substring(pos + 1);
        if (name == "sym")
          this.setSymbol(value);
        else
          this.m_map[name] = value;
      }
    }
  }
}; // end setFromUrl()



function escapeCommasInQuotedString(s)
{
  var frag = s.split(/"|%22/);
  for (var i = 1; i < frag.length; i += 2)
    frag[i] = frag[i].replace(/,/g, "%2c");
  return frag.join('"');
} // end escapeCommasInQuotedString()



// Parse a format specifier of the form: ai(embedfont=true,compress=false)
gtUrl.prototype.setFromFormat = function(format)
{
  if (!format || format.length <= 0)
    return;

  format = escapeCommasInQuotedString(format);
  var pos1 = format.indexOf('(');
  var params;
  if (pos1 >= 0)
  {
    this.m_service = format.substring(0, pos1);
    var pos2 = format.indexOf(')');
    if (pos2 < 0)
      pos2 = format.length;
    params = format.substring(pos1 + 1, pos2).split(",");
  }
  else
  {
    // Handle a lone format name
    this.m_service = format;
    return;
  }

  for (var i = 0; i < params.length; i++)
  {
    var arg = params[i];
    arg = arg.replace(/%2c/g, ',');
    var pos = arg.indexOf('=');
    if (pos > 0)
      this.m_map[arg.substring(0, pos)] = arg.substring(pos + 1); // Must not unescape!?? (not nice to change input string)
  }
}; // end setFromFormat()



gtUrl.prototype.getParam = function(param)
{
  return (param == "sym") ? this.m_symbols[0].toString() : this.m_map[param];
}; // end getParam()



gtUrl.prototype.getParamDef = function(param, def)
{
  var val = this.getParam(param);
  return (val) ? val : def;
}; // end getParamDef()



gtUrl.prototype.setParam = function(param, value)
{
  if (param == "sym")
    this.setSymbol(value);
  else
    this.m_map[param] = value;
}; // end setParam()



gtUrl.prototype.delParam = function(param)
{
  delete this.m_map[param];
}; // end delParam()



gtUrl.prototype.setService = function(service)
{
  this.m_service = service;
}; // end setService()



gtUrl.prototype.getService = function()
{
  return this.m_service;
}; // end getService()



gtUrl.prototype.toString = function()
{
//  if (this instanceof Window)
//    return this.location; // The IE8 integrated debugger calls this function with "this" pointing to a window...
    
  var result = (this.m_service.length > 0) ? (this.m_service + "?") : "";
  var first  = true;

  for (var key in this.m_map)
  {
    if ("" + this.m_map[key] !== "")
    {
      result += (first ? "" : "&amp;") + key + "=" + this.m_map[key];
      first = false;
    }
  }

  for (key in this.m_symbols)
  {
    if (this.m_symbols[key])
    {
      result += (first ? "" : "&amp;") + "sym=" + this.m_symbols[key].toString();
      first = false;
    }
  }

  return result;
}; // end toString()



// getUrl(): DEPRECATED! Use toString() in stead!
gtUrl.prototype.getUrl = function()
{
  return this.toString();
}; // end getUrl()



gtUrl.prototype.toFormatString = function()
{
  var result = (this.m_service.length > 0) ? (this.m_service + "(") : "(";
  var first  = true;

  for (key in this.m_map)
  {
    if ("" + this.m_map[key] !== "")
    {
      result += (first ? "" : ",") + key + "=" + this.m_map[key];
      first = false;
    }
  }
  return result + ")";
}; // end toFormatString()



// getFormat(): DEPRECATED! Use toFormatString() in stead!
gtUrl.prototype.getFormat = function()
{
  return this.toFormatString();
}; // end getFormat()



gtUrl.prototype.clearSymbols = function()
{
  for (var key in this.m_symbols)
    delete this.m_symbols[key];
}; // end clearSymbols()



gtUrl.prototype.getSymbol = function(key)
{
  return this.m_symbols[key];
}; // end getSymbol()



// Infer key from value. If id is defined use its value as key, otherwise use symbol (enclosed in [])
gtUrl.prototype.setSymbol = function(value)
{
  value = value.replace(/%22/g, '"');
  var sym = new gtSym(value);
  var key = (sym.m_id) ? sym.m_id : "[" + sym.m_symbol + "]";
  this.m_symbols[key] = sym;
  return sym;
}; // end setSymbol()



gtUrl.prototype.delSymbol = function(id)
{
  if (this.getSymbol(id))
  {
    delete this.m_symbols[id];
    return true;
  }
  else
  {
    return false;
  }
}; // end delSymbol()



gtUrl.prototype.setSymbolId = function(sym, id)
{
  if (this.getSymbol(sym.m_id))
    delete this.m_symbols[sym.m_id];
  sym.m_id = id;
  this.m_symbols[id] = sym;
}; // end setSymbolId()



///////////////////////////////////////////////////////////////////////////////////////

function unQuote(text)
{
  if (!text)
    return undefined;
  if (text.charAt(0) == "\"")
    text = text.substr(1);
  if (text.charAt(text.length - 1) == "\"")
    text = text.substr(0, text.length - 1);
  return text;
} // end unQuote()



function gtSym(sym)
{
  this.setFromString(sym);
} // end gtSym()



gtSym.prototype.setFromString = function(sym)
{
  if (sym && sym.length > 0)
  {
    // Strip off enclosing ()
    pos1 = sym.indexOf('(');
    if (pos1 >= 0)
    {
      pos2 = sym.indexOf(')');
      if (pos2 < 0)
        pos2 = sym.length;
      sym = sym.substring(pos1 + 1, pos2);
    }
    // Dissect it!
    var values = sym.split(",");
    this.m_x        = values[0];
    this.m_y        = values[1];
    this.m_symbol   = unQuote(values[2]);
    this.m_url      = unQuote(values[3]);
    this.m_tooltip  = unQuote(values[4]);
    this.m_id       = unQuote(values[5]);
    this.m_text     = unQuote(values[6]);
    if (!this.m_id || this.m_id.length === 0)
      this.m_id = "[" + this.m_symbol + "]";
  }
}; // end setFromString()



gtSym.prototype.toString = function()
{
  var ret = '(' + this.m_x + ',' + this.m_y + ',"' + this.m_symbol + '",';
  ret += (this.m_url)     ? '"' + this.m_url + '",' : ',';
  ret += (this.m_tooltip) ? '"' + this.m_tooltip + '"' : '';
  if (this.m_id)
    ret += ',"' + this.m_id + '"';
  if (this.m_text)
    ret += ',"' + this.m_text + '"';
  return ret + ')';
}; // end toString()


///////////////////////////////////////////////////////////////////////////////////////
