//////////////////////////////////////////////////////////////////////////////
// BANK OF CANADA OBJECT, FUNCTIONS AND DATABASE
//
// http://www.bankofcanada.ca/en/rates/exchange-look.html normal exchange
// http://www.bankofcanada.ca/en/rates/rss_fx.html        all rss exchange
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// CONSTANTS
//////////////////////////////////////////////////////////////////////////////
var BoCDecPos =  4;    // Decimal positions
var BoCErrLog = "";    // Log for errors
var BoCTrcLog = "";    // Log for trace


//////////////////////////////////////////////////////////////////////////////
// CONTROL
//////////////////////////////////////////////////////////////////////////////
var BoCArr = new Array; // Works as array (access by numbers)
var BoCLst = new Array; // Works as asociative list (access by strings)


//////////////////////////////////////////////////////////////////////////////
// BANK OF CANADA ACCESS FUNCTIONS
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
   function BoCAddErr(newErr) // Error messaje

// PURPOSE: Store a new error messaje
//////////////////////////////////////////////////////////////////////////////
{ 
  if(BoCErrLog=="") { BoCErrLog = newErr; }
  else              { BoCErrLog = BoCErrLog + "<br>" + newErr; }
}


//////////////////////////////////////////////////////////////////////////////
   function BoCAddTrc(newTrc) // Error messaje

// PURPOSE: Store a new trace messaje
//////////////////////////////////////////////////////////////////////////////
{ 
  BoCTrcLog = BoCTrcLog + " " + newTrc;
  HtmInjectCode("BoCTrcDiv", "RSS " + newTrc);
}


//////////////////////////////////////////////////////////////////////////////
// BANK OF CANADA RSS FUNCTIONS
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
   function BoCRssGet(bocPos, // Array position begins with 1 for EUR, 2...
                      urlRss, // Only uses for trace
                      urlPhp) // Via Php in the same host (Non IE)

