/*
 * Copyright 2007 Aristidis Skarpetis, all rights reserved.
 * aris@infotub.com
 *
 */

// define variables exported in generated file design_array.js so they exist
var img_dir = null;
var browse_width = null;
var shirt_widths = null;
var dda = null;

// these are constants for the link in DD.display()
var LINK_VIEW = 10;	//!< click to view design and configute shirt size, colours and quantity
var LINK_ZOOM = 20;	//!< click to brink up zoomed version, also displays magnifying glass
var LINK_CART = 30;	//!< click to edit the shirt, also displays colour swatches
var LINK_HISTORY = 40;	//!< click to edit the shirt, also displays colour swatches, history item
var LINK_FRONTPAGE = 50;//!< click to edit the shirt, the table is left-aligned

// design summary object definition
function DD(id, title, cat_swim, cat_fly, cat_walk, cat_roll, cat_stuff, x, y, w, h, fa)
{
  this.id = id; // id of the image referer, not of the image
  this.title = title;

  this.cat_swim	= cat_swim;
  this.cat_fly	= cat_fly;
  this.cat_walk	= cat_walk;
  this.cat_roll	= cat_roll;
  this.cat_stuff= cat_stuff;
  
  this.comp_x = x;
  this.comp_y = y;
  this.comp_w = w;
  this.comp_h = h;

  this.fa = fa; // img attributes

  // 10k to width transformations
  this.scale = function(w, n) { return Math.round((w * n) / 10000.0); }  
  this.x = function(w) { return this.scale(w, this.comp_x); }
  this.y = function(w) { return this.scale(w, this.comp_y); }
  this.w = function(w) { return this.scale(w, this.comp_w); }
  this.h = function(w) { return this.scale(w, this.comp_h); }
  /**
   *  gets the img tag attributes src, width, height set to the correct values for the specified width
   * {PRE: shirt_widths array is defined and filled}
   * {PRE: img_dir is defined and it points to the relative directory where the design images are, no trailing slash}
   */
  this.img = function(w) {
    for (var i = 0; i < shirt_widths.length; i++) {
      if (shirt_widths[i] == w) {
	return "src=\"" + img_dir + "/" + this.fa[i] + "\" width=\"" + this.w(w) + "\" height=\"" + this.h(w) + "\"";
      }
    }
    return "src=\"images/spc.png\" width=\"16\" height=\"16\"";
  }


  /**
   * This function saves us a great deal of bandwidth.
   * It prints the shirts on the client side rather than us sending all the table HTML from PHP.
   * The disadvantage is that without JavaScript the user cannot see the shirts.
   * This is fine considering without it they cannot pick categories from the category picker either.
   *
   * @param w the width at which you want to render the shirt, a COMPXXX style is expected to exist for the width
   * @param gv_cat the categories in the form browse.inc likes, supply false if you don't have it
   * @param link_type one of LINK_XXXX
   * @param id_cartitem when LINK_CART link_type, "cartitem=" to this value will be added in the link line if this is non-zero positive, for LINK_HISTORY this will be the serialised cart item string and "history=" to this value will be added to the link line
   * @param extra some link types allow extra HTML to be added to the bottom part of the shirt, supply null for all other types, note that if this turns out wider than w the shirt will be distorted
   */
  this.display = function(w, gv_cat, link_type, id_cartitem, extra) {

    if (gv_cat == false) gv_cat = "all";


    var dlink;
    var img_id;
    var tbl_id;

    switch (link_type) {

    case LINK_ZOOM:
      dlink = "<a"
	+ " href=\"#\""
	+ " onFocus=\"if(this.blur)this.blur()\"" // see browse.php::printCatChooser()
	+ " onclick=\"setZoomVisible(true); return false;\""
	+ ">";
      img_id = "the_design_image";
      tbl_id = "the_design_table";
      break;


    case LINK_CART:
      // make the link
      var gv_all = "";
      if ((id_cartitem > 0) || (gv_cat != null)) {
	gv_all = "?";
	if (id_cartitem > 0) gv_all += "cartitem=" + id_cartitem;
	if (gv_cat != null) {
	  if (id_cartitem > 0) gv_all += "&";
	  gv_all += "cat=" + gv_cat;
	}
      }
      dlink = "<a"
	+ " name=\"cart" + this.id + "\"" // TO-DO: when we implement cart item IDs, use that instead
	+ " title=\"" + this.title + "\""
	+ " alt=\"" + this.title + "\""
	+ " href=\"browse.php"
	+ gv_all
	+ "\""
	+ " onFocus=\"if(this.blur)this.blur()\""
	+ ">";
      img_id = "cart" + this.id;
      tbl_id = "tbl" + this.id;
      break;


    case LINK_HISTORY:
      dlink = "<a"
      + " name=\"design" + this.id + "\"" // for autoscrolling to this design
      + " title=\"" + this.title + "\""
      + " alt=\"" + this.title + "\""
      + " href=\"browse.php?history=" + id_cartitem + "&cat=" + gv_cat + "\""
      + " onFocus=\"if(this.blur)this.blur()\""
      + ">";
      img_id = "design" + this.id;
      tbl_id = "tbl" + this.id;
      break;


    case LINK_VIEW:
    case LINK_FRONTPAGE:
    default:
      dlink = "<a"
      + " name=\"design" + this.id + "\"" // for autoscrolling to this design
      + " title=\"" + this.title + "\""
      + " alt=\"" + this.title + "\""
      + " href=\"browse.php?view=" + this.id + "&cat=" + gv_cat + "\""
	//+ " href=\"javascript:viewDesign(" + this.id + ", '" + gv_cat + "')\""
      + " onFocus=\"if(this.blur)this.blur()\""
      + ">";
      img_id = "design" + this.id;
      tbl_id = "tbl" + this.id;
      break;
    }

    // {PRE: if w is less than 200, it divides into it}
    // 48 & 39 and the heights of the shirt parts top & bottom at 200
    var th = Math.round((w / 200) * 48);
    var bh = Math.round((w / 200) * 39);

    // title
    //document.writeln("<p>" + this.title + "</p>");

    document.writeln("<table id=\"" + tbl_id + "\""
		     + "align=\"" + ((link_type == LINK_FRONTPAGE) ? "left" : "center") + "\"" 
		     + ((link_type == LINK_FRONTPAGE) ? " style=\"margin-right: 2ex; \"" : "")
		     + " class=\"DESIGN\""
		     + " border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"" + w + "\">");
    if (link_type == LINK_VIEW) {
      document.writeln("<a name=\"anchor" + this.id + "\"></a>");
    }
    //{PRE: shirt_of_the_week has been defined elsewhere in the page}
    document.write("<tr><td class=\"COMP" + w + "TOP" + (this.id == shirt_of_the_week ? "SOW" : "") + "\">" + dlink
		   + "<img class=\"PAD\" src=\"images/spc.png\" width=\"" + w + "\" height=\"" + th + "\" />"
		   + "</a></td></tr>");

    document.writeln("<tr><td class=\"COMP" + w + (this.id == shirt_of_the_week ? "SOW" : "") + "\">" + dlink);

    document.write("<img class=\"PAD\" src=\"images/spc.png\" width=\"" + w + "\" height=\"" + this.y(w) + "\" />");

    document.write("<img class=\"PAD\" src=\"images/spc.png\" width=\"" + this.x(w) + "\" height=\"" + this.h(w) + "\" />");
    document.write("<img id=\"" + img_id + "\" class=\"DESIGN\" " + this.img(w) + " />");
    document.write("<img class=\"PAD\" src=\"images/spc.png\" width=\"" + (w - this.x(w) - this.w(w)) + "\" height=\"" + this.h(w) + "\" />");

    document.write("<img class=\"PAD\" src=\"images/spc.png\" width=\"" + w + "\" height=\"" + (w - this.y(w) - this.h(w)) + "\" />");

    document.write("</a></td></tr>");

    var style = null;
    if (link_type == LINK_VIEW) {
      style =  " style=\"text-align: center; vertical-align: top; \"";
    }
    document.write("<tr><td class=\"COMP" + w + "BOT\"" + (this.id == shirt_of_the_week ? "SOW" : "") + (style != null ? style : "") + ">");


    if (link_type == LINK_ZOOM) {
      document.write(dlink + "<img src=\"images/spc.png\" width=\"" + (w - 30) + "\" height=\"" + bh + "\" />"
		     + "<img align=\"top\" src=\"images/zoom_in.gif\" width=\"23\" height=\"23\" /></a>");
    } else if ((link_type == LINK_CART) || (link_type == LINK_HISTORY)) {
      document.write(dlink);
      document.write("<img src=\"images/spc.png\" width=\"" + w + "\" height=\"1\" />");
      if (extra != null) {
	document.write(extra);	
      }
      document.write("</a>");      
    } else {
      //{PRE: show_titles boolean has been defined, probably exported from PHP}
      if (show_titles) {
	document.write("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" align=\"center\">"
		       + "<tr><td class=\"BTXTSML\" style=\"padding-right: 0.5ex; \">");
	document.write(dlink + this.title + "</a>");
	document.write("</td><td style=\"white-space: nowrap; \">" + dlink); // inherit for IE5
	if (this.cat_swim)	document.write("<img src=\"im/tag_01.gif\" width=\"20\" height=\"20\" />");
	if (this.cat_fly)	document.write("<img src=\"im/tag_02.gif\" width=\"20\" height=\"20\" />");
	if (this.cat_walk)	document.write("<img src=\"im/tag_03.gif\" width=\"20\" height=\"20\" />");
	if (this.cat_roll)	document.write("<img src=\"im/tag_04.gif\" width=\"20\" height=\"20\" />");
	if (this.cat_stuff)	document.write("<img src=\"im/tag_05.gif\" width=\"20\" height=\"20\" />");
	document.write("</a></td></tr></table>");
	
      } else {
	document.write(dlink + "<img src=\"images/spc.png\" width=\"" + w + "\" height=\"" + bh + "\" /></a>");
      }
    }

    document.writeln("</td></tr></table>");

  }

}

