/** \file   shopping_cart.js
 *  \brief  Functions for working with shopping cart blocks.
 *  \date   Created:   20 July 2004
 *  \remark CVS-ID:    $Id: shopping_cart.js,v 1.3 2005/11/27 21:12:43 shane Exp $
 *  \remark Copyright: (c) 2004 ICServ Inc. All rights reserved.
 *
 *  \alert  This file contains readable javascript code and documentation.
 *          It is not optimized for network transfer, please pack the file
 *          before uploading it to beta and to production.
 *
 *  \alert  This library uses function from dynamic_content.js.  If you
 *          include this file, you should also include dynamic_content.
 */

// Constants (use var so they are not visible outside this file)
var IMAGE_KEY         = "ezsc_rpl_image";
var IMAGE_DEFAULT_KEY = "ezsc_rpl_image_default";
var ADJUST_KEY        = "ezsc_price_adjust";
var ADJUST_TYPE_KEY   = "ezsc_price_adjust_type";


/** Writes a dynamic price field if the browser supports it.  The price
 *  can be updated using adjust_product_price().
 *
 *  \tparam String price_name
 *          The name we should used for the dynamic display
 *  \tparam Number base_price
 *          The initial price that should be shown.
 */
function write_dynamic_price( price_name, base_price )
{
   if (_is_ns4()) {
      // Netscape 4.x can't support dynamic price changes so just write it
      // out static.
      document.write( _format_price(base_price) );
   }
   else {
      // we can dynamically change the price using dynamic_content.js
      writer( price_name, _format_price(base_price) );
   }
}


/** Adjusts the price of the product that is displayed to the shopper.
 *  This is done by finding all of the initialized select boxes in the
 *  specified form getting the modification value of the selected options.
 *
 *  The \p start_idx and \p count parameters can be used to limit which
 *  input fields in the form are processed.
 *
 *  \tparam String price_name
 *          The name of the dynamic price display (the same as passed to
 *          write_dynamic_price()).
 *  \tparam String form_name
 *          The name of the form containing the select boxes that the
 *          price should be modified based upon.
 *  \tparam Number base_price
 *          The original price of the product.
 *  \tparam Number start_idx
 *          The element in the form that we should start processing at.
 *          Default: 0
 *  \tparam Number count
 *          How many elements should we process to calculate the new price.
 *          Default: \p document[form_name].elements.length
 */
function adjust_product_price( price_name, form_name, base_price, start_idx,
                               count )
{
   if (_is_ns4()) {
      // Netscape 4.x can't handle dynamic price updates so just return.
      return;
   }

   if ( !start_idx || start_idx < 0 )
      start_idx = 0;

   if ( !count || count < 0 )
      count = document[form_name].elements.length;

   count = start_idx + count;

   if ( count > document[form_name].elements.length )
      count = document[form_name].elements.length;

   var new_price = base_price;

   for (var i = start_idx; i < count; i ++) {
      var tmp = document[form_name].elements[i];
      if ((tmp.type == "select-one" || tmp.type == "select-multiple") &&
           tmp[IMAGE_DEFAULT_KEY])
      {
         var opt = tmp.options[ tmp.selectedIndex ];
         if (opt[ADJUST_TYPE_KEY] == '%') {
            // +/- precentage of base price
            new_price += base_price * opt[ADJUST_KEY] / 100;
         }
         else {
            // fixed +/- adjustment
            new_price += opt[ADJUST_KEY];
         }
      }
   }

   if (new_price < 0) {
      new_price = 0;
   }

   // from dynamic_content.js
   alter_content( price_name, _format_price( new_price ) );
}


/** Formats the \p price ensuring it is rounded to two decimal places.
 *
 *  \tparam Number price
 *          The price to format.
 *
 *  \treturn String The formatted price.
 */
function _format_price( price )
{
   price = parseFloat( price );

   // Shift the decimal over two places so we can round to the 2nd decimal
   var shifted = price * 100;

   // Round the now shifted number. This will give us a whole number.
   var rounded = Math.round( shifted );

   // Convert the whole number back to a float now rounded to the 2nd
   // decimal
   price = rounded / 100;


   var formatted_price = price.toString();
   var decimal_pos = formatted_price.indexOf(".");

   if (decimal_pos == -1) {
      formatted_price += ".";
      decimal_pos = formatted_price.length - 1;
   }

   //                       |
   //                      \|/ calculates the current number of decimals
   var zeros_needed = 2 - (formatted_price.length - decimal_pos - 1);

   for (var i = 0; i < zeros_needed; i ++)
      formatted_price += "0";

   return formatted_price;
}


/** Determines if the current browser is a Netscape 4.x browser.
 *
 *  \treturn bool True if it is a netscape 4 browser, false otherwise.
 */
function _is_ns4()
{
   return document.layers && !document.getElementById;
}