// PURPOSE: Returns the Xml as text. 
//          Uses an indirect Php via for all browsers.
//////////////////////////////////////////////////////////////////////////////
{
  var chkXml = true;
  if(window.ActiveXObject) { xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
  else if(window.XMLHttpRequest)              { xhr= new XMLHttpRequest(); } 
  else                                                   { chkXml = false; }

  if(chkXml) // If is ok
  {
    xhr.open("GET", urlPhp, true); // Prepare the xml http request object

    xhr.setRequestHeader("Cache-Control", "no-cache");
    xhr.setRequestHeader("Pragma", "no-cache");
    xhr.onreadystatechange = function() // Execute when ready (asincronous)
    {
      if(xhr.readyState == 4)
      {
        if(xhr.status == 200)
        {
          if(xhr.responseText != null)
          {
            if(bocPos==1) { BoCUpdEurCaD(bocPos, xhr.responseText); }
            else          { BoCUpdKey   (bocPos, xhr.responseText); }
          }
          else
          { BoCAddErr("["+bocPos +"|"+xhr.status+"|"+xhr.statusText+"];"); }
        }
        else
        { BoCAddErr("["+bocPos +"|"+xhr.status+"|"+xhr.statusText+"];"); }
      }
    }
    xhr.send(null); // Send the request
  }
}   


//////////////////////////////////////////////////////////////////////////////
// OBJECT FUNCTIONS
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
   function BoCObj(bocKey, // Currency code (text)
                   bocNam, // Currency name
                   bocRss, // Absolut Rss url at Bank of Canada
                   bocPhp, // Php at the same host
                   bocCaD, // 1 CaD = bocCaD bocKey
                   bocEur, // 1 Eur = bocEur bocKey
                   bocTyp, // noon, close rate or default when not updated
                   bocDte) // Get date

// PURPOSE: Create a currency exchange database object.
//////////////////////////////////////////////////////////////////////////////
{
  this.bocKey = bocKey; // Currency code (text)
  this.bocNam = bocNam; // Currency name
  this.bocRss = bocRss; // Absolut Rss url at Bank of Canada
  this.bocPhp = bocPhp; // Php at the same host
  this.bocCaD = bocCaD; // 1 CaD = bocCaD bocKey
  this.bocEur = bocEur; // 1 Eur = bocEur bocKey
  this.bocTyp = bocTyp; // noon, close rate or default when not updated
  this.bocDte = bocDte; // Get date
}


//////////////////////////////////////////////////////////////////////////////
   function BoCPut(bocKey, // Currency code (text)
                   bocNam, // Currency name
                   bocRss, // Absolut Rss url at Bank of Canada
                   bocPhp, // Php at the same host
                   bocCaD, // 1 CaD = bocCaD bocKey
                   bocEur, // 1 Eur = bocEur bocKey
                   bocTyp, // noon, close rate or default when not updated
                   bocDte) // Get date

// PURPOSE: Create a currency exchange database object.
//////////////////////////////////////////////////////////////////////////////
{
  var bocPos = BoCArr.length; // Position for this new entry
  BoCArr[bocPos] = bocKey; 
  BoCLst[bocKey] = new BoCObj(bocKey, bocNam, bocRss, bocPhp,
                              bocCaD, bocEur, bocTyp, bocDte);
}


//////////////////////////////////////////////////////////////////////////////
// BANK OF CANADA FUNCTIONS
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
   function BoCGetItem(inpHtm)
//////////////////////////////////////////////////////////////////////////////
{ return(TxtBetween2Tag(inpHtm, "<item", "</item>")); }


/*----------------------------------------------------------------------------
<item rdf:about="http://www.bankofcanada.ca/rss/fx/noon/iexe0101.xml">
  <title>CA: 0.9947 USD = 1 CAD 2008-07-18 Bank of Canada noon rate</title>
  ...
  <dc:date>2008-07-18</dc:date>
  <cb:baseCurrency>CAD</cb:baseCurrency>
  <cb:targetCurrency>USD</cb:targetCurrency>
  <cb:value frequency="business" decimals="4">0.9947</cb:value>
  <cb:rateType>noon</cb:rateType>
  ...
</item>
----------------------------------------------------------------------------*/

//////////////////////////////////////////////////////////////////////////////
   function BoCGetItemDate(itm)
//////////////////////////////////////////////////////////////////////////////
{ return(TxtReplace(XmlGetValue(itm, "dc:date"), "-", "/")); }


//////////////////////////////////////////////////////////////////////////////
   function BoCGetItemType(itm)
//////////////////////////////////////////////////////////////////////////////
{ return(XmlGetValue(itm, "cb:rateType")); }


//////////////////////////////////////////////////////////////////////////////
   function BoCGetItemTarget(itm)
//////////////////////////////////////////////////////////////////////////////
{ return(XmlGetValue(itm, "cb:targetCurrency")); }


//////////////////////////////////////////////////////////////////////////////
   function BoCGetItemValue(itm)
//////////////////////////////////////////////////////////////////////////////
{ return(1 * XmlGetValue(itm, "cb:value")); } // Returns as numeric


//////////////////////////////////////////////////////////////////////////////
   function BoCUpdEurCaD(bocPos,    // Must be 1 for EUR
                         cadEurXml) // Xml text

// PURPOSE: Update the 2 main BoC objects: BoCLst["CAD"] and BoCLst["EUR"].
//          Canadian Dollar and Euro:
//          - must have the position 0 and 1 in the array PdbArr,
//          - are calculate at the same time (with euros rss xml),
//          - all other currencies depend on CaD and Eur.
//          Side effects when finish:
//          - calls to update the next currency (2) and 
//          - if BoCDivSlider exist insert the text EUR, CAD
//////////////////////////////////////////////////////////////////////////////
{
  var objCaD = BoCLst["CAD"];
  var objEur = BoCLst["EUR"];

  var cadEurItm = BoCGetItem(cadEurXml);       // Get the item information
  var cadEurVal = BoCGetItemValue(cadEurItm);  // Get the exchange value
  var cadEurDte = BoCGetItemDate(cadEurItm);   // Get the date value
  var cadEurTyp = BoCGetItemType(cadEurItm);   // Get the rate type
  var cadEurTrg = BoCGetItemTarget(cadEurItm); // Must be EUR

  if(cadEurTrg != objEur.bocKey) // Other currency?
  { BoCAddErr("["+bocPos+"|"+cadEurTrg+"!="+objEur.bocKey+"|?];"); } 
  else
  {
    objCaD.bocEur = DatRound(1/cadEurVal, BoCDecPos); // 1 / Rss value
    objEur.bocCaD = DatRound(cadEurVal,   BoCDecPos); // Rss value
    objCaD.bocDte = cadEurDte;     // Rss date
    objEur.bocDte = cadEurDte;     // Rss date
    objCaD.bocTyp = cadEurTyp;     // Rss type
    objEur.bocTyp = cadEurTyp;     // Rss type
  }
  BoCAddTrc("CAD EUR");
  BoCUpdNxt(bocPos+1); // Update next currency
}


//////////////////////////////////////////////////////////////////////////////
   function BoCUpdNxt(bocPos) // 2, 3, 4,...

// PURPOSE: Calls the next update, if there isn't call de final function.
//////////////////////////////////////////////////////////////////////////////
{
  if(bocPos < BoCArr.length) // If there are next update it
  {
    var bocKey = BoCArr[bocPos];
    var bocObj = BoCLst[bocKey];
    BoCRssGet(bocPos, bocObj.bocRss, bocObj.bocPhp); // Ask for next Xml
  }
  else { BoCUpdEnd(); } // The asincronous cicle was end
}


//////////////////////////////////////////////////////////////////////////////
   function BoCUpdKey(bocPos,    // Must be 1 for EUR
                      cadKeyXml) // Xml text

// PURPOSE: Update one BoC object: BoCLst[BoCArr[bocPos]].
//////////////////////////////////////////////////////////////////////////////
{
  var bocKey = BoCArr[bocPos];
  var objKey = BoCLst[bocKey];
  var eurCaD = BoCLst["CAD"].bocEur; // Change 1 Eur = n CaD

  var cadKeyItm = BoCGetItem(cadKeyXml);       // Get the item information
  var cadKeyVal = BoCGetItemValue(cadKeyItm);  // Get the exchange value
  var cadKeyDte = BoCGetItemDate(cadKeyItm);   // Get the date value
  var cadKeyTyp = BoCGetItemType(cadKeyItm);   // Get the rate type
  var cadKeyTrg = BoCGetItemTarget(cadKeyItm); // Must be equal to Key

  if(cadKeyTrg != objKey.bocKey) // Other currency?
  { BoCAddErr("["+bocPos+"|"+cadKeyTrg+"!="+objKey.bocKey+"|?];"); } 
  else
  {
    objKey.bocCaD = DatRound(cadKeyVal, BoCDecPos);  // 1 CaD = cadKeyVal Key
    objKey.bocEur = DatRound(eurCaD * cadKeyVal, BoCDecPos); // 1 Eur = x Key
    objKey.bocDte = cadKeyDte; // Rss date
    objKey.bocTyp = cadKeyTyp; // Rss type
  }
  BoCAddTrc(objKey.bocKey);
  BoCUpdNxt(bocPos+1); // Update next currency
}


//////////////////////////////////////////////////////////////////////////////
   function BoCUpdEnd() // 2, 3, 4,...

// PURPOSE: Final calls when all update cicle was end.
//////////////////////////////////////////////////////////////////////////////
{
  HtmInjectCode("BoCTrcDiv", "");
}


//////////////////////////////////////////////////////////////////////////////
// BANK OF CANADA VIEW FUNCTIONS
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
   function BoCPriEurKey(bocKey, // Currency key
                         priEur, // Price in Eur
                         BoCDecPos) // Precision

// PURPOSE: Returns a text with a price change (use € to be sort).
//////////////////////////////////////////////////////////////////////////////
{
  var objKey = BoCLst[bocKey];
  var eurKey = objKey.bocEur;
  var priKey = DatRound(priEur * eurKey, BoCDecPos);
  var priTxt = priEur+" € = "+priKey+" "+bocKey;             // Text price
  var excTxt = "€ = "+DatRound(eurKey,BoCDecPos)+" "+bocKey; // Text exhange
  var dteTyp = objKey.bocDte+" "+objKey.bocTyp+" rate";      // Text date
  var allTxt = priTxt+" ("+excTxt+", "+dteTyp+")";

  return(allTxt);
}


//////////////////////////////////////////////////////////////////////////////
   function BoCSelectWrite(frmNam, // Form name
                           selKey) // Selected currency key

// PURPOSE: Write select option for all currencies in the database
//////////////////////////////////////////////////////////////////////////////
{
  document.write(
    "<select name='bocKey' size=1 "+
    "onChange='BoCSelectChange(document."+frmNam+");'>");

  var selTxt = " ";
  for(var arrPos=0; arrPos<BoCArr.length; arrPos++)
  {
    var bocKey = BoCArr[arrPos];
    var bocObj = BoCLst[bocKey];

    var picNam = bocObj.bocNam;
    if(bocKey!=selKey) { selTxt = " "; }
    else               { selTxt = " selected "; }
    var optTxt = "<option"+selTxt+"value='"+bocKey+"'>"+
                 bocKey+" | "+bocObj.bocNam+"</option>";
    document.write(optTxt);
  }
  document.write("</select>");
//document.write("<br><div id='BoCTrcDiv'>|&nbsp;</div>");
}


//////////////////////////////////////////////////////////////////////////////
   function BoCSelectChange(frmObj) // Form object

// PURPOSE: Update a form with currencies exchange information.
//////////////////////////////////////////////////////////////////////////////
{
  var picNum = frmObj.picNum.value; // Pictures
  var pdbObj = PdbLst[picNum];

  var bocKey = frmObj.bocKey.value; // Cuerrencies
  var bocObj = BoCLst[bocKey];

  var eurS36 = 0.50; // Must goes to other place [ASC]
  var priEur = DatRound(pdbObj.priBas * eurS36, 2);
  var bocStr = priEur+" €"; // Default: simple price in euros

  if(bocKey != "EUR") { bocStr =  BoCPriEurKey(bocKey, priEur, 2); }
  if(frmObj.priBdg) { frmObj.priBdg.value = bocStr; }
}


//////////////////////////////////////////////////////////////////////////////
// DATABASE
// IExplorer can access to any host in internet.
// FireFox only can access when the page and the rss are in the same host.
// For Php don't write the host (the same host for page and Php)
// /rssget.php?id=USD&ct=5 from root and works for all my differents domains
// over the same host.
//////////////////////////////////////////////////////////////////////////////

BoCPut("CAD", "Canadian Dollar", // Must be the position 0 in array BoCArr
       "",            // Rss not needed
       "",            // Php not needed
       1.0,           // 1 CAD = 1 CAD
       1.5939,        // 1 EUR = 1.5939 CAD (default value)
       "default",     // default rate, noon rate, close rate, etc.
       "2008/07/18"); // Get date (default value)

BoCPut("EUR", "European Euro", // Must be the position 1 in array BoCArr
       "http://www.bankofcanada.ca/rss/fx/noon/eurocae01.xml",
       "/rssget.php?id=EUR&ct=5",
       0.6274,        // 1 CAD = 0.6274 EUR (default value)
       1.0,           // 1 EUR = 1 EUR
       "default",     // default rate, noon rate, close rate, etc.
       "2008/07/18"); // Get date

BoCPut("USD", "U.S. Dollar",
       "http://www.bankofcanada.ca/rss/fx/noon/iexe0101.xml",
       "/rssget.php?id=USD&ct=5",
       0.9947,        // 1 CAD = 0.9947 USD (default value)
       1.5855,        // 1 EUR = 1.5855 USD (default value)
       "default",     // default rate, noon rate, close rate, etc.
       "2008/07/18"); // Get date

BoCPut("GBP", "U.K. pound sterling",
       "http://www.bankofcanada.ca/rss/fx/noon/iexe1201.xml",
       "/rssget.php?id=GBP&ct=5",
       0.4978,        // 1 CAD = 0.4978 GBP (default value)
       0.7934,        // 1 EUR = 0.7934 GBP (default value)
       "default",     // default rate, noon rate, close rate, etc.
       "2008/07/18"); // Get date

BoCPut("JPY", "Japanese yen",
       "http://www.bankofcanada.ca/rss/fx/noon/iexe0701.xml",
       "/rssget.php?id=JPY&ct=5",
       106.5190,      // 1 CAD = 106.5190 JPY (default value)
       169.7806,      // 1 EUR = 169.7806 JPY (default value)
       "default",     // default rate, noon rate, close rate, etc.
       "2008/07/21"); // Get date

BoCPut("CHF", "Swiss franc",
       "http://www.bankofcanada.ca/rss/fx/noon/iexe1101.xml",
       "/rssget.php?id=CHF&ct=5",
       1.0185,        // 1 CAD = 1.0185 CHF (default value)
       1.6234,        // 1 EUR = 1.6234 CHF (default value)
       "default",     // default rate, noon rate, close rate, etc.
       "2008/07/21"); // Get date

BoCPut("CZK", "Czech Republic koruna",
       "http://www.bankofcanada.ca/rss/fx/noon/iexe2301.xml",
       "/rssget.php?id=CZK&ct=5",
       14.4634,       // 1 CAD = 14.4634 CZK (default value)
       23.0532,       // 1 EUR = 23.0532 CZK (default value)
       "default",     // default rate, noon rate, close rate, etc.
       "2008/07/21"); // Get date


//////////////////////////////////////////////////////////////////////////////
// UPDATE STATIC in bocupd.js
//////////////////////////////////////////////////////////////////////////////


