//----------------------------------------------------------------------
//-           Temple Beth Ami Event Registration Form
//-          (http://www.bethami.org/events/register)
//-
//- Users can select the events the wish to register for, the number of
//- people attending in different price categories, and even leave a
//- message for the event corrdinator.
//-
//- Once a user has entered at least one registration for one Event
//- and has pressed the "Google Checkout" button on the page, the user
//- is taken to Google Checkout for credit card payment.
//----------------------------------------------------------------------

  //--------------------------------------------------------------------
  //- Developer's debugging flag....
  //--------------------------------------------------------------------

  tbaDebug = 0;

  //--------------------------------------------------------------------
  //- The minimum dollar amount required to process an Event Regustration.
  //--------------------------------------------------------------------

  tbaMinimum = 10;

  //--------------------------------------------------------------------
  //- Make sure all events submitted to Google Checkout are flagged as
  //- Events {E}.
  //--------------------------------------------------------------------

  GoogleEventTag = '{E}';

  //--------------------------------------------------------------------
  //- Local Extensions to tbaPrice
  //--------------------------------------------------------------------

  tbaPrice.prototype.quantity = 0;

  tbaPrice.prototype.getQuantity = function()
  {
   return this.forceNumber(this.quantity);
  };

  //--------------------------------------------------------------------
  //- Since the quantity is the only thing this UI can change, it is
  //- the only thing we need to look at for validity. It must either
  //- be a valid number or a blank.
  //--------------------------------------------------------------------

  tbaPrice.prototype.isValid = function()
  {
   var n = this.getQuantity();

   if (!isNaN(n))
    {return true;}

   return tbaTrim(String(this.quantity)).length === 0;
  };

  //--------------------------------------------------------------------
  //- Local Extensions to tbaEvent
  //--------------------------------------------------------------------

  //- Add an attribute for any user-entered text.
  tbaEvent.prototype.usermsg = '';

  //--------------------------------------------------------------------
  //- prepare: Called during the tbaEvent constructor. Add a 'Quantity'
  //- to each price and make sure the user-entered message is clear.
  //--------------------------------------------------------------------
  tbaEvent.prototype.prepare = function()
  {
   //- Add a quantity value for each description/price set.
   for (i=0; i<this.prices.length; i++)
    {this.prices[i].quantity = 0;}

   //- Clear out the message field;
   this.usermsg = '';
  };

  //--------------------------------------------------------------------
  //- setQuantity: Store a quantity for a price (i.e. the number of
  //- items purchased.)
  //--------------------------------------------------------------------
  tbaEvent.prototype.setQuantity = function(index, amt)
  {
   if (index > this.prices.length || index < 0)
    {return false;}

   this.prices[index].quantity = amt;

   return !isNaN(this.prices[index].getQuantity());
  };

  //--------------------------------------------------------------------
  //- isValid: Check the current event for correctness. In the case of
  //- event registration. An event is valid if all its prices are valid.
  //--------------------------------------------------------------------
  tbaEvent.prototype.isValid = function()
  {
   for (i=0; i<this.prices.length; i++)
    {if (!this.prices[i].isValid())
     {return false;}}

   return true;
  };

  //--------------------------------------------------------------------
  //- getInvalid: Return a collection of any prices in this event that
  //- are NOT valid (i.e. the quantity is not blank or a number).
  //--------------------------------------------------------------------
  tbaEvent.prototype.getInvalid = function()
  {
   var a = [];

   for (i=0; i<this.prices.length; i++)
    {if (!this.prices[i].isValid())
     {a.push(this.prices[i]);}}

   return a;
  };

  //--------------------------------------------------------------------
  //- getSelected: Return a collection of any prices in this event that
  //- are valid and have a quantity > 0.
  //--------------------------------------------------------------------
  tbaEvent.prototype.getSelected = function()
  {
   var a = [];

   for (i=0; i<this.prices.length; i++)
    {if (this.prices[i].isValid() && (this.prices[i].getQuantity() > 0))
     {a.push(this.prices[i]);}}

   return a;
  };

  //--------------------------------------------------------------------
  //- JavaScript functions begin here
  //--------------------------------------------------------------------

  //--------------------------------------------------------------------
  //- tbaConfirmMessage: Overridden function from tbaFormFunctions.
  //- Create the action confirmation message the user sees when the
  //- Submit (Google Checkout) button is pressed.
  //--------------------------------------------------------------------
  function tbaConfirmMessage(selected)
  {
    var msg   = '';
    var total = 0;

    for (var i=0; i<selected.length; i++)
    {
     var event  = selected[i];
     var name   = event.name;
     var prices = event.getSelected();

     for (var j=0; j<prices.length; j++)
     {
      var price = prices[j];
      var desc  = price.getDescription();
      var rate  = String(price.getPrice());
          rate  = rate.replace(/\$/g,   '');
          rate  = rate.replace(/\x2C/g, '');  // x2C == a comma (,)
          rate  = Number(rate);
      var amt   = String(price.getQuantity());
          amt   = amt.replace(/\$/g,   '');
          amt   = amt.replace(/\x2C/g, '');  // x2C == a comma (,)
          amt   = Number(amt);

      //- The rate is NaN if it is "FREE"
      if (isNaN(rate))
      {
       msg = msg + '  '+name+': '+amt+' '+desc+' (FREE)\n';
      }
      else
      {
       var tot = rate*amt;
       total   = total + tot;

        //- If the rate is "1" then amt is really a dollar value.
        if (rate == 1)
         msg = msg + '  '+name+': '+desc+' $'+amt.toFixed(2)+'\n';
        else
         msg = msg + '  '+name+': '+amt+' '+desc+' @ $'+rate.toFixed(2)+' = $'+tot.toFixed(2)+'\n';
      }
     }
    }

    total = total.toFixed(2);

    msg = "You are about to register for the following events:\n\n" + msg;
    msg = msg + "\nTotal: $"+total+"\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 Event Registration page.";

    return msg;
   }

   function tbaRejectMessage(rejected)
   {
    var err   = '';

    for (var i=0; i<rejected.length; i++)
    {
     var reject = rejected[i];
     var name   = reject.name;

     for (var j=0; j<reject.prices.length; j++)
     {
      var price = reject.prices[j];
      var desc  = price.getDescription();

      if (!price.isValid())
       {err = err + 'Reservations for '+name+' ('+desc+') must be a valid number.\n';}
     }
    }

    err = "The following errors were found:\n\n" + err;

    return err;
   }

  //--------------------------------------------------------------------
  //- tbaDisplayEvents: Display an Event in a form suitable for doing
  //- event registration.
  //--------------------------------------------------------------------
  function tbaDisplayEvent(event)
  {
   if (event === undefined)
    {return;}

   var today   = new Date();
   var edate   = new Date(event.endDate);
       edate   = isNaN(edate) ? new Date(event,date) : edate;
   var cutoff  = new Date(event.cutoff);
// var tooLate = ((!isNaN(cutoff)) && (cutoff < today));
   var tooLate = (isNaN(cutoff) || (tbaTrim(event.cutoff).length == 0))
                 ? false : (cutoff < today);

   //- Don't show events that are over.
   if (today > edate)
    {return;}

   var title     = event.group;

   //- Display the individual event and create its input fields.
   //- Start out with the input fields hidden and the "plus" icon shown.
   var name     = tbaTrim(event.name);
   var anchor   = 'tba_event_' + name.replace(/\W+/g, '_');
   var date     = tbaTrim(event.date);
       date     = date.toLowerCase() == 'n/a' ? '' : date;
   var endDate  = tbaTrim(event.endDate);
       endDate  = endDate.toLowerCase() == 'n/a' ? '' : endDate;
   var deadline = tbaTrim(event.cutoff);
   var time     = tbaTrim(event.time);
   var desc     = tbaTrim(event.desc);
   var link     = tbaTrim(event.link);
   var msg      = tbaTrim(event.msg);
   var prices   = event.prices;
   var spanId   = 'tba_span_'+event.id;
   var tag      = 'Click here to register for '+name;

   tbaWrite.writeln('<p>');

   //- Display the event name and the icon.
   //- The icon starts out as 'plus' since the input fields are hidden.
   tbaWrite.writeln(' <a id="'+anchor+'"></a>');
   tbaWrite.writeln(' <span class="tbaEvent">'+name+'</span>');
   tbaWrite.writeln(' <br/>');

   //- Display the date and time.
   var dt = date;

   if ((dt.length > 0) && (time.length > 0))
    {dt += ', ';}

   dt += time;

   if ((dt.length > 0) && (endDate.length > 0))
    {dt += ' - ';}

   dt += endDate;

   if (dt.length > 0)
    {tbaWrite.writeln('<strong>'+dt+'</strong><br>');}

   //- Display the event's description.
   tbaWrite.writeln(' '+desc);
   tbaWrite.writeln(' <br/>');

   //- Display the "for more information" link, if given.
   if (link)
    {tbaWrite.writeln('<a href="'+link+'" target="_blank">For more information, click here</a><br>');}

   //- Display the special hilighted mesage, if given.
   if (msg)
    {tbaWrite.writeln('<span class="tbaHilight">'+msg+'</span><br>');}

   //- If the registration deadline has passed, do not let the user register.
   if (tooLate)
   {
    tbaWrite.writeln('  <font size="2"><b>&nbsp;*The registration deadline for this event has passed!*&nbsp;</b></font>');
    tbaWrite.writeln('  <hr>');
    tbaWrite.writeln('  </p>');
    return;
   }

   if (deadline.length > 0)
   {
    tbaWrite.writeln('  <em>-- Registration Deadline is '+deadline+'</em><br>');
   }

   //- Display the "Click here to register" message and set up to toggle the event display
   tbaWrite.writeln(' <font style="cursor:hand">');
   tbaWrite.writeln(' <b>');
   tbaWrite.writeln('  <a onclick="tbaToggleEvent(\''+spanId+'\');"');
   tbaWrite.writeln('     name="'+tag+'"');
   tbaWrite.writeln('     title="'+tag+'"');
   tbaWrite.writeln('     id="icon_'+spanId+'">');
   tbaWrite.writeln('   <img src="'+tbaPlusIconURL+'"');
   tbaWrite.writeln('        alt="'+tag+'"/>');
   tbaWrite.writeln('  </a>');
   tbaWrite.writeln('  <a href="javascript:tbaToggleEvent(\''+spanId+'\',true);"');
   tbaWrite.writeln('     name="'+tag+'"');
   tbaWrite.writeln('     title="'+tag+'" ');
   tbaWrite.writeln('     onmouseover="this.style.fontStyle=\'oblique\';"');
   tbaWrite.writeln('     onmouseout="this.style.fontStyle=\'normal\';">');
   tbaWrite.writeln('   <font size="2">&nbsp;*Click here to register*&nbsp;</font>');
   tbaWrite.writeln('  </a>');
   tbaWrite.writeln(' </b>');
   tbaWrite.writeln(' </font>');
   tbaWrite.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.
   tbaWrite.writeln(' <span id="'+spanId+'" style="display:none;">');

   //- Put the Categories, prices, & quantities into a table to keep it neat.
   tbaWrite.writeln('  <table border="0" >');

   //- Go through the prices and create an item for each name/price pair.
   for (var p=0; p<prices.length; p++)
   {
    if (prices[p] === undefined)
     {continue;}

    var category = prices[p].description;
    var price    = prices[p].price;

    if (tbaTrim(price.toString()).length === 0)
     {continue;}

    tbaWrite.writeln('   <tr>');

    //- Display the Category.
    tbaWrite.writeln('    <td>');
    tbaWrite.writeln('     &nbsp;'+category+'&nbsp;');
    tbaWrite.writeln('    </td>');

    //- Display the Price for the Category.
    tbaWrite.writeln('    <td>');

      //- If price == 1, then the user is asked to enter a dollar amount.
     if (prices[p].getPrice() == 1)
      tbaWrite.writeln('     (enter $)&nbsp;');
     else
      tbaWrite.writeln('     (@ '+price+')&nbsp;');

    tbaWrite.writeln('    </td>');

    //- Accept input for the number (quantity) of registrations at that price
    var a = 'tbaAllEvents.getEventById('+event.id+').setQuantity('+p+',this.value);';

    tbaWrite.writeln('    <td>');
    tbaWrite.writeln('     <input type="text" size="11" maxlength="11" onchange="'+a+'" />');
    tbaWrite.writeln('    </td>');

    tbaWrite.writeln('   <tr>');
   }

   tbaWrite.writeln('  </table>');

   //- Display the message box for any user-entered text.
   var o = 'tbaAllEvents.getEventById('+event.id+').usermsg = this.value';

   tbaWrite.writeln('  <b>Notes or Special Instructions:</b><br />');
   tbaWrite.writeln('  <textarea rows="3" cols="80" onchange="'+o+'"></textarea>');

   tbaWrite.writeln(' </span>');
   tbaWrite.writeln(' <hr>');
   tbaWrite.writeln(' </p>');
  }

  //--------------------------------------------------------------------
  //- tbaExitFormPostSetup: After all the events are displayed, look at
  //- the event groups. If any of them are empty or if all its event's
  //- dates are passed, then hide the event group tab.
  //--------------------------------------------------------------------
  function  tbaExitFormPostSetup (eventCollection, formAction)
  {
    var groups = eventCollection.groups();
    var first  = '';

    for (var i=0; i<groups.length; i++)
    {
      var ok = false;
      var c  = eventCollection.getEventsForGroup(groups[i]);

      if (c.length > 0)
      {
        var any = false;

        for (var j=0; j<c.length; j++)
         {any = any || !c[j].isOver()}

        ok = any;
      }

      //- Get the group name and turn it into the tab name;
      var grp    = groups[i].replace(/\W+/g, '_');
      var spanId = 'tba_group_page_'+grp;
      var headId = 'tba_group_tab_'+grp;
      var page   = document.getElementById(spanId)
      var tab    = document.getElementById(headId)

      if (!ok)
      {
       page.style.display = "none";
       tab.style.display  = "none";
      }
      else
      {
       if (first == '')
        {first = spanId;}
      }
    }

    if (first != '')
     {tbaToggleGroup(first);}
  }


  //--------------------------------------------------------------------
  //- tbaExitPreValidation: Called before the form has been validated.
  //- Checks the total amount, in dollars, that the user is about to
  //- spend for registration, and stops the process if the amount is
  //- less than the proscribed minimum.
  //--------------------------------------------------------------------
  function tbaExitPreValidation (events)
  {
   var selected = [];
   var total    = 0;
   var i;

   //- Validate the fields
   for (i=0; i<events.length; i++)
   {
    var event = events.getEventByIndex(i);
    var sels  = event.getSelected();

    if (sels.length > 0)
     {selected.push(event);}
   }

   var total = 0;

   for (var i=0; i<selected.length; i++)
   {
    var event  = selected[i];
    var prices = event.getSelected();

    for (var j=0; j<prices.length; j++)
    {
     var price = prices[j];
     var rate  = String(price.getPrice());
         rate  = rate.replace(/\$/g,   '');
         rate  = rate.replace(/\x2C/g, '');  // x2C == a comma (,)
         rate  = Number(rate);
     var amt   = String(price.getQuantity());
         amt   = amt.replace(/\$/g,   '');
         amt   = amt.replace(/\x2C/g, '');  // x2C == a comma (,)
         amt   = Number(amt);

     //- The rate is NaN if it is "FREE"
     if (!isNaN(rate))
     {
      var tot = rate*amt;
      total   = total + tot;
     }
    }
   }

   if (total >= tbaMinimum)
    {return true;}

   alert("Your total purchase is $" + total.toFixed(2) + "\n\n" +
         "We cannot accept online registrations for amounts " +
         "less than $" + tbaMinimum.toFixed(2));

   return false;
  }

  //--------------------------------------------------------------------
  //- tbaExitPostValidation: Called after the form has been validated
  //- and the user has confirmed the actions, but before the Google
  //- fields are created. Go through the selected events and, if a
  //- price == 1, switch Price and Quantity. This is done because
  //- Google Checkout will not allow fractional quantities and dollar
  //- Amounts entered on Payment events (i.e. where the Price=1) can
  //- easily hold dollars and cents.
  //--------------------------------------------------------------------
  function tbaExitPostValidation (events, selected)
  {
   for (var i=0; i<selected.length; i++)
   {
    var event = selected[i];

    for (var k=0; k<event.prices.length; k++)
    {
     var price = event.prices[k];

     if (price.getPrice() === 1)
     {
      price.price    = price.getQuantity();
      price.quantity = 1;
     }
    }
   }

   return true;
  }

  //--------------------------------------------------------------------
  //- JavaScript functions end here
  //--------------------------------------------------------------------