/** Initializes a product option select box. Adds custom attributes
 *  to the options in the select box that contain the replacement image
 *  the price adjustment and the adjustment type.  This allows other
 *  functions to access this data as needed.
 *
 *  This function should be called once after a select box has been defined
 *  and populated. The Array parameters should have the same number of
 *  elements as there are options in the select box.
 *
 *  \alert You must call this function once for each option select box
 *         before using adjust_product_price() or replace_product_img()
 *
 *  \tparam String select_name
 *          The name (or the form element index) of the select box to
 *          initialize. If the value passed in is a number it is interpreted
 *          as an array index into the form elements array.
 *  \tparam String form_name
 *          The name of the form containing the select box.
 *  \tparam Array  images
 *          The replacement images to associate with the options.
 *  \tparam Array  adjusts
 *          The numeric price adjustments for each option.
 *  \tparam Array  adj_types
 *          The types of the adjustments above. '%' indicates percentage
 *          adjustment anything else indicates a fixed adjustment.
 */
function init_product_option( select_name, form_name, images,
                              adjusts, adj_types, left_img, right_img )
{
   var choice;
   var choice_idx = Number(select_name);

   if ( isNaN( choice_idx ) ) {
      choice = document[form_name][select_name];
   }
   else {
      choice = document[form_name].elements[choice_idx];
   }

   for ( var i = 0; i < choice.options.length; i ++ ) {
      var tmp = choice.options[i];
      if (adjusts) {
         tmp[IMAGE_KEY]       = images[i];
         tmp[ADJUST_KEY]      = adjusts[i];
         tmp[ADJUST_TYPE_KEY] = adj_types[i];
      }
      else {
         var items = tmp.value.split(";");
         var adjust = parseFloat(items[1]);
         var type;

         if ( isNaN(adjust) ) {
            adjust = 0;
         }

         if ( items[2] == 'percentage' ) {
            type = '%';
         }
         else {
            type = '$';
         }

         tmp[ADJUST_KEY]      = adjust;
         tmp[ADJUST_TYPE_KEY] = type;
         tmp[IMAGE_KEY]       = items[3];

         tmp.value = items[0];
      }
   }

   choice[IMAGE_DEFAULT_KEY] = [ left_img, right_img ];
}


/** Replaces the left and/or right product images with the replacement
 *  image of the selected option. If the selected option does not have
 *  a replacement image, the product image will be set to that of the
 *  normal left and/or right product image.
 *
 *  It is assumed that the image element is contained within the same form
 *  as the select box and that the left image is named \p left_img and that
 *  the right image is named \p right_img.
 *
 *  \alert You must call init_product_option() before calling this function.
 *
 *  \tparam Select choice The select box for which the onchange handler was
 *                        triggered.
 *  \tparam int    which  Specifies which image should be replaced. 0 = left,
 *                        1 = right, >1 = both;
 */
function replace_product_img( choice, which )
{
   var left  = false;
   var right = false;

   switch( which ) {
      case 0:
         left = true;
         break;
      case 1:
         right = true;
         break;
      default:
         left = right = true;
         break;
   }

   // set the default left image to the current left image url
   if ( !choice[IMAGE_DEFAULT_KEY][0] && choice.form.left_img ) {
      choice[IMAGE_DEFAULT_KEY][0] = choice.form.left_img.src;
   }

   // set the default right image to the current right image url
   if ( !choice[IMAGE_DEFAULT_KEY][1] && choice.form.right_img ) {
      choice[IMAGE_DEFAULT_KEY][1] = choice.form.right_img.src;
   }

   if ( left ) {
      var limg = choice.options[ choice.selectedIndex ][IMAGE_KEY];
      if (limg == "")
         limg = choice[IMAGE_DEFAULT_KEY][0];
      choice.form.left_img.src = limg;
   }

   if ( right ) {
      var rimg = choice.options[ choice.selectedIndex ][IMAGE_KEY];
      if (rimg == "")
         rimg = choice[IMAGE_DEFAULT_KEY][1];
      choice.form.right_img.src = rimg;
   }
}


/** Displays a popup window with the given title and the contents of body
 *  centered within a paragraph. The suid parameter is required if you want
 *  the page to be styled according to the account's global information
 *  settings.
 *
 *  \tparam string title the page title
 *  \tparam string body the page body
 *  \tparam string suid the member account id to get the global cfg from
 */
function popup( title, body, suid ) {
   h = screen.availHeight;
   w = screen.availWidth;

   var popW = 500;
   var popH = 230;

   var topPos = (h-popH)/2;
   var leftPos = (w-popW)/2;

   var url = '';
   var name = 'blah';

   mywindow = window.open('', '',
                          'dependent=no,status=yes,toolbar=no,' +
                          'location=no,resizable=yes,scrollbars=yes' +
                          ',width='   + popW +
                          ',height='  + popH +
                          ',screenX=' + leftPos +
                          ',screenY=' + topPos +
                          ',top='     + topPos +
                          ',left='    + leftPos);

   var doc =
      "<html><head>" +
      "<title>" + title + "</title>" +
      "<link rel='stylesheet' type='text/css' " +
        "href='/cgi-bin/ez-catalog/css_gen.cgi?SUID=" + suid + "' />" +
      "</head>" +
      "<body><center><h2>"  + title + "</h2></center>" +
      "<div align='left'>" +
      body +
      "</div>" +
      "<div align='center'><p>" +
      "<input type='button' value='Ok' name='close' " +
        "onclick='window.close()' />" +
      "</p></div>" +
      "</body></html>";

   mywindow.document.open();
   mywindow.document.write( doc );
   mywindow.document.close();
}