/** Design zoom image specification */
function DZ(x, y, w, h, img)
{
  this.x = x;
  this.y = y;
  this.w = w;
  this.h = h;
  this.img = img;
}

// garment size summary object definition
function GS(id, size, width, length, sleeve)
{
  this.id = id; // id of the image referer, not of the image

  this.size = size;
  this.width = width;
  this.length = length;
  this.sleeve = sleeve;

  this.DEBUG = function() {
    document.writeln("id:" + this.id +
		   ", size:" + this.size +
		   ", width:" + this.width + "cm" +
		   ", length:" + this.length + "cm" +
		   ", sleeve:" + this.sleeve + "cm" +
		     "<br />");
  }
}

//--INIT------------------------------------------------

// expressions to be executed onload
var load_exec = new Array();
// initLoad has run
var init_load_ok = false;
function addLoadExec(exec_func)
{
  load_exec[load_exec.length] = exec_func;  
}

function initLoad()
{
  for (i = 0; i < load_exec.length; i++) {
    eval(load_exec[i]);
  }
  init_load_ok = true;
}
 

     
// expressions to be executed onresize
var resize_exec = new Array();
// initResize has run
var init_resize_ok = false;
function addResizeExec(exec_func)
{
  resize_exec[resize_exec.length] = exec_func;
}

function initResize()
{
  for (i = 0; i < resize_exec.length; i++) {
    eval(resize_exec[i]);
  }
  init_resize_ok = true;
}


/**
 * Initialised by initPageMetrics()
 */
var metrics = {
  vw: 0, vh: 0,	// the container dimension (window or frame)
  px: 0, py: 0,	// scroll offset
  pw: 0, ph: 0	// size of the document
};
/**
 * Cross browser viewport dimensions, scrolling offset, viewport dimensions.
 * credit: http://www.quirksmode.org/viewport/compatibility.html
 */
function initPageMetrics()
{
  // Inner dimensions of window or frame containing the body (viewport vx, vy)
  if (self.innerHeight) // all except Explorer
    {
      metrics.vw = self.innerWidth;
      metrics.vh = self.innerHeight;
    }
  else if (document.documentElement && document.documentElement.clientHeight) // Explorer 6 Strict Mode
    {
      metrics.vw = document.documentElement.clientWidth;
      metrics.vh = document.documentElement.clientHeight;
    }
  else if (document.body) // other Explorers
    {
      metrics.vw = document.body.clientWidth;
      metrics.vh = document.body.clientHeight;
    }


  // Scrolling offset (px, py)
  if (self.pageYOffset) // all except Explorer
    {
      metrics.px = self.pageXOffset;
      metrics.py = self.pageYOffset;
    }
  else if (document.documentElement && document.documentElement.scrollTop) // Explorer 6 Strict    
    {
      metrics.px = document.documentElement.scrollLeft;
      metrics.py = document.documentElement.scrollTop;
    }
  else if (document.body) // all other Explorers
    {
      metrics.px = document.body.scrollLeft;
      metrics.py = document.body.scrollTop;
    }

  // Page height (pw, ph)
  // The height of the body element.
  // From original page: this is a tricky one, some browsers require scrollHeight, others offsetHeight, but all browsers support both properties.
  // Therefore I see which property has the larger value. This means the page height the script below gives is never smaller than the window height.
  var test1 = document.body.scrollHeight;
  var test2 = document.body.offsetHeight
    if (test1 > test2) // all but Explorer Mac
      {
	metrics.pw = document.body.scrollWidth;
	metrics.ph = document.body.scrollHeight;
      }
    else // Explorer Mac; would also work in Explorer 6 Strict, Mozilla and Safari
      {
	metrics.pw = document.body.offsetWidth;
	metrics.ph = document.body.offsetHeight;
      }

}

//--------------------------------------------------

function adjustWidth_logo(ew)
{
  var logo = document.getElementById("the_logo");
  if (logo === null) { return; }

  var w = albino_page_width * 2;

  if ((ew > w) && (logo.height == 70)) {
    logo.width = 442;
    logo.height = 140;
    logo.src = "images/ALBINO_splat_140h.gif";
  } else if ((ew < w) && (logo.height == 140)) {
    logo.width = 221;
    logo.height = 70;
    logo.src = "images/ALBINO_splat_70h.gif";
  }
}

var epicentre_call_counter = 0;

/**
 * event handler
 *
 * Checks the item with id "the_epicentre" to see if its width exeeds (2 * albino_page_width).
 * \a albino_page_width is generated by PHP.
 *
 * If the width has doubled, we adjust a number of graphics to be bigger.
 */
