//----------------------------------------------------------------------
//-     Temple Beth Ami Donations Submission Form Support Functions
//-    (Source at: http://www.bethami.net/js/tbaDonationFunctions.js)
//-
//- These functions support the easy creation of forms to allow users
//- to make online donations to the synagogue.
//-
//- Users can select the fund or funds to donate to, and the amount they
//- wish to donate. User may optionally indicate who a donation is
//- dedicated to, and who should be notified of the donation.
//-
//- Once a user has entered at least one donation amount to one fund,
//- and has pressed the "Google Checkout" button on the page, the user
//- is taken to Google Checkout for credit card payment of the donation.
//----------------------------------------------------------------------

  //--------------------------------------------------------------------
  //- Global Variables begin here
  //-
  //-  The following Global Variables can be changed:
  //-
  //-    GoogleLive
  //-    GoogleLiveMerchId
  //-    GoogleSandMerchId
  //-    tbaPlusIconURL
  //-    tbaCheckIconURL
  //-    tbaSynagogueName
  //-    tbaMinimumDonation
  //-
  //- THERE ARE NO OTHER CONFIGURABLE VARIABLES!
  //--------------------------------------------------------------------

  //--------------------------------------------------------------------
  //- The Google variables point the form's action and the Google Checkout
  //- icons to Google's sandbox for testing and live system for production.
  //-
  //- MAKE SURE YOU HAVE THE CORRECT SANDBOX AND PRODUCTION MERCHANT IDs
  //--------------------------------------------------------------------

  //- GoogleLive is 1 if the form is live (collecting real donations.)
  //- GoogleLive is 0 if you are testing the form using the Sandbox.
  var GoogleLive         = 1;

  //- These are the Merchant Ids for the live checkout and for the
  //- sandbox. MAKE SURE THESE ARE CORRECT!
  var GoogleLiveMerchId  = "536847348074558";
  var GoogleSandMerchId  = "577591753504749";

  //- This is the Google Checkout URL the form goes to when LIVE.
  var GoogleLiveURL      = "https://checkout.google.com/cws/v2/Merchant/"
                           +GoogleLiveMerchId+"/checkoutForm";

  //- This is the Google Checkout URL the form goes to when using the Sandbox.
  var GoogleSandboxURL   = "https://sandbox.google.com/checkout/cws/v2/Merchant/"
                           +GoogleSandMerchId+"/checkoutForm";

  //- The Google Checkout button image for the Live site.
  var GoogleLiveImg      = "https://checkout.google.com/buttons/checkout.gif"
                           +"?merchant_id="+GoogleLiveMerchId
                           +"&w=160&h=43&style=trans&variant=text&loc=en_US";

  //- The Google Checkout button image for the sandbox.
  var GoogleSandboxImg   = "http://sandbox.google.com/checkout/buttons/checkout.gif"
                           +"?merchant_id="+GoogleSandMerchId
                           +"&w=160&h=43&style=white&variant=text&loc=en_US";

  //- Based on the value of GoogleLive, use the live site or the sandbox
  //- Google Checkout URL and button image.
  var GoogleCheckoutURL  = GoogleLive ? GoogleLiveURL : GoogleSandboxURL;
  var GoogleCheckoutImg  = GoogleLive ? GoogleLiveImg : GoogleSandboxImg;

  //- Pre-Load the Google Checkout image to help the page display faster.
  var GoogleCheckoutIcon = new Image();
  GoogleCheckoutIcon.src = GoogleCheckoutImg;

  //--------------------------------------------------------------------
  //- tbaPlusIconURL and tbaCheckIconURL:
  //- These variable hold the URLs of the Plus and Check Icons on the page.
  //-
  //- They are both 16x16 pixel images.
  //- The Plus  icon is displayed when a fund has its input fields hidden.
  //- The Check icon is displayed when a fund has its input fields visible.
  //--------------------------------------------------------------------

  var tbaPlusIconURL     = "http://www.bethami.net/gr/add.gif";
  var tbaCheckIconURL    = "http://www.bethami.net/gr/tick.gif";

  //- Pre-Load the plus & check images to help the page display faster.
  var tbaPlusIcon        = new Image();
  var tbaCheckIcon       = new Image();

  tbaPlusIcon.src        = tbaPlusIconURL;
  tbaCheckIcon.src       = tbaCheckIconURL;

  //--------------------------------------------------------------------
  //- tbaSynagogueName: used to display the name of the synagogue in the
  //- donation confirmation message in tbaValidateDonations.
  //--------------------------------------------------------------------

  var tbaSynagogueName   = "Temple Beth Ami";

  //--------------------------------------------------------------------
  //- tbaMinimumDonataion  establishes the minimum allowable donation
  //- amount in dollars.
  //--------------------------------------------------------------------

  var tbaMinimumDonation = 10;

  //--------------------------------------------------------------------
  //- tbaHidden keeps track of whether or not a given fund's
  //- input fields are visible.
  //--------------------------------------------------------------------

  var tbaHidden          = new Object;

  //--------------------------------------------------------------------
  //- tbaCounter is used to keep track of the number used for the
  //- input field groups created when displaying the fund lists.
  //--------------------------------------------------------------------

  var tbaCounter         = 0;

  //--------------------------------------------------------------------
  //- Global Variables end here
  //--------------------------------------------------------------------

  //--------------------------------------------------------------------
  //- JavaScript functions begin here
  //--------------------------------------------------------------------

  //--------------------------------------------------------------------
  //- THE FOLLOWING FUNCTIONS CONTROL HOW THE PAGE WORKS AFTER IT IS
  //- DRAWN (i.e. how it reacts to 'clicks'.)
  //--------------------------------------------------------------------

  //--------------------------------------------------------------------
  //- tbaValidateDonations
  //-
  //- This is called when the form is submitted (i.e. when the Google
  //- Checkout button is clicked):
  //-  (<form ... onsubmit="return tbaValidateDonations(document,form);">)
  //-
  //- 1. Validate Fields: Make sure that any donation amount entered is
  //-    >= tbaMinimumDonation. (Dedication and Notification are optional
  //-    so they are not checked.) Make sure that at least one fund is
  //-    selected for donation.
  //-
  //- 2. Ask users to validate that they want to make a donation before
  //-    we send them to google checkout.
  //-
  //- 3. Get rid of any Google Checkout fields that have been created.
  //-
  //- 4. Create the form fields that Google Checkout needs to process
  //-    the donations. This is done because we end up concatenating
  //-    the dedication and notification information and using that as
  //-    the Item description (item_description_X.) We add a {D} to the
  //-    Fund name and make that the "Part Number" (item_name_X.)
  //-    The {D} tag is to allow a filter in Gmail to recognize that
  //-    this is a Donation so it can forward it to the mailing list
  //-    google_donations@bethami.org, which in turn forwards a copy
  //-    of the notice to the appropriate synagogue staff.
  //--------------------------------------------------------------------

  function tbaValidateDonations(form, formName)
  {
   var minimum = tbaMinimumDonation;
   var fields  = new Array(0);
   var total   = 0;
   var msg     = '';
   var re      = /\$|,/g;
   var donor   = document.getElementById('tbaDonorName').value;
       donor   = tbaTrim(donor);

   //- Make sure we know who the donor(s) are.
   if (0 == donor.length)
    msg = 'Please supply the Donor Name(s)\n';

   //- Validate the fields
   for (var i=0; i<form.elements.length; i++)
   {
    var field = form.elements[i];

    //- Since only a dollar amount is needed to make a donation,
    //- skip any field that is not a tba_item_price
    if (field.id.search(/tba_item_price/i) < 0)
     continue;

    //- Remove $ and , from number.
    var value = field.value.replace(re, '');
        value = parseFloat(value);
    var empty = (0 == (tbaTrim(field.value)).length);
    var index = field.id.match(/tba_item_price_(\d+)/i)[1];
    var fund  = document.getElementById('tba_item_name_'+index).value;

    //- SKIP if field is blank or 0.
    if (empty || value == 0)
     continue;

    //- REJECT if field is a string (not a number).
    if (isNaN(value))
    {
     msg = msg + 'The donation amount for '+fund+' must be a number.\n';
     continue;
    }

    //- REJECT if amount is negative.
    if (value < 0)
    {
     msg = msg + 'The donation amount for '+fund+' must be more than 0.\n';
     continue;
    }

    //- REJECT if amount of donation is less than allowed minimum.
    if (value < minimum)
    {
     msg = msg + 'The donation amount for '+fund+' must be at least $'+minimum+'.\n';
     continue;
    }

    total = total + value;
    fields.push(index);
   }

   //- REJECT if nothing is chosen and there are no other errors.
   if (fields.length == 0 && msg.length == 0)
    msg = msg + 'Please select at least one Fund for your Donation.';

   //- Any error message means that validation has failed,
   //- Inform user and return false (don't continue to Google Checkout.)
   if (msg.length > 0)
   {
    alert(msg);
    return false;
   }

   //- Confirm that user wants to make a donation.
   total = total.toFixed(2);

   msg = "**** T H A N K   Y O U ! ****\n\n";
   msg = msg + "You are about to make a donation of $" + total + " to ";
   msg = msg + tbaSynagogueName+".\n\n";
   msg = msg + "IF THIS IS WHAT YOU WANT TO DO, press the OK button below. ";
   msg = msg + "You will be taken to Google Checkout where you will enter your ";
   msg = msg + "credit card information (MasterCard, Visa, AmEx, Discover.)\n\n";
   msg = msg + "Press CANCEL to return to the Donations page."

   //- If user presses Cancel, fail the validation & return to the form.
   if (!confirm(msg))
    return false;

   //- Add the selected Funds to the form as Google Checkout fields.
   tbaAddGoogleFields(form, fields);

   //- Validation has succeeded,
   //- Return true to allow processing to continue to Google Checkout.
   return true;
  }

  //--------------------------------------------------------------------
  //- tbaTrim: Remove leading & trailing whitespace from a string
  //--------------------------------------------------------------------

  function tbaTrim(str)
  {
   return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  }

  //--------------------------------------------------------------------
  //- tbaToggleRows: Called "onclick" for each Fund name.
  //- Show or hide the input fields
  //--------------------------------------------------------------------

  function tbaToggleRows(spanId)
  {
   //- If tbaHidden does NOT have a value for a given span id, then
   //- assume that it is hidden (default).
   var hidden = eval('tbaHidden.'+spanId);
       hidden = (hidden == undefined) ? true : hidden;
   var hide   = !hidden;

   //- Switch the display status of the input rows.
   var vStyle = (hide)? "none" : "";
   var span   = document.getElementById(spanId);

   span.style.display = vStyle;

   //- Get the input fields (Amount, Dedication, and Notification.)
   var index  = document.getElementById(spanId+'_index').value;
   var amt    = document.getElementById("tba_item_price_"+index);
   var ded    = document.getElementById("tba_item_description_"+index);
   var nfy    = document.getElementById("tba_item_notify_"+index);
   var plus   = document.getElementById("find_"+spanId);

   //- When hiding the fields, clear any values, set the icon to 'plus'.
   if (hide)
   {
    amt.value = '';
    ded.value = '';
    nfy.value = '';
    plus.innerHTML = '<img src="'+tbaPlusIconURL+'">';
   }

   //- When displaying the fields, set the curson on the $ field
   //- and set the icon to 'check'.
   else
   {
    plus.innerHTML = '<img src="'+tbaCheckIconURL+'">';
    amt.select();
    amt.focus();
   }

   //- Flip the 'hidden' switch to keep track of whether the fields are
   //- hidden or displayed.
   eval('tbaHidden.'+spanId+'='+!hidden);
  }

  //--------------------------------------------------------------------
  //- tbaResetForm: Called when the 'Clear Donations Form' button is
  //- pressed. Clears out and hides all donation fields.
  //--------------------------------------------------------------------

  function tbaResetForm(form)
  {
   //- The input fields in the form are all arranged in named spans.
   var spans = form.getElementsByTagName('span');

   //- Look at each span
   for (var i=0; i<spans.length; i++)
   {
    var span  = spans[i];
    var id    = span.id;

    //- If a span has an id, it has input fields, otherwise skip it.
    if (!id)
     continue;

    //- If the span text is not hidden, hide it.
    var hidden = eval('tbaHidden.'+id);
        hidden = (hidden == undefined) ? true : hidden;

    if (!hidden)
      tbaToggleRows(id);
   }

   //- Return 'true' to allow the reset button to continue working.
   return true;
  }

  //--------------------------------------------------------------------
  //- tbaAddGoogleFields: Called after all fields have been validated
  //- and tbaValidateDonations is getting the form ready to send to
  //- Google Checkout. Inserts the fields needed for Google Checkout.
  //--------------------------------------------------------------------

  function tbaAddGoogleFields(form, fieldNumbers)
  {
   //- First remove any old versions of the fields that may be around
   //- from previous submissions.
   tbaDeleteGoogleFields(form);

   //- Define a Regular Expression to remove '$' and ',' from numbers
   //- when they are passed in through the 'price' field.
   var re      = /\$|,/g;

   //- Find the GoogleFields section of the form to hold the...
   //- ok... Google Fields.
   var fields  = document.getElementById('GoogleFields');

   //- Get the already validated donor name.
   var donor   = document.getElementById('tbaDonorName').value;
       donor   = tbaTrim(donor);

   //- Create a "0th" field, that has no price, that holds the name or
   //- names of the donors and add it to the form.
   var nm      = tbaBuildGoogleField('item_name_0',        'Donor Name(s):');
   var ds      = tbaBuildGoogleField('item_description_0', donor);
   var pr      = tbaBuildGoogleField('item_price_0',       0);
   var qu      = tbaBuildGoogleField('item_quantity_0',    1);

   fields.appendChild(nm);
   fields.appendChild(ds);
   fields.appendChild(pr);
   fields.appendChild(qu);

   //- fieldNumbers conains a list of all the funds that have valid
   //- donation amounts. Extract all the tba_item_xx fields related to
   //- that fund and use them to create Google Checkout (item_XX) fields.
   for (var i=0; i<fieldNumbers.length; i++)
   {
    var n      = i+1;
    var index  = fieldNumbers[i];
    var fields = document.getElementById('GoogleFields');
    var fund   = document.getElementById('tba_item_name_'+index       ).value;
    var price  = document.getElementById('tba_item_price_'+index      ).value;
        price  = price.replace(re, '');
    var notify = document.getElementById('tba_item_notify_'+index     ).value;
    var desc   = document.getElementById('tba_item_description_'+index).value;
        desc   = (notify.length > 0) ? desc+' --Notify: '+notify : desc;
        desc   = (desc.length   > 0) ? desc : '.';

    //- Add the Google Checkout fields to the form

    //- Append a {D} to the beginning of the item (fund)name so Gmail can
    //- recognize this as a donation and forward it to the donation list.
    var nm     = tbaBuildGoogleField('item_name_'+n, '{D} '+fund);

    //- The description includes dedication and notification information.
    var ds     = tbaBuildGoogleField('item_description_'+n, desc);

    //- Finally add the amount of the donation.
    var pr     = tbaBuildGoogleField('item_price_'+n, price);

    //- Google Checkout requires a quantity, so it is always 1 for this.
    var qu     = tbaBuildGoogleField('item_quantity_'+n, 1);

    //- Add the fields to the "GoogleFields" section of the form
    //- so we can find them later to delete, if needed.
    fields.appendChild(nm);
    fields.appendChild(ds);
    fields.appendChild(pr);
    fields.appendChild(qu);
   }
  }

  //--------------------------------------------------------------------
  //- tbaBuildGoogleField: Create a single google field given its name
  //- and value.
  //--------------------------------------------------------------------

  function tbaBuildGoogleField(name, value)
  {
    var field   = document.createElement('input');
    field.type  = 'hidden';
    field.id    = name;
    field.name  = name;
    field.value = value;

    return field;
  }

  //--------------------------------------------------------------------
  //- tbaDeleteGoogleFields: Remove all item_price, item_description,
  //- item_name & item_quantity fields created from a previous submit.
  //--------------------------------------------------------------------

  function tbaDeleteGoogleFields(form)
  {
   var deletes = new Array(0);
   var fields  = document.getElementById('GoogleFields');

   //- Find any leftover Google Checkout data by looking for
   //- item_price_XX fields.
   for (var i=0; i<form.elements.length; i++)
   {
    var field = form.elements[i];

    if (field.id.search(/^item_price/i) >= 0)
    {
     var ix = field.id.match(/^item_price_(\d+)/i)[1];
     deletes.push(ix);
    }
   }

   //- Get rid of any leftover Google Checkout fields by removing them
   //- from the GoogleFields section of the form.
   for (var i=0; i<deletes.length; i++)
   {
    var ix      = deletes[i];
    var iName   = document.getElementById('item_name_'+ix       );
    var iDesc   = document.getElementById('item_description_'+ix);
    var iPrice  = document.getElementById('item_price_'+ix      );
    var iQuant  = document.getElementById('item_quantity_'+ix   );

    fields.removeChild(iName );
    fields.removeChild(iDesc );
    fields.removeChild(iPrice);
    fields.removeChild(iQuant);
   }
  }

  //--------------------------------------------------------------------
  //- THE FOLLOWING FUNCTIONS CONTROL HOW THE PAGE GETS DISPLAYED.
  //--------------------------------------------------------------------

  //--------------------------------------------------------------------
  //- tbaDisplayDonationForm: Display a full donation page given a set
  //- of fund lists.
  //-
  //- The 'fundLists' data structure is a 3-level deep array.
  //- The structure is:
  //-
  //- Level 0: Each Element is an array that contains a group of funds.
  //-          These groups are displayed as separate sections.
  //-          The version below has Income and Endowment funds.
  //-
  //-          e.g. fundGroup = fundLists[i];
  //-
  //- Level 1: Each Element describes an individual fund, which includes
  //-          a fund Name and an optional Description.
  //-          The FIRST element of the array is the section header and
  //-          section description. The Funds themseleves are listed
  //-          starting at the second element.
  //-
  //-          e.g. fund = fundGroup[j];
  //-
  //- Level 2: The first element is the fund Name.
  //-          The second element is the fund Description.
  //-
  //-          e.g. name = fund[0]; desc = fund[1];
  //--------------------------------------------------------------------

  function tbaDisplayDonationForm(fundGroups)
  {
   //- Create links to the individual page sections (Fund Groups).
   tbaDisplayGroupLinks(fundGroups)

   //- Create the Form Header.
   tbaFormHeader();

   //- Display the Fund Groups.
   for (var i=0; i<fundGroups.length; i++)
   {
    //- Place an Anchor so we can link to this page section.
    document.writeln('<a id="'+tbaAnchorLink(fundGroups[i])+'"></a><br/>');

    //- Show the Submit/Reset buttons at the top of the section.
    tbaDisplayButtons();

    //- Show the Fund Group description and the individual funds.
    tbaDisplayFunds(fundGroups[i]);
   }

   //- Put an extra set of submit/reset buttons at the bottom of the page.
    tbaDisplayButtons();

   //- Finish Creating the Form.
   tbaFormFooter();
  }

  //--------------------------------------------------------------------
  //- tbaDisplayShortDonationForm: Create and display a small (maybe 1
  //- or 2 option) Donation Form.
  //-
  //- The 'fundGroup' data structure is a 2-level deep array.
  //- The structure is:
  //-
  //- Level 0: Each Element describes an individual fund, which includes
  //-          a fund Name and an optional Description.
  //-          The FIRST element of the array is the section header and
  //-          section description. The Funds themseleves are listed
  //-          starting at the second element.
  //-
  //-          e.g. fund = fundGroup[j];
  //-
  //- Level 1: The first element is the fund Name.
  //-          The second element is the fund Description.
  //-
  //-          e.g. name = fund[0]; desc = fund[1];
  //--------------------------------------------------------------------

  function tbaDisplayShortDonationForm(fundGroup)
  {
   //- Create the Form Header.
   tbaFormHeader();

   //- Display the Fund Group.
   tbaDisplayFunds(fundGroup);

   //- Dispay the buttons without the "Top of Page" link.
   tbaDisplayButtons(1);

   //- Finish Creating the Form.
   tbaFormFooter();
  }

  //--------------------------------------------------------------------
  //- tbaDisplayGroupLinks: Create a set of links to the Fund Group
  //- sections that will appear in the page below.
  //--------------------------------------------------------------------

  function tbaDisplayGroupLinks(fundGroups)
  {
   //- Create links to the individual page sections (Fund Groups).
   for (var i=0; i<fundGroups.length; i++)
   {
    var fundGroup = fundGroups[i];
    var title     = fundGroup[0][0];
    var anchor    = tbaAnchorLink(fundGroup);

    document.write ('<a href="#'+anchor+'">['+title+']</a>');
    document.write ('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
   }

   document.writeln('<br>');
  }

  //--------------------------------------------------------------------
  //- tbaAnchorLink: Create a string suitable for being a fund group
  //- anchor or link.
  //--------------------------------------------------------------------

  function tbaAnchorLink(fundGroup)
  {
    var title  = fundGroup[0][0];
    var anchor = 'tba_group_' + title.replace(/\W+/g, '_');

    return anchor;
  }

  //--------------------------------------------------------------------
  //- tbaFormHeader: Create the beginning of the donation form
  //--------------------------------------------------------------------

  function tbaFormHeader()
  {
   //- Create the HTML form header.
   document.writeln('<form method="POST"');
   document.writeln('      id="tbaDonations"');
   document.writeln('      name="tbaDonations"');
   document.writeln('      action="'+GoogleCheckoutURL+'"');
   document.writeln('      accept-charset="utf-8"');
   document.writeln('      target="_blank"');
   document.writeln('      onsubmit="return tbaValidateDonations(document.tbaDonations);">');

   //- Add the hidden field '_charset_' which is required by Google Checkout.
   document.writeln(' <input type="hidden" name="_charset_"/>');

   //- NEW -
   document.writeln(' <div style="text-align:right;">');
   document.writeln('  <br>Popup blocker problem? Click here &gt;&gt; ');
   document.writeln('  <input type="checkbox" onchange="tbaToggleTarget(this);"><br>');
   document.writeln(' </div>');

   //- Display an input field for the Donor Names.
   document.writeln('<br><font size="2"<b>DONOR NAME(S):</b></font> <input type="text" name="tbaDonorName"  id="tbaDonorName" value=""  size="110" />');
  }

  //--------------------------------------------------------------------
  //- tbaToggleTarget: Turn off the popping up of the Google Payments
  //- window for users with popup problems.
  //--------------------------------------------------------------------
   function tbaToggleTarget(checkbox)
   {
     var target = checkbox.checked ? '' : '_blank';

     document.tbaDonations.target = target;
   }

  //--------------------------------------------------------------------
  //- tbaDisplayFunds: Display the Fund group description and all the
  //- Funds in the group.
  //--------------------------------------------------------------------

  function tbaDisplayFunds(fundGroup)
  {
   var title     = fundGroup[0][0];
   var text      = fundGroup[0][1];

   //- Display the fund group and its description.
   document.writeln('<h1><font color=#3399ff>'+title+'</font></h1>');
   document.writeln('<p><strong>'+text+'</strong></p>');
   document.writeln('<p></p>');

   //- Display the individual funds and create their input fields.
   //- Start out with the input fields hidden and the "plus" icon shown.
   for (var i=1; i<fundGroup.length; i++)
   {
    var name     = fundGroup[i][0];
    var id       = 'tba_fund_' + name.replace(/\W+/g, '_');
    var desc     = fundGroup[i][1];
    var noAck    = fundGroup[i][2] == 'no';

    tbaCounter++;

    var tiName   = 'tba_item_name_'        + tbaCounter;
    var tiPrice  = 'tba_item_price_'       + tbaCounter;
    var tiDesc   = 'tba_item_description_' + tbaCounter;
    var tiNotify = 'tba_item_notify_'      + tbaCounter;
    var idIndex  = id+'_index';

    document.writeln('<p>');

    //- The first row displays the fund name and the icon.
    //- The icon starts out as 'plus' since the input fields are hidden.
    //- This row also contains the fund name (tba_item_name_xx) as a
    //- hidden field. The row also contains the index number for this
    //- group of items (the 'xx' in tba_item_name_xx, etc.) as a hidden
    //- field. It is used to find the fields for hiding/showing the rows.
    document.writeln(' <font style="cursor:hand"><b>');
    document.writeln('  <a onclick="tbaToggleRows(\''+id+'\');"');
    document.writeln('     id="find_'+id+'">');
    document.writeln('   <img src="'+tbaPlusIconURL+'"/>');
    document.writeln('  </a>');
    document.writeln('  <a onclick="tbaToggleRows(\''+id+'\');"');
    document.writeln('     onmouseover="this.style.fontStyle=\'oblique\';"');
    document.writeln('     onmouseout="this.style.fontStyle=\'normal\';">');
    document.writeln('   <font size="3">&nbsp;'+name+'</font>');
    document.writeln('  </a>');
    document.writeln(' </b></font>');
    document.writeln(' <input type="hidden" name="'+tiName+'"  id="'+tiName+'"  value="'+name+'" />');
    document.writeln(' <input type="hidden" name="'+idIndex+'" id="'+idIndex+'" value="'+tbaCounter+'" />');
    document.writeln(' <br/>');

    //- The second row displays the fund's description.
    document.writeln(' '+desc);
    document.writeln(' <br/>');

    //- Begin an identified section here to allow the input fields to be
    //- hidden and shown as needed. These fields are hidden by default.
    document.writeln(' <span id="'+id+'" style="display:none;">');

    //- The third row is the donation amount (tba_item_price_xx).
    document.writeln('  Donation Amount (in $):<br/>');
    document.writeln('  <input type="text"   name="'+tiPrice+'" id="'+tiPrice+'" value="" size="20" maxlength="20" />');
    document.writeln('  <br/>');

    //- The fourth row is the dedication (tba_item_description_xx).
    if (!noAck)
    {
     document.writeln('  Dedication (To whom? In honor of... In memory of... With thanks for...): <font color="red">*optional*</font><br/>');
     document.writeln('  <input type="text"   name="'+tiDesc+'"  id="'+tiDesc+'" value=""  size="120" />');
     document.writeln('  <br/>');
    }
    else
    {
     document.writeln('  <input type="hidden"   name="'+tiDesc+'"  id="'+tiDesc+'" value="" />');
     document.writeln('  <br/>');
    }

    //- The fifth row is notification information (tba_item_notify_xx).
    if (!noAck)
    {
     document.writeln('  Notify (Name and Mailing Address): <font color="red">*optional*</font><br/>');
     document.writeln('  <input type="text"   name="'+tiNotify+'" id="'+tiNotify+'" value=""  size="120" /><br/>');
     document.writeln('  <br/>');
    }
    else
    {
     document.writeln('  <input type="hidden"   name="'+tiNotify+'" id="'+tiNotify+'" value="" /><br/>');
     document.writeln('  <br/>');
    }

    document.writeln(' </span>');
    document.writeln('</p>');
   }
  }

  //--------------------------------------------------------------------
  //- tbaDisplayButtons: Show the Google Checkout submit
  //- and the Reset buttons
  //--------------------------------------------------------------------

  function tbaDisplayButtons(noTopLink)
  {
   //- Display a separator line and then show the Google Checkout button
   //- and place a Clear Form (reset) button next to it.
   document.writeln('<p align="left">');
   document.writeln(' <hr>');
   document.writeln(' <table width="100%" border="0">');
   document.writeln(' <tr valign="top">');
   document.writeln('  <td>');
   document.writeln('   <input type="image"');
   document.writeln('          name="Google Checkout"');
   document.writeln('          src="'+GoogleCheckoutImg+'"');
   document.writeln('          alt="Click here to go to Google Checkout"');
   document.writeln('          title="Click here to go to Google Checkout"');
   document.writeln('          height="43"');
   document.writeln('          width="160"/>');
   document.writeln('  </td>');
   document.writeln('  <td>');
   document.writeln('   <input type="reset"');
   document.writeln('          value="Clear Form"');
   document.writeln('          onclick="return tbaResetForm(document.tbaDonations);"');
   document.writeln('          style="vertical-align:top;margin-left:20px;" />');
   document.writeln('  </td>');

   //- If 'noTopLink' is passed as a parameter (i.e. as a 1) then do not
   //- put the "Top of Page" link in the right column of the button row.
   //- Yes this link is referring to an RJWeb Bulder id, but it gets us
   //- back to the top of the WHOLE PAGE, not just the top of this form.
   if (!noTopLink)
   {
    document.writeln('  <td align="right" width="100%">');
    document.writeln('   <a href="#cprContact Us">Top of Page</a>');
    document.writeln('  </td>');
   }

   //- Finish out the button section with another separator line.
   document.writeln(' </tr>');
   document.writeln(' </table>');
   document.writeln(' <hr>');
   document.writeln('</p>');
  }

  //--------------------------------------------------------------------
  //- tbaFormFooter: Create the end of the donation form
  //--------------------------------------------------------------------

  function tbaFormFooter()
  {
   //- Create a place where we can add and delete Google Checkout fields.
   document.writeln(' <div id="GoogleFields">');
   document.writeln(' </div>');

   //- Complete the form.
   document.writeln('</form>')
  }

  //--------------------------------------------------------------------
  //- JavaScript functions end here
  //--------------------------------------------------------------------