function checkEpicentre()
{
  // {PRE: albino_page_width has been defined by PHP }
  if (typeof(albino_page_width) == "undefined") { return; }
  if (albino_page_width < 400) { return; }

  ++epicentre_call_counter;

  var the_id = "the_epicentre";

  var epi = document.getElementById(the_id);
  if (epi == null) { return; }

  
  //--------------------
  //
  var debug = false;
  //
  //--------------------

  var logo, status, msg;
  if (debug) {
    logo = document.getElementById("the_logo");    
    status = document.getElementById("the_status");
    msg = "count:" + epicentre_call_counter
      + " epiw:" + epi.offsetWidth
      + " albino_page_width:" + albino_page_width
      + " logo_init:" + logo.src;
  }
  //--------------------


  // adjust the logo size
  adjustWidth_logo(epi.offsetWidth);

  
  // NOTES: At the moment, this is an onreisze and an onkeyup handler,
  // maybe it should be launched by a TIMER which runs every 3-4 seconds
  // which simply checks that the epicentre size has changed and if it has,
  // it calls this and we dispose with inconsistent event dispatching across browsers
  //
  // Called via onresize and onkeyup:
  // - FireFox OK
  // - Opera calls this OK but its zoom zooms everything in the page and does not change the offsetWidth, it may be keeping the real pixel width elsewhere
  // - Safari consumes the CMD+plus and CMD+minus keystrokes end the DOM does not get them
  // - Explorer ???


  // TO-DO:
  //
  // adjust:
  // 
  // - size of the shirts in the cart summary, the browser, the full cart content
  // - size of the markers, the chroma in the colour picker
  // - size and position of the zoomed shirt in the colour picker



  //--------------------
  if (debug) {
    if ((status != null) && (msg.length > 0)) {
      status.innerHTML = msg
	+ " logo_fin:" + logo.src;    
    }
  }
  //--------------------

}

//--------------------------------------------------

/**
 * Preloads the images needed for the category rollovers
 */
function preloadSubImages()
{
  if (document.images) {
    var img_src = new Array();
    var i = 0;
    img_src[i++] = "im/da_01.png";
    img_src[i++] = "im/da_02.png";
    img_src[i++] = "im/da_03.png";
    img_src[i++] = "im/da_04.png";
    img_src[i++] = "im/da_05.png";
    img_src[i++] = "im/di_01.png";
    img_src[i++] = "im/di_02.png";
    img_src[i++] = "im/di_03.png";
    img_src[i++] = "im/di_04.png";
    img_src[i++] = "im/di_05.png";    

    img_src[i++] = "im/sa_01.png";
    img_src[i++] = "im/sa_02.png";
    img_src[i++] = "im/sa_03.png";
    img_src[i++] = "im/sa_04.png";
    img_src[i++] = "im/sa_05.png";
    img_src[i++] = "im/si_01.png";
    img_src[i++] = "im/si_02.png";
    img_src[i++] = "im/si_03.png";
    img_src[i++] = "im/si_04.png";
    img_src[i++] = "im/si_05.png";    

    var preload_obj = new Image(35, 31);
    for (i = 0; i < img_src.length; i++) {
      preload_obj.src = img_src[i];
    }
  }
}

function preloadDotImages()
{
  //{PRE: preload_a is an array in the global namespace}
  if (document.images) {
    var i = 0;
    for (i = 0; i < allmrk.length; i++) {
      img = new Image(16, 16);
      img.src = allmrk[i].src;
      preload_a.push(img);      
    }
  }
}

/**
 * IMPORTANT:
 * If we change the marker naming we have to also change this.
 */
function preloadMarkerImages()
{
  //{PRE: preload_a is an array in the global namespace}
  if (document.images) {
    var i = 0;
    var s = "images/";
    for (i = 0; i < allmrk.length; i++) {
      var img = new Image();
      img.src = s + "tip" + allmrk[i].src.substr(s.length + 3);
      preload_a.push(img);
    }
  }
}

/**
 * ***** IMPORTANT *******
 * Make sure to update when new sizes are added.
 *
 * Images use to make up the shirt of a given width.
 * Make multiple calls if you need multiple widths.
 */
function preloadShirtImages(width)
{
  // clamping for safety and future compatibility
  if (width < 50) {
    width = 50;
  } else if ((width > 50) && (width < 100)) {
    width = (width < 75 ? 50 : 100);
  } else if ((width > 100) && (width < 200)) {
    width = (width < 150 ? 100 : 200);
  } else if ((width > 200) && (width < 400)) {
    width = (width < 300 ? 200 : 400);
  } else if (width > 400) {
    width = 400;
  }

  var im1 = new Image();
  var im2 = new Image();
  var im3 = new Image();
  var im4 = new Image();
  var im5 = new Image();
  var im6 = new Image();

  switch (width) {
  case 50:
    im1.src = "images/REF_50_01.jpg";
    im2.src = "images/REF_50_02.jpg";
    im3.src = "images/REF_50_03.jpg";    
    im4.src = "images/REF_SOW_50_01.jpg";
    im5.src = "images/REF_SOW_50_02.jpg";
    im6.src = "images/REF_SOW_50_03.jpg";    
    break;
  case 100:
    im1.src = "images/REF_100_01.jpg";
    im2.src = "images/REF_100_02.jpg";
    im3.src = "images/REF_100_03.jpg";
    im4.src = "images/REF_SOW_100_01.jpg";
    im5.src = "images/REF_SOW_100_02.jpg";
    im6.src = "images/REF_SOW_100_03.jpg";
    break;
  case 200:
    im1.src = "images/REF_200_01.jpg";
    im2.src = "images/REF_200_02.jpg";
    im3.src = "images/REF_200_03.jpg";
    im4.src = "images/REF_SOW_200_01.jpg";
    im5.src = "images/REF_SOW_200_02.jpg";
    im6.src = "images/REF_SOW_200_03.jpg";
    break;
  case 400:
    im1.src = "images/REF_400_01.jpg";
    im2.src = "images/REF_400_02.jpg";
    im3.src = "images/REF_400_03.jpg";
    im4.src = "images/REF_SOW_400_01.jpg";
    im5.src = "images/REF_SOW_400_02.jpg";
    im6.src = "images/REF_SOW_400_03.jpg";
    break;
  default:
    break;
  }

  //{PRE: preload_a is an array in the global namespace}
  preload_a.push(im1, im2, im3, im4, im5, im6);
}


/**
 * Toggles the visibility of the submenu row and adjust the active category button bottom to 
 * Make sure you have preloaded images.
 */
function toggleSubRow()
{
  var t = document.getElementById("cat_table");
  var c = t.rows.length;

  var bot = document.getElementById("active_cat");

  // zero-based indices
  var i = 1;

  if (t.rows[i].style.display != "none") {
    t.rows[i].style.display = "none";
    bot.src="im/bot_s.png";
  } else {
    t.rows[i].style.display = "";
    bot.src="im/bot_m.png";
  }  
  
}


/**
 * Toggles the subcategory icon from active to innactive (im/sa_00.png & im/si_00.png)
 *
 * @param subcat the number of the category icon
 */
function toggleSubIcon(subcat)
{

  var img = document.getElementById("s_0" + subcat);
  if (img == undefined) {
    alert("undefined category");
    return;
  }

  // extract the document base
  var base = document.URL;
  var i = document.URL.lastIndexOf('/');
  if (i > -1) {
    base = document.URL.substr(0, i);
  }
 

  // prepend the document base
  var sa = base + "/im/sa_0" + subcat + ".png";
  var si = base + "/im/si_0" + subcat + ".png";

  if (img.src == sa) {
    img.src = si;
  } else {
    img.src = sa;
  }
 
}

//--SHIRT------------------------------------------------

/* for onresize handler */
function adjustZoomShirt()
{
  if (isVisible("the_zoom")) {
    setZoomVisible(true);
  }
}

function setZoomVisible(b)
{
  var zoom = document.getElementById("the_zoom");
  if (zoom == null) return;
  var zc = document.getElementById("the_zoom_cell");
  if (zc == null) return;

  var logo = document.getElementById("the_logo");
  var logo_p = { x: 0, y:0 };
  pageCoords("the_logo", logo_p);

  if (b) {

    // NOTE: zc.offsetWidht is zero until the zoom has been shown
    var zw = 0;
    if (zoom.style.width) {
      /*
       * *********** HACK ???? *************
       * we use pixel units so style.width has "px" appended to it,
       * parseInt() seems to succesfylly strip it, saw it at some site I cannot remember
       */
      zw = parseInt(zoom.style.width);
    } else if (zoom.width) {
      zw = zoom.width;
    }

    zoom.style.left = ((metrics.pw - zw) / 2.0) + "px";
    if ((logo != null) && (logo_p.x > 0)) {
      zoom.style.top = (logo_p.y + logo.height) + "px";
    } else {      
      zoom.style.top = "100px";
    }

  }

  zoom.style.display = (b ? "" : "none");

  //--DEBUG--
  /*
  if (b) {
    alert("setZoomVisible()"
    + " vdw:" + dw
    + " zw:" + zw
    + " lt:" + (logo == null ? "null" : logo_p.y)
    + " nl:" + zoom.style.left   
    + " nw:" + zoom.style.width
    + " zcw:" + zc.offsetWidth
    + " zch:" +  zc.offsetHeight
    + " src:" + design_original_src_zoom
    + " events: " + event_buffer
    );
    //zoom.style.top = "100px";
    //zoom.style.left = "300px";
  }
  */




  // in IE6 form elements portrude through the layer and we need to hide them
  // we put an empty iframe behind the layer and it covers up all form elements
  // hiding the elements with the style.display property causes the layout to jump
  var frame = document.getElementById("the_zoom_iframe");
  // the container table's cell in which the shirt table is placed
  if ((frame != null) && (zc != null)) {
    frame.style.display = (b ? "" : "none");
    frame.style.left = zoom.style.left;
    frame.style.top = zoom.style.top;
    // these are non-zero now that the zoom has been displayed
    frame.width = zc.offsetWidth;
    frame.height = zc.offsetHeight;
  }
}

//----------------------------------------------------------------------------------------------------


function hideHelper()
{
  var helper = document.getElementById("the_helper");
  if (helper == null) return;
  helper.style.display = "none";
}

/**
 * Set the helper text to \a text and show it in the middle on the document
 * @param text display this in the helper, if you are happy with what it already has on it, supply nothing.
 */
function showHelper()
{
  var helper = document.getElementById("the_helper");
  if (helper == null) return;

  if (arguments.length > 0) {
    var d = document.getElementById("the_helper_text");
    if (d == null) return;
    d.innerHTML = arguments[0];
  }

  

  helper.style.display = ""; // helper.offsetWidth and Height are zero until the element is shown, so we show first then adjust

  adjustHelper();
}

function adjustHelper()
{
  var helper = document.getElementById("the_helper");
  if (helper == null) return;

  if (helper.style.display != "none") {
    helper.style.left = (metrics.px + ((metrics.vw - helper.offsetWidth) / 2)) + "px";
    helper.style.top = (metrics.py + ((metrics.vh - helper.offsetHeight) / 2)) + "px";
  }
}

/**
 * Only use this to affect the positioning of a table.
 * It will output this: <img><br><img> but the images will be sqaure and randomly between zero and max pixels
 */
function jitter(max)
{
  var x = Math.round(Math.random() * max);
  var y = Math.round(Math.random() * max);
  if (y > 0) {
    document.write("<img class=\"JIT\" src=\"images/spc.png\" width=\"" + y + "\" height=\"" + y + "\" />");
    document.write("<br />");
  }
  if (x > 0) {
    document.write("<img align=\"left\" class=\"JIT\" src=\"images/spc.png\" width=\"" + x + "\" height=\"" + x + "\" />");
  }
}

/**
 * The image src of the design before any chroma was clicked.
 * It is set by bufferDesignOrgSrc();
 */
var design_original_src = null;
var design_original_src_zoom = null;
function bufferDesignSrc()
{
  var img = document.getElementById("the_design_image");
  if (img != null) design_original_src = img.src;
}
function bufferDesignSrcZoom()
{
  var img = document.getElementById("the_zoom_design_image");
  if (img != null) design_original_src_zoom = img.src;
}

/**
 * Displays a single shirt with the design whose id is the parameter.
 * Clicking on the shirt will zoom in on it.
 *
 * {PRE: browse_width is defined}
 */
function displayShirtWithZoom(id, gv_cat)
{
  for (var i = 0; i < dda.length; i++) {
    if (id == dda[i].id) {
      dda[i].display(browse_width, gv_cat, LINK_ZOOM, null);
      return;
    }
  }
}



/**
 * Displays a shirt with a design on it.
 * This function's argument list is becoming a little long.
 *
 * @param w width to render the shirt at
 * @param id_design design whose image we will use on the shirt
 * @param link_type one of LINK_XXX as needed by DD.display()
 * @param id_cartitem the id of the cart item, or null
 * @param gv_cat GET["gv_cat"] as propagated from browse.php, or null
 * @param extra anything extra you want to put at the bottom of the shirt, or null
 */
function displayShirt(w,
		      id_design, link_type,
		      id_cartitem,
		      gv_cat, extra)
{
  for (var i = 0; i < dda.length; i++) {
    if (id_design == dda[i].id) {
      dda[i].display(w, gv_cat, link_type, id_cartitem, extra);
      return;
    }
  }
}


/**
 * Displays the title of the given design
 */
function displayTitle(id)
{
  for (var i = 0; i < dda.length; i++) {
    if (id == dda[i].id) {
      document.write(dda[i].title);
      return;
    }
  }
}


/**
 * Prints the shirts in the array dda of DD objects.
 * Clicking on a shirt will take you to its detailed view.
 *
 * {PRE: browse_width is defined}
 *
 * @param cat the cat get variable from the caller
 * @param columns how many columns to present the designs in
 * @param is_xxxx categories
 */
function printShirts(gv_cat, columns, is_random, is_swim, is_fly, is_walk, is_roll, is_stuff)
{
  // combine the categories 

  var jitter_max = 8;

  if (is_random) {

    var random_count = 6;

    // {PRE: there are at least random_count designs in dda}

    var slice = 1.0 / (dda.length + 0.0);
    var ra = new Array();
    for (var i = 0; i < random_count; i++) {      
      var pick = -1;
      while (pick < 0) {
	pick = Math.floor(Math.random() / slice); // Math.round was giving us indices out of range
	have_unique = true;
	for (var k = 0; k < ra.length; k++) {
	  if (ra[k] == pick) {
	    pick = -1;
	    break;
	  }
	}
      }
      ra.push(pick);
    }

    /*
    // all designs
    document.write("<p align=\"center\">");
    for (i = 0; i < dda.length; i++) {      
    document.write("<b>" + i + ":</b>" + dda[i].id + " ");
    }    
    document.write("</p>\n");
    // randomly picked
    document.write("<p align=\"center\">");
    document.write("(" + ra.length + " from " + dda.length + ") ");
    for (i = 0; i < ra.length; i++) {
    document.write("<b>" + i + ":</b>" + ra[i] + " - ");
    }
    document.writeln("done</p>");
    */
  }


  document.writeln("<table align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">");
  document.writeln("<tr>");
  var count = 0;
  if (is_random) {

    for (var i = 0; i < ra.length; i++) {
      if ((count > 0) && (count % columns == 0)) {
	document.write("</tr>\n<tr>");
      }

      document.write("<td>");
      jitter(jitter_max);
      dda[ra[i]].display(browse_width, gv_cat, LINK_VIEW, null);
      document.write("</td>");

      ++count;
    }

    // LANG
    // This phrase must be supplied from somewhere else in the future
    if (count == 0) {
      document.write("<td class=\"NODTXT\">");
      document.write("I am sorry but I could not pick any designs for you!");
      document.write("</td>");
    }

  } else {

    var use = false;
    var all = (gv_cat == "all");
    //all  = is_swim && is_fly && is_walk && is_roll && is_stuff;

    for (var i = 0; i < dda.length; i++) {

      // this needs to be combined so if we have is_swim AND is_walk
      // we must show all designs that amongst others belong to both swim AND walk categories
      use = true;
      if (!all) { 
	if (use && is_swim)	use = dda[i].cat_swim;
	if (use && is_fly)	use = dda[i].cat_fly;
	if (use && is_walk)	use = dda[i].cat_walk;
	if (use && is_roll)	use = dda[i].cat_roll;
	if (use && is_stuff)	use = dda[i].cat_stuff;
      }

      if (use) {
	if ((count > 0) && (count % columns == 0)) {
	  document.write("</tr>\n<tr>");
	}

	document.write("<td>");
	jitter(jitter_max);
	dda[i].display(browse_width, gv_cat, LINK_VIEW, null);
	document.write("</td>");

	++count;
      }
    }

    // LANG: err_msg
    if (count == 0) {
      var err_msg;
      if (all) {
	err_msg = "Hmmm... it looks like our designs are not available right now. Try again later.";
      } else {
	var err_a = new Array();
	var i = 0;
	if (is_swim)	err_a[i++] = "swim";
	if (is_fly)	err_a[i++] = "fly";
	if (is_walk)	err_a[i++] = "walk";
	if (is_roll)	err_a[i++] = "roll";
	if (is_stuff)	err_a[i++] = "is stuff";
	if (err_a.length == 0) {
	  err_msg = "Click on a category so you can see the designs.";
	} else {
	  var s;
	  for (i = 0; i < err_a.length; i++) {
	    if (i == 0) {
	      s = "<b>" + err_a[0] + "</b>";
	    } else if (i == (err_a.length - 1)) {
	      s += " and " + "<b>" + err_a[i] + "</b>";
	    } else {
	      s += ", " + "<b>" + err_a[i] + "</b>";
	    }
	  }
	  // {PRE: each category has at least one design}
	  err_msg = "I am sorry but I don't have anything to show you that can " + s + ".<br />Try combining fewer categories.";
	}
      }
      document.write("<td class=\"NODTXT\">");
      document.write("<p>&nbsp;</p>");
      document.write(err_msg);
      document.write("</td>");
    }

  }


  document.writeln("</tr>");
  document.writeln("</table>");

}

//--------------------------------------------------

// marker colour definition
// used for allmrk array
function MRK(type, name, src)
{
  this.type = type;	// marker type string, currently CFM or ASM
  this.name = name;	// name of the marker colour
  this.src = src;	// dot image
  this.quantity = 0;	// quantity of this marker, limited to 2 by the functions here
}

// altername marker definition for setMerkers() and useChroma()
// we use this to set which markers are selected in allmrk array
function MMRK(type, name, quantity)
{
  this.type = type;		// marker type string, currently CFM or ASM
  this.name = name;		// name of the marker colour
  this.quantity = quantity;	// quantity of this marker, limited to 2 by the functions here
}

// {PRE: string offmrk is declared and is set to the path of the empty market image}
// {PRE: array of markers allmrk is declared and initialised to contain an MRK object for each marker, MRKs are flagged visible or not during interaction }


function removeMarker_priv(n, refresh)
{
  if (n < 0) return;
  if (n >= allmrk.length) return;

  --allmrk[n].quantity;  

  if (allmrk[n].quantity < 0) {
    allmrk[n].quantity = 0;
  }
  if (refresh) {
    updateDisplay();
  }
}

function addMarker_priv(n, refresh)
{
  if (n < 0) return;
  if (n >= allmrk.length) return;

  ++allmrk[n].quantity;

  if (allmrk[n].quantity > 2) {
    allmrk[n].quantity = 0; // so the user can easily remove a marker in case they double clicked
  }
  if (refresh) {
    updateDisplay();
  }
}

/**
 * NOTE: added ondblclick handler as IE6 felt constipated when you clicked furiously.
 * Trouble is all other browsers are firing a double click AND two single clicks
 * which means using the ondblclick handler on the other browsers makes them feel weird.
 * The solution is to ignore events that come together since the double click will come at the same time as the second click
 * therefore the second can safely be ignored.
 */
var last_event_stamp = 0;
var event_buffer = null;
/**
 * @return true if the time of call and last_event_stamp are the same, false if they are different (also sets last_event_stamp to call time)
 */
function eventCheck()
{  
  var d = new Date();
  var t = d.getTime();

  event_buffer += "_" + t;
  
  // WORKS:
  // I am avoiding adding an event listener for double and single clicks
  // if events are less than 100ms apart, I return false.
  if ((t - last_event_stamp) < 100) return true;

  last_event_stamp = t;
  return false;
}
/**
 * Event handler
 */
function removeMarker(n)
{
  if (eventCheck()) return;
  removeMarker_priv(n, true);  
}
/**
 * Event handler
 */
function addMarker(n)
{
  if (eventCheck()) return;
  addMarker_priv(n, true);
}

/**
 * Rounds the given number to two decimals and returns a string which is made to have trailing zeros if needed.
 * I do not check the type so make sure you supply a number.
 */
function twoDecimals(n)
{
  // round to 2 decimals
  n = Math.round(100.0 * n) / 100.0;

  // make sure we have 2 decimals
  n = "" + n;
  var dot = n.indexOf('.');
  if (dot > -1) {
    if (dot == n.length - 2) {
      n += "0";
    }
  } else {
    n += ".00";
  }

  return n;
}

// just for display, the total will be specified at checkout
function updateTotal() // MONEY
{
  var price = document.getElementById("the_price");
  if (price == null) return;

  // {PRE: numbers cost_shirt, cost_cfm_marker, cost_asm_marker are defined, string currency_symbol is defined}

  var total = cost_shirt; // MONEY
  //{PRE: free_cfm_count has been defined}
  var free_cfm = (typeof(free_cfm_count) != "undefined") ? free_cfm_count : 3;
  // scan for marker quantities
  var cfm_count = 0;
  var asm_count = 0;
  var i;
  for (i = 0; i < allmrk.length; i++) {
    if (allmrk[i].quantity > 0) {
      if (allmrk[i].type == "CFM") {
	cfm_count += allmrk[i].quantity;
      } else if (allmrk[i].type == "ASM") {
	asm_count += allmrk[i].quantity;
      }
    }
  }
  if (cfm_count > free_cfm) {
    total += (cfm_count - free_cfm) * cost_cfm_marker;
  }
  if (asm_count > 0) {
    total += asm_count * cost_asm_marker;
  }

  // multiply by quantity
  var f = document.getElementById("cc_form");
  if (f != null) {
    total = total * f.elements["cc_quantity_select"].value;
  }

  // test IE
  price.innerHTML = "<b>"
    + "Total" // LANG
    + ":</b>&nbsp;"
    + currency_symbol // MONEY
    + twoDecimals(total); // MONEY
  // no VAT
    //+ "<br />(" + currency_symbol + twoDecimals(total / 1.19) + " ex.VAT)"; // MONEY
}

function updateDisplay()
{  
  var dot_a;  // DOM image by id
  var dot_b;  // DOM image by id

  // {PRE: quantity checks are performed in addMarker(), removeMarker() }
  for (var i = 0; i < allmrk.length; i++) {
    dot_a = document.getElementById("dot_a_" + i);
    dot_b = document.getElementById("dot_b_" + i);
    if (allmrk[i].quantity == 0) {
      if (dot_a != null) dot_a.src = offmrk;
      if (dot_b != null) dot_b.src = offmrk;
    } else if (allmrk[i].quantity == 1) {
      if (dot_a != null) dot_a.src = allmrk[i].src;
      if (dot_b != null) dot_b.src = offmrk;
    } else if (allmrk[i].quantity == 2) {
      if (dot_a != null) dot_a.src = allmrk[i].src;
      if (dot_b != null) dot_b.src = allmrk[i].src;
    }
  }

  updateTotal();
}

function setMarkers_priv_ORG(ma, clear)
{
  if (ma == null) return;
  if (ma.length < 1) return;

  var i;
  var j;

  // clear user choices
  if (clear) {
    for (i = 0; i < allmrk.length; i++) {
      allmrk[i].quantity = 0;
    }
  }

  // set the quantities from the passed objects to allmrk
  for (i = 0; i < ma.length; i++) {
    for (j = 0; j < allmrk.length; j++) {
      if ((ma[i].type == allmrk[j].type)
	  && (ma[i].name == allmrk[j].name)) {
	allmrk[j].quantity += ma[i].quantity;
	// clamp
	if (allmrk[j].quantity < 0) allmrk[j].quantity = 0;
	if (allmrk[j].quantity > 2) allmrk[j].quantity = 2;
      }
    }
  }


  updateDisplay();
}


/**
 * Between the requirements of adding marker sets and setting the marker set, we made some provisions.
 * @param ma the set to scan
 * @param accum if true, the marker quantities are accumulated by one i.e. accumulator mode, false will clear all quantities and set the quantities from the supplied set, i.e. regular mode
 */
function setMarkers_priv(ma, accum)
{
  if (ma == null) return;
  if (ma.length < 1) return;

  var i;
  var j;


  var maxq = 0; // the max quantity of a marker in the union of the current set and the parameter set
  var maxall = true; // are all the markers in the union of the two set at the same quantity?
  var last_max = 0;
  //
  // evaluate the state of the union
  //
  if (accum) {
    for (i = 0; i < ma.length; i++) {
      for (j = 0; j < allmrk.length; j++) {
	if ((ma[i].type == allmrk[j].type) && (ma[i].name == allmrk[j].name)) {
	  last_max = Math.max(last_max, allmrk[j].quantity);
	  maxall = maxall && (last_max == allmrk[j].quantity);
	  maxq = Math.max(maxq, allmrk[j].quantity);
	}
      }
    }
    // NOTE: maxall && maxq==2 means we can clear the set, update display and return
  }

  //
  // clear user choices
  //
  else {
    for (i = 0; i < allmrk.length; i++) {
      allmrk[i].quantity = 0;
    }
  }


  // set the quantities from the passed objects to allmrk (depending on accum mode or not)
  for (i = 0; i < ma.length; i++) {
    for (j = 0; j < allmrk.length; j++) {
      if ((ma[i].type == allmrk[j].type) && (ma[i].name == allmrk[j].name)) {

	// accumulator mode
	if (accum) {
	  if (maxall) {
	    //allmrk[j].quantity += ma[i].quantity;
	    ++allmrk[j].quantity;
	  } else {
	    if (allmrk[j].quantity < maxq) {
	      //allmrk[j].quantity += ma[i].quantity;
	      ++allmrk[j].quantity;
	    }
	  }
	  // clamp
	  if (allmrk[j].quantity < 0) allmrk[j].quantity = 0;
	  if (allmrk[j].quantity > 2) {
	    if (maxall) {	      
	      if (maxq >= 2) {
		allmrk[j].quantity = 0; // more like interacting with a marker in the UI
	      }
	    } else {
	      allmrk[j].quantity = 2;
	    }
	  }

	}//END-if


	// regular mode
	else {
	  allmrk[j].quantity = ma[i].quantity;
	  // clamp
	  if (allmrk[j].quantity < 0) allmrk[j].quantity = 0;
	  if (allmrk[j].quantity > 2) allmrk[j].quantity = 2;
	}

      }

    }//END-for-j
  }//END-for-i


  //--DEBUG--
  /*
  alert("accum:" + (accum ? "on" : "off") +
	" maxq:" + maxq +
	" maxall:" + (maxall ? "true" : "false")
	);
  */

  updateDisplay();
}

/**
 * Sets the colour set to only contain the colours
 * whose type, name and quantity are in the array ma in the form of MMRK objects
 */
function setMarkers(ma)
{
  setMarkers_priv(ma, false);
}

/**
 * Adds the specified markers to the already selected set.
 */
function addMarkers(ma)
{
  setMarkers_priv(ma, true);
}

/**
 * Adds all the CFM markers to the already selected set
 */
function addAllCFM()
{
  if (allmrk.length < 1) return;

  var names_count = 0;
  var marker_count = 0;

  for (i = 0; i < allmrk.length; i++) {
    if (allmrk[i].type == "CFM") {      
      ++names_count;
      marker_count += allmrk[i].quantity;
    }
  }

  if (names_count < 1) return; // ERROR

  //
  // Already has max free selected, do not add more.
  // We do this check to avoid adding twice as many markers
  // as addMarkers() has intelligent for interactive marker selection.
  //
  if (marker_count >= free_cfm_count) return;

  var all_a = new Array(names_count);
  var k = 0;
  for (i = 0; i < allmrk.length; i++) {
    if (allmrk[i].type == "CFM") {      
      all_a[k] = new MMRK("CFM", allmrk[i].name, 1);
      ++k;
    }
  }
   
  addMarkers(all_a);
}

//--------------------------------------------------

/**
 * @param img_src chroma preview image source for the shirt at the nominated browsing width
 * @param img_src chroma preview image source for the zoom layer at the nominated zoom width
 * @param ma array of MMRK objects (each MMRK describes type of marker, name of colour and quantity)
 */
function useChroma(img_src, img_src_zoom, ma)
{
  var d = document.getElementById("the_design_image");
  if (d != null) {
    d.src = img_src;
  }

  d = document.getElementById("the_zoom_design_image");
  if (d != null) {
    d.src = img_src_zoom;
  }

  setMarkers(ma);
}

//--------------------------------------------------

var shirt = { x: 0, y:0 }; // I don't think this is being used
/*
 * Finds the page coords of the given element id and puts them in the given coordinate object
 * which is assumed to have an "x" and a "y" member.
 * eg: var p = { x: 0, y:0 };
 */
function pageCoords(id, coords)
{
  var p = document.getElementById(id);

  if (p == null) return false;

  coords.x = 0;
  coords.y = 0;
  while (p != null) {
    coords.x += p.offsetLeft;
    coords.y += p.offsetTop;
    p = p.offsetParent;
  }

  return true;
}

/**
 * returns true if the element's display style is not set to none
 */
function isVisible(id)
{
  var v = document.getElementById(id);
  if (v == null) return false;
  return (v.style.display != "none");
}

//--------------------------------------------------

/*
 * Gets the selected shirt size
 */
function currentSize(f)
{
  if (f == null) return -1;

  var c = f.elements["cc_size_radio"].length;
  for (var i = 0; i < c; i++) {
    if (f.elements["cc_size_radio"][i].checked) {
      return f.elements["cc_size_radio"][i].value;
    }
  }

  return -1;
}

function clearSize(f)
{
  if (f == null) return;

  var c = f.elements["cc_size_radio"].length;
  for (var i = 0; i < c; i++) {
    f.elements["cc_size_radio"][i].checked = false;
  }
}

function setSize(f, v)
{
  if (f == null) return;
  var c = f.elements["cc_size_radio"].length;
  for (var i = 0; i < c; i++) {
    if (f.elements["cc_size_radio"][i].value == v) {
      f.elements["cc_size_radio"][i].checked = true;
    }
  }
}

//--------------------------------------------------


// not needed
function preloadMeasurementOverlay()
{
  var preload_obj = new Image(270, 288);
  preload_obj.src = "images/garment_sizes.png";
}

/**
 * If you want to toggle the visiblity supply true.
 * If you just want to adjust, eg. on resize, supply false.
 */
function setMeasurementOverlayVisible(b)
{
  var over = document.getElementById("the_measurements_overlay");
  if (over == null) return;

  over.style.display = (b ? "" : "none");

  if (b) {
    var tbl_id = "the_design_table";
    var tbl = document.getElementById(tbl_id);
    if (tbl == null) return;
  
    var p = { x: 0, y:0 };
    if (!pageCoords(tbl_id, p)) return;

    // the overlay is such that if centered width-wise over the image table it registers

    // test IE
    // opera, safari OK
    var width = parseInt(tbl.offsetWidth);
    var off_x = Math.round((width - over.width) / 2.0);
    over.style.left = (p.x + off_x) + "px";  
    over.style.top = p.y + "px";

    /*
    return;
    
    alert("tbl.w:" + width
	  + ", tbl.ow" + tbl.offsetWidth
	  + ", over.w:" + over.width
	  + ", over.sw:" + over.style.width
	  + ", p.x:" + p.x
	  + ", p.y:" + p.y
	  + ", offx:" + off_x
	  );
    */
  }
}

/*
 * for the onresize handler
 */
function adjustMeasurementOverlay()
{
  if (isVisible("the_measurements_overlay")) {
    setMeasurementOverlayVisible(true);
  }
}

/**
 * converts centimeter to inch with 2 decimal point precision
 */
function cmToInch(n)
{
  return Math.round((n * 10.0) / 2.54) / 10.0;
}

function updateMeasurements()
{
  var d = document.getElementById("the_measurements");
  if (d == null) return;

  var f = document.getElementById("cc_form");  
  if (f == null) return;

  //var gid = f.elements["cc_size_select"].value;
  var gid = currentSize(f);

  
  var s = false;
  for (var i = 0; i < gsa.length; i++) {
    if (gid == gsa[i].id) {

      var ntd = "<td style=\"font-weight:bold; padding-right:2ex;\">";

      s = "<table class=\"CCMSRTBL\" border=\"0\" align=\"center\" cellspacing=\"0\">"
	+ "<tr class=\"CCMRK\"><td>&nbsp;</td><td>centimetres</td><td>&nbsp;</td><td>inches</td></tr>"  // LANG
	+ "<tr class=\"CCMRK\">" + ntd + "C</td><td>" + gsa[i].width + "</td><td>&nbsp;</td><td>" + cmToInch(gsa[i].width) + "</td></tr>"
	+ "<tr class=\"CCMRK\">" + ntd + "L</td><td>" + gsa[i].length + "</td><td>&nbsp;</td><td>" + cmToInch(gsa[i].length) + "</td></tr>"
	+ "<tr class=\"CCMRK\">" + ntd + "S</td><td>" + gsa[i].sleeve + "</td><td>&nbsp;</td><td>" + cmToInch(gsa[i].sleeve) + "</td></tr>"
	+ "</table>\n";
      
      break;
    }
  }

  if (s == false) {
    s = "<table class=\"CCMSRTBL\" border=\"0\" align=\"center\" cellspacing=\"0\">"
      + "<tr class=\"CCMRK\" style=\"white-space: nowrap\">choose a shirt size from the menu</td></tr>" // LANG
      + "</table>\n";
  }

  d.innerHTML = s; // test IE
}

function setMeasurementsVisible(b)
{
  var r = document.getElementById("the_measurements_row");
  if (r != null) {
    r.style.display = (b ? "" : "none");
  }

  var a = document.getElementById("the_measurements_link");
  if (a != null) {
    a.innerHTML = b
      ? "hide" // LANG
      : "measurements"; // LANG
  }
}

function toggleMeasurements()
{
  var b = isVisible("the_measurements_row");

  if (!b) {
    updateMeasurements();
  }

  setMeasurementsVisible(!b);
  setMeasurementOverlayVisible(!b);
}

//----------------------------------------------------------------------------------------------------

function setHelpVisible(b)
{
  var r = document.getElementById("the_help_row");
  if (r != null) {
    r.style.display = (b ? "" : "none");
  }

  var a = document.getElementById("the_help_link");
  if (a != null) {
    a.innerHTML = (b
		   ? "hide help" // LANG
		   : "help"); // LANG
  }
}

function toggleHelp()
{
  var b = isVisible("the_help_row");

  setHelpVisible(!b);

  adjustMeasurementOverlay(); // needs to follow shirt
}

//--------------------------------------------------

/* browse designs */
function togglePricingInfo()
{
  var r = document.getElementById("the_pricing_info");
  if (r == null) return;

  var a = document.getElementById("the_pricing_info_link");

  if (r.style.display == "none") {
    r.style.display = "";
    a.innerHTML = "Hide pricing information."; // LANG
  } else {
    r.style.display = "none";
    a.innerHTML = "Show pricing information."; // LANG
  }
}

//--------------------------------------------------

/*
 * Resets shirt choices
 */
function shirtReset()
{
  setZoomVisible(false);
  setMeasurementsVisible(false);
  setMeasurementOverlayVisible(false);
  setHelpVisible(false);

  // reset colours
  var i;
  for (i = 0; i < allmrk.length; i++) { allmrk[i].quantity = 0; } //
  updateDisplay();

  // reset shirt image
  // reset zoom image
  if (design_original_src == null) return;
  var img = document.getElementById("the_design_image");
  if (img != null) img.src = design_original_src;
  img = null;
  img = document.getElementById("the_zoom_design_image");
  if (img != null) img.src = design_original_src_zoom;


  // adjust input items
  var f = document.getElementById("cc_form");
  if (f == null) return;  

  // reset size
  // {PRE: gsa is an array containsing GS instances describing garment sizes available}
  // {PRE: the size select option values are garment size ids}
  //f.elements["cc_size_select"].value = 0;
  clearSize(f);
  /*
   * This code will make the select choose the first size available in gsa
  if ((gsa != undefined) && (gsa.length != undefined)) {
    if (gsa.length > 0) {
      f.elements["cc_size_select"].value = gsa[0].id;
    }
  }
  */
      
  // reset quantity
  f.elements["cc_quantity_select"].value = 1;

  // adjust price
  updateTotal();
}


/*
 * Changes the current shirt choices to the ones in the parameters
 *
 * @param id_garment the size id
 * @param ma array of MMRK objects (each MMRK describes type of marker, name of colour and quantity)
 * @param quantity set the item quantity select to this
 */
function shirtRevert(id_garment, ma, quantity)
{
  setZoomVisible(false);
  setMeasurementsVisible(false);
  setMeasurementOverlayVisible(false);
  setHelpVisible(false);


  // adjust input items
  var f = document.getElementById("cc_form");
  if (f == null) return;  

  // revert size
  // {PRE: gsa is an array containsing GS instances describing garment sizes available}
  // {PRE: the size select option values are garment size ids}
  if ((gsa != undefined) && (gsa.length != undefined)) {
    if (gsa.length > 0) {
      for (var i = 0; i < gsa.length; i++) {
	if (gsa[i].id == id_garment) {
	  //f.elements["cc_size_select"].value = gsa[i].id;
	  setSize(f, gsa[i].id);
	}
      }
    }
  }

  // revert quantity
  if (quantity > 0) {
    f.elements["cc_quantity_select"].value = quantity;
  }

  // set the colours, which also adjusts price
  setMarkers(ma);
}


//--------------------------------------------------

/*
 * Adds shirt of selected size, quantity and markers to the cart.
 * Note: URL length limit of 2000 is safe for all webservers and browsers with many going to many tens of thousands.
 *
 * @param id_design
 * @param id_cartitem non-zero means this was an edit
 * @param cart_script script which lwill process the add parameter
 * @param gv_cat value of GET["cat"] or null
 */
function addShirtToCart(id_design, id_cartitem, cart_script, gv_cat)
{
  // fetching the data
  var f = document.getElementById("cc_form");
  if (f == null) {
    showHelper("An error occured. Please reload the page. If the error persists, please contact us."); //LANG, ERROR
    return;
  }

  // make sure that the 10 base cfms are selected before anything else
  addAllCFM();


  //var f_size = f.elements["cc_size_select"].value;  
  var f_size = currentSize(f);
  if (f_size <= 0) {
    showHelper("Please choose a shirt size."); //LANG
    return;
  }

  var f_quantity = f.elements["cc_quantity_select"].value;  
  var f_cfm = "_LS_CFM_";
  var f_asm = "_LS_ASM_";
  var cfm_count = 0;
  for (var i = 0; i < allmrk.length; i++) {
    for (var j = 0; j < allmrk[i].quantity; j++) {
      if (allmrk[i].type == "CFM") {	
	f_cfm += allmrk[i].name + "_";
	++cfm_count;
      }
      if (allmrk[i].type == "ASM") {
	f_asm += allmrk[i].name + "_";
      }
    }
  }
  f_cfm += "LE";
  f_asm += "LE";

  //{PRE: free_cfm_count has been defined}
  var free_cfm = (typeof(free_cfm_count) != "undefined") ? free_cfm_count : 3;
  if (cfm_count < free_cfm) {
    showHelper("You must select " + free_cfm + " Crayola Fabric Markers to be included at no extra cost."); //LANG, PARAM
    return;
  }


  // constructing the add string, note that I am not urlencoding the ":"
  // cartitemID is supplied as zero as this is a new item
  // cishirt:cartitemID:quantity:designID_sizeID_LS_type_col_col_col_LE
  // cishirt:2:34_M_LS_CFM_red_purple_brown_yellow_LE
  var add_url = cart_script + (gv_cat == null ? "?" : ("?cat=" + gv_cat + "&")) + "add_item=cishirt:" + id_cartitem + ":" + f_quantity + ":" + id_design + "_" + f_size + f_cfm + f_asm;

  // alert(add_url); //DEBUG

  window.location = add_url;
}

//--------------------------------------------------


/**
 * When a a shipping location is selected, we update the total amount to be sent to the check out
 */
function updateCheckoutTotal()
{
  var price = document.getElementById("co_total");
  if (price == null) return false;

  var ppf = document.getElementById("the_checkout_form");
  if (ppf == null) return false;

  //{PRE: cost_cart is defined }
  //{PRE: cost_cart_extax is defined }
  //{PRE: is_ewp is defined }
  //{PRE: zone_cost_a is defined and its contents are in the same semantic order as co_shipping_select }
  //{PRE: zone_name_a is defined and its contents are in the same semantic order as co_shipping_select }
  //{PRE: zone_ewp_a is defined and it contains three instances of the entire encoded cart each initialised with shipping cost items for each zone
  // and its contents are in the same semantic order as co_shipping_select }

  var total = 0.0 + cost_cart;
  var total_extax = 0.0 + total / cost_cart_extax;

  var f = document.getElementById("co_form");
  if (f != null) {
    ship_cost = parseFloat(zone_cost_a[f.elements["co_shipping_select"].value]);
    total = cost_cart + ship_cost;
    total_extax = cost_cart_extax + ship_cost;

    var zi = parseInt(f.elements["co_shipping_select"].value);
    if (is_ewp) {
      if (typeof zone_ewp_a != "undefined") {
	ppf.elements["encrypted"].value = zone_ewp_a[zi];  
      } else {
	return false;
      }
    } else {
      ppf.elements["os0_1"].value = zone_name_a[zi];
      ppf.elements["amount_1"].value = zone_cost_a[zi];
    }
  }


  // test IE
  price.innerHTML =
    "&euro;" // MONEY
    + twoDecimals(total); // MONEY  
    /* no VAT
    + " ("
    + "&euro;" // MONEY
    + twoDecimals(total_extax) // MONEY
    + " "
    + "ex.VAT"
    + ")"
    ;
    */

  return true;
}


/**
 * Posts the checkout form to our payment processor
 */
function postCheckoutForm()
{
  // TO-DO:
  // Make this alert into a helper later
  if (typeof cart_err_a != "undefined") {
    alert("There was an error initialising the checkout: \"" + cart_err_a[0] + "\" Please reload the page or contact us to fix it."); // LANG, PARAM
    return;
  }

  var f = document.getElementById("the_checkout_form");
  if (f == null) return;

  // in case they try to sneak to the checkout without shipping charged
  if (updateCheckoutTotal()) {
    f.submit();
  }
}

/**
 * Postions the star and shirt of the week
 */
function initFPGrid()
{
  var sow = document.getElementByID("fpsow");
  if (sow != null) {
    sow.style.top = "50px";
    sow.style.left = "50px";
  }


  var star = document.getElementByID("fpsowstar");
  if (star != null) {
    star.style.top = "40px";
    star.style.left = "40px";
  }
}

