function popup_init() {
  
  if(document.getElementById("highway-bg")){

    // Background ads are just pixels
    var y = 1;
    bg_spam("highway-bg", y);
    bg_spam("highway-bg", 2);
  }

  
  if(  document.forms[0] ) {
    page_form = document.forms[0];
  }

  //////////////////////////////////////////////////////////////////////////////////
  
  //               Standard interactive element: Option 1 (Part i)
  
  //        In this scenario, the popup content exists in the page for 
  //        non-javascript browsers. The positioning of the popup is less 
  //        sophisticated.
  
  //////////////////////////////////////////////////////////////////////////////////
  if ( document.getElementById('popup-link-alert') && document.getElementById('popup-set-alert') ) {
    init_mouseover_popup('popup-link-alert', 'popup-set-alert');
  }



  //////////////////////////////////////////////////////////////////////////////////////////
  
  //             Standard interactive element: Option 1 (Part ii: help-tip popups)
  
  //     These popups are more sophisticated, demanding coordinates and other parameters.
  //     They have drop shadows as per the .psd we were given.
  
    
  //  These call the following function with these parameters:-
  //  function init_tooltip_popup( link_id, pointer_vert, pointer_horiz, width, x_adjust, y_adjust, tooltip_timeout, mess ) {
  
  //  The  x_adjust, y_adjust parameters allow you to tweak the position of the popup relative
  //  to the mouse.
  
  //  The tooltip_timeout parameter is in milliseconds (but is unfinished, so as long as
  //  the mouse hovers, the tip stays). A value of zero would make it permanent as it is now.
  
  //////////////////////////////////////////////////////////////////////////////////////////

  if ( document.getElementById('tooltip-link-1') ) {
    init_tooltip_popup('tooltip-link-1', 'top', 'right', 100, 0, 0, 0, '<p>Nam liber tem por cum soco ngue</p>' );
  }
  if ( document.getElementById('tooltip-link-2') ) {
    init_tooltip_popup('tooltip-link-2', 'top', 'left', 100, 0, 0, 0, '<p>nihil imperdiet domipsum dolor</p>' );
  }
  if ( document.getElementById('tooltip-link-3') ) {
    init_tooltip_popup('tooltip-link-3', 'bottom', 'left', 140, 0, 0, 0, '<p>tooltip-link-3</p>' );
  }
  if ( document.getElementById('tooltip-link-4') ) {
    init_tooltip_popup('tooltip-link-4', 'bottom', 'right', 180, 0, 0, 0, '<p>tooltip-link-4</p>' );
  }

  var n_checklist = 1;
  while( document.getElementById('checklist-item-'+ n_checklist +'-a-tag') ) {
    init_tooltip_popup('checklist-item-'+ n_checklist +'-a-tag', 'top', 'right', 105, 0, 0, 1000, '<p>Expand this step</p>' );
    init_tooltip_popup('checklist-checkbox-'+ n_checklist , 'top', 'right', 145, 0, 0, 1000, '<p>Check this box once you\'ve completed this step</p>' );
    n_checklist++;
  }

  if( document.getElementById('download-checklist') && document.getElementById('download-checklist-menu') ) {
    init_tooltip_popup( 'download-checklist', 'top', 'right', 145, 0, 0, 1000, '<p>Download and save this checklist to your computer</p>' );
    init_download_checklist_dropdown_menu('download-checklist', 'download-checklist-menu');
  }

  if( document.getElementById('my-checklists-delete') ) {
    init_tooltip_popup('my-checklists-delete', 'top', 'right', 145, 0, 0, 1000, '<p>Clear your work and delete your checklist</p>');
  }

  if( document.getElementById('my-profile-alert-3-edit') ) {
//    The next line should work but Firefox turns tags into impotent character code values and makes me cry.
//    var my_profile_alert_3_mess = document.getElementById('my-profile-alert-3-noscript').innerHTML + ' | <a href="javascript://">close</a>';
    var my_profile_alert_3_mess = '<p>Alert me when this word is mentioned in the New Zealand Herald business news feed.<br>\
      <input type="text" name="alert-3" value="dairy"><br>\
      <a href="javascript://">Save</a> | <a href="javascript://">close</a></p>';

    init_tooltip_popup('my-profile-alert-3-edit', 'bottom', 'right', 167, 0, 0, 1000, my_profile_alert_3_mess);
  }

  ///////////////////////////////////////////////
  //  The following "help tips" use a different
  // set of functions. They could simply be 
  // Tooltips.
  var number_of_help_tips = 3;
  init_help_tips(number_of_help_tips);

  /////////////////////////////////////////////////////////////////////////

  //             Standard interactive element: Option 2: Folding 

  if ( document.getElementById('text-folder-1') && document.getElementById('folded-text-1') ) {
    init_fold_text('text-folder-1', 'folded-text-1');
  }

  if ( document.getElementById('interactive-folder-1') && document.getElementById('interactive-fold-content-1') ) {
    init_fold_text('interactive-folder-1', 'interactive-fold-content-1');
  }

  //////////////////////////////

  //  characters typed

  var max_char_array = new Array;
  max_char_array[0] = new Array('dummy','dummy',0);
    
  max_char_array[1] = new Array( 'chars-typed-box-1', 'chars-typed-info-1', 100 );
  if ( document.getElementById( max_char_array[1][0]) && document.getElementById(max_char_array[1][1]) ) {
    init_characters_typed( max_char_array[1][0], max_char_array[1][1], max_char_array[1][2] );
  }



  
  ////////////////////////////////////////////
  
  //              Checklists
  
  ////////////////////////////////////////////
  
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  //  Here is the naming convention for multiple expandable blocks,
  //  Otherwise the javascript won't work.
  //  These all have to be an id.
  
  
  //    1) There is a main name, in this case "checklist"
  //       This is unlikely to be used by itself, but as part of an id name.
  
  
  //    2) sub block
  //       =========
  //       Each sub-block containing an expandable section has a name according to the following convention:-
  //       mainId + hyphen + "item" + hyphen + subBlockNumber
  
  //       e.g.: checklist-item-1
  
  //       - Each subBlockNumber must be 1 + the previous.
  //       - The first sub-block with number 0 is special as it has an "Expand All" link
  //       - ( so if you don't want an "Expand All" link, start numbering at 1 ) 
  
  
  //    3) link to trigger expand/collapse behaviour
  //       =========================================
  //       Each sub-block has a link which expands its content.
  //       This is likely to be in an HTML <a href= tag, so the naming convention for this link is thus:-
  //       mainId + hyphen + "item" + hyphen + subBlockNumber + "-a-tag"
  
  //       e.g.:  checklist-item-3-a-tag
  
  
  //    4) Expandable content
  //       ==================
  //       The id for the expandable/collapsable section itself:-
  //       mainId + '-contracted_section-' + subBlockNumber
  
  //       e.g.: checklist-contracted-section-2
  
  
  //    5) The checkbox you click on
  //       =========================
  //       e.g.:  checklist-checkbox-1
  
  
  //    6) These checkboxes have label tags that need to be altered
  //       ========================================================
  //       e.g.:  checklist-checkbox-label-1
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  if (document.getElementById('checklist' + '-item-0')) {
    init_multiple_block_expand('checklist', 0);
  }



  max_char_array[2] = new Array( 'chars-typed-box-2', 'chars-typed-info-2', 1000 );  
  if ( document.getElementById(max_char_array[2][0]) && document.getElementById(max_char_array[2][1]) ) {
    init_characters_typed( max_char_array[2][0], max_char_array[2][1], max_char_array[2][2] );
  }


  
  ////////////////////////////////////////////
  
  //          Greyout with popup
  
  ////////////////////////////////////////////
  //  These are mainly in checklist page. See
  // HTML just above body tag.
  
  // You call a function thus:- 
  // function init_greyout( link_id, target_id [, greyout_message]) {
  
  // The greyout_message is optional and adds a message
  // to the link not the actual message that pops up,
  // which is hard-coded in HTML.
  
  // The javascript looks in the HTML for a close link
  // like the target_id but with the added suffix "-close"
  // e.g.:-
  // id="greyout-popup-1
  // id="greyout-popup-1-close

  if ( document.getElementById('greyout-1') && document.getElementById('greyout-popup-1') ) {
    init_greyout('greyout-1', 'greyout-popup-1', '<b>Grey out the page and pop up a message</b>');
  }

  if ( document.getElementById('save-checklist') && document.getElementById('greyout-popup-1') ) {
    init_greyout( 'save-checklist', 'greyout-popup-1' );
  }

  if ( document.getElementById('whats-a-checklist-link') && document.getElementById('greyout-popup-2') ) {
    init_greyout( 'whats-a-checklist-link', 'greyout-popup-2' );
  }

    
  if(document.getElementById('progress-meter')) {
    //
    // function init_progress_meter(init_percent, meter_width, x_offset, y_offset, text_x_offset, text_y_offset)
    //
    // these offsets position the needle on the progress meter 
    // on the checklist pages.
    //
    progress_meter_init_percent = 0;
    progress_meter_meter_width = 387;
    progress_meter_x_offset = -5;
    progress_meter_y_offset = -6;
    progress_meter_text_x_offset = -10;
    progress_meter_text_y_offset = -22;
    init_progress_meter(progress_meter_init_percent);//, progress_meter_meter_width, progress_meter_x_offset, progress_meter_y_offset, progress_meter_text_x_offset, progress_meter_text_y_offset);
  }

  //////////////////////////////////////
  //      Bubbling-up/Shuffling/ 
  //   rearranging order of elements
  //////////////////////////////////////

  if(document.getElementById('my-tools')) {
    init_shuffling('my-tools');
  }
}


































function findPos(obj) {
  var curtop = 0;
  if (obj.offsetParent) {
    curtop = obj.offsetTop
    while (obj.offsetParent) {
      obj = obj.offsetParent;
      curtop += obj.offsetTop;
    }
  }
  return curtop;
}

function init_help_tips(num) {
  var element;
  var help_img;
  var help_tip_wrapper;
  for(var m=1; m<= num; m++) {
    element = document.getElementById('help_tip_'+m);
    if (element) {
      help_tip_wrapper = document.getElementById('help_tip_wrapper_'+m);
      help_tip_wrapper.innerHTML = '<a href="javascript://" class="help-tip" id="help_'+m+'"><img src="/img/help-q.gif" width="12" height="14" alt="?help"></a> ';
      help_img = document.getElementById('help_'+m);
      element.style.border = "#979797 1px solid";
      element.style.background = "#ffffff url(/img/corner-grey.gif) top left no-repeat";
      element.style.padding= "16px 12px";
      element.style.display= "block";
      element.style.position = "absolute";
      element.style.top = "45px";
      element.style.left = "-5000px";
      element.style.zIndex = 100;
      element.onclick  = make_help_tip_handler(m);
      help_img.onclick = make_help_tip_handler(m);
    }
  }
}

function make_help_tip_handler(m) {
  return function() { show_hide_help_tip(m) };
}

function show_hide_help_tip(n) {
  var tip = document.getElementById('help_tip_'+n);
  if (!tip) return false;
  if (tip.style.left == "12px") {
    tip.style.left = "-5000px";
  } else {
    tip.style.left = "12px";
  }
  return false;
}

// Special dropdown menu on Checklist page
function init_download_checklist_dropdown_menu(link_id , menu_id ) {
  var download_checklist_menu = document.getElementById(menu_id);
  download_checklist_menu.style.zIndex = 999;
  download_checklist_menu.style.marginLeft = '';
  download_checklist_menu.style.background =  'white';
  download_checklist_menu.style.width = '139px';
  download_checklist_menu.style.position =  'absolute';
  download_checklist_menu.style.right = '0px';
  download_checklist_menu.style.top = '0px';
  download_checklist_menu.style.display = 'none';
  document.getElementById(link_id).onclick = toggle_download_checklist_dropdown_menu;
}

function toggle_download_checklist_dropdown_menu() {
  if(document.getElementById('download-checklist-menu').style.display=='block') {
    document.getElementById('download-checklist-menu').style.display='none';
  } else {
    document.getElementById('download-checklist-menu').style.display='block';
  }
}

//////////////////////////////////////////////////////////////////////////////////

//               Standard interactive element: Option 1 (Part i)

//        In this scenario, the popup content exists in the page for 
//        non-javascript browsers. The positioning of the popup is less 
//        sophisticated.

//////////////////////////////////////////////////////////////////////////////////

function init_mouseover_popup(link_id, popup_id) {
    var target = document.getElementById(popup_id);
    // set initial hide
    target.style.position = "absolute";
    target.style.left = "-5000px";

    // apply CSS class
    target.className = "popup-interactive";

    // add Close link
//    var blockcontent = target.innerHTML;
//    var popblockcontent = blockcontent + "<p><a href=\"javascript://\" onclick=\"javascript:unpop_message(popup_id);return false;\">Close</a></p>";
//    target.innerHTML = popblockcontent;
      
    var linktarget = document.getElementById(link_id);

    // add popup link
    var linktargetcontent = linktarget.innerHTML;
    var poptargetcontent = '<strong><a href="javascript://" id="'+ link_id +'-a-tag">Set an alert</a></strong> | ' + linktargetcontent;

    //element.onclick  = make_help_tip_handler(m);
    linktarget.innerHTML = poptargetcontent;

    var link_a_tag = document.getElementById(link_id +'-a-tag');
    ///////////////////////////////////////////
    // the following steve's message functions
    // are for debugging in Safari.
//     link_a_tag.onmouseover = steves_evil_wrapper('a-mouseover', make_popup_handler(popup_id));
//    link_a_tag.onmouseout = steves_evil_wrapper('a-mouseout', make_mouseout_handler(popup_id));

//     link_a_tag.onmouseover = steves_evil_wrapper('mouseover',  safari_mouseover(popup_id));
//    link_a_tag.onmouseout  = steves_evil_wrapper('mouseout',  safari_mouseout(popup_id));

//     target.onmouseover = steves_evil_wrapper('mouseover', mouseover_target(popup_id));
//    target.onmouseout = steves_evil_wrapper('mouseout', make_mouseout_handler(popup_id));

     link_a_tag.onmouseover = safari_mouseover(popup_id);
    link_a_tag.onmouseout  = safari_mouseout(popup_id);

     target.onmouseover = mouseover_target(popup_id);
    target.onmouseout = make_mouseout_handler(popup_id);
}

/////////////////////////////////////////////////////////////
//  The Safari browser is a pain in the arse. If you
//  rollover a link, you get a mouseout event followed by a
//  mouseover event for every pixel the mouse moves. This
//  could drive you batty.
//  Therefore, for every mouseout event, if a mouseover
//  event doesn't trigger within a short space of time, only
//  then can it be considered a genuine mouseout event.
/////////////////////////////////////////////////////////////
////////////////////////////////////////////
// the following steve's message functions
// are for debugging in Safari.
////////////////////////////////////////////
function steves_evil_wrapper(event, handler) {
  return function(ev) {
    var coords = new Array;
    coords = get_popup_coordinates(ev);
    steves_message(event + '(' + coords[0] + ',' + coords[1] + ')');
    return handler();
  }
}

function steves_message(message) {
  var message_box = document.getElementById('steves-message-thing');
  message_box.innerHTML += message + ' ...  ';
}

var safari_timer = new Object;

function safari_mouseover(popup_id) {
  return function() {
    if (safari_timer[popup_id]) {
      clearTimeout(safari_timer[popup_id]);
//      steves_message('clearTimeout('+safari_timer[popup_id]+')');
      safari_timer[popup_id] = undefined;
    }
    else {
      popup_message(popup_id);
//      steves_message('popup_message('+popup_id+')');
    }
  }
}

function safari_mouseout(popup_id) {
  var mouseout = make_mouseout_handler(popup_id);
  var safari_mouseout_timeout = function() {
//    steves_message('mouseout');
    safari_timer[popup_id] = undefined;
    mouseout();
  }
  return function() {
    safari_timer[popup_id] = setTimeout(safari_mouseout_timeout, 30);
//    steves_message('setTimeout()');
  }
}

var mouseout_timer = new Object;

function make_mouseout_handler(n) {
  return function() {
    if(mouseout_timer[n]) {
      clearTimeout( mouseout_timer[n] );
      mouseout_timer[n] = undefined;
    }
//    steves_message(n);
    mouseout_timer[n] = setTimeout(make_unpop_handler(n), 500);
  };
}

function mouseover_target(p) {
//  alert(p);
  return function() { clearTimeout( mouseout_timer[p] ); };
}

/*
function make_popup_handler(m) {
  return function() { popup_message(m); };
}
*/

function make_unpop_handler(m) {
  return function() { unpop_message(m); };
}

function popup_message(idname){
  document.getElementById(idname).style.left = "auto";
}

function unpop_message(idname){
  document.getElementById(idname).style.left = "-5000px";
}

/////////////////////////////////////////////////////////////////////////////////////////////

//             Standard interactive element: Option 1 (Part ii: help-tip popups)

//     These popups are more sophisticated, demanding coordinates and other parameters.
//     They have drop shadows as per the .psd we were given.

/////////////////////////////////////////////////////////////////////////////////////////////

function init_tooltip_popup( link_id, pointer_vert, pointer_horiz, width, x_adjust, y_adjust, tooltip_timeout, mess ) {
  var link_tag = document.getElementById(link_id);
  var tooltip_parent = document.getElementsByTagName('BODY')[0];//Maybe page_form
  
  var new_div = document.createElement("div");
  var targ_id = "tooltip-"+link_id;
  new_div.setAttribute("id", "tooltip-"+link_id);
  new_div.setAttribute("class", "tooltip" );
  new_div.setAttribute("className", "tooltip" );

  var new_div_inner = document.createElement("div");
  new_div_inner.setAttribute("id", "tooltip-"+link_id+"-inner");
  new_div_inner.setAttribute("class", "tooltip-inner");
  new_div_inner.setAttribute("className", "tooltip-inner");

  new_div.appendChild(new_div_inner);

  tooltip_parent.appendChild( new_div, link_tag );

  var target = document.getElementById(targ_id);
  target.style.position = "absolute";
  target.style.display = 'none';

  var target_inner = document.getElementById(targ_id + '-inner');
  target_inner.style.display = 'none';
  target_inner.innerHTML = mess;
  
  ///////////////////////////////////////////
  // the following steve's message functions
  // are for debugging in Safari.
  //  link_tag.onmouseover =  steves_evil_wrapper('mouseover', make_popup_tooltip_safari(targ_id, pointer_vert, pointer_horiz, width, mess));
  //  link_tag.onmouseout = steves_evil_wrapper('mouseout',  safari_mouseout_tooltip(targ_id));
  ///////////////////////////////////////////

  link_tag.onmouseover =  make_popup_tooltip_safari("tooltip-"+link_id, pointer_vert, pointer_horiz, width, x_adjust, y_adjust, tooltip_timeout, mess);
  link_tag.onmouseout = safari_mouseout_tooltip("tooltip-"+link_id);

}

function make_popup_tooltip_safari(targ_id, pointer_vert, pointer_horiz, width, x_adjust, y_adjust, tooltip_timeout, mess) {
//  return function(ev) { popup_tooltip(ev, targ_id, pointer_vert, pointer_horiz, width, mess ); };
//}
//function safari_mouseover(popup_id) {
  return function(ev) {
    if (safari_timer[targ_id]) {
      clearTimeout(safari_timer[targ_id]);
//      steves_message('clearTimeout('+safari_timer[targ_id]+')');
      safari_timer[targ_id] = undefined;
    }
    else {
      popup_tooltip(ev, targ_id, pointer_vert, pointer_horiz, width, x_adjust, y_adjust, tooltip_timeout, mess );
//      steves_message('popup_tooltip');
    }
  }
}

function safari_mouseout_tooltip(popup_id) {
  var mouseout = make_mouseout_handler_tooltip(popup_id);
  var safari_mouseout_timeout = function() {
//    steves_message('mouseout');
    safari_timer[popup_id] = undefined;
    mouseout();
  }

  return function() {
    safari_timer[popup_id] = setTimeout(safari_mouseout_timeout, 30);
//    steves_message('setTimeout()');
  }
}

//var mouseout_timer = new Object;
function make_mouseout_handler_tooltip(n) {
  return function() {
    if(mouseout_timer[n]) {
      clearTimeout( mouseout_timer[n] );
      mouseout_timer[n] = undefined;
    }
//    steves_message(n);
    mouseout_timer[n] = setTimeout(make_unpop_handler_tooltip(n), 500);
  };
}

function make_unpop_handler_tooltip(m) {
  return function() { unpop_message_tooltip(m); };
}

//function mouseover_target(p) {
//  alert(p);
//  return function() { clearTimeout( mouseout_timer[p] ); };
//}

function unpop_message_tooltip(idname){
  document.getElementById(idname).style.display = "none";
  document.getElementById(idname + '-inner').style.display="none";
}

function popup_tooltip( ev, targ_id, pointer_vert, pointer_horiz, width, x_adjust, y_adjust, tooltip_timeout, mess ) {
  //////////////////////////

  // First get coordinates

  //////////////////////////
  var coords = new Array;
  coords = get_popup_coordinates(ev);
  var posX = coords[0];
  var posY = coords [1];
  

  ////////////////////////////////////
  
  // find height of element if you can
  
  ////////////////////////////////////
  var padding = 8;  
  if ( pointer_horiz == 'right' ) {
    posX -= width + 2*padding + 10;
  }
  else {
    posX += 10;
  }
  if ( pointer_vert == 'bottom' ) {
    posY -= 2*padding + mess.length/3  + 10;
  }
  else {
    posY += 10;
  }

  posX += x_adjust;
  posY += y_adjust;

//alert('posX : ' + posX+ '\nposY : ' + posY);
  var target = document.getElementById(targ_id);
  target.style.left = posX + "px";
  target.style.top = posY + "px";
  target.style.display= "block";
  target.style.width= width + 'px';

  var target_inner = document.getElementById(targ_id + '-inner');

  target_inner.style.display="block";
  var width_inner = width - 1;
  target_inner.style.width= width_inner + 'px';
//alert(target_inner.id +" , " + "#ffffff url(/img/corner-grey-" + pointer_vert + "-" + pointer_horiz + ".gif) " + pointer_vert + " " + pointer_horiz + " no-repeat");
  target_inner.style.background = "#ffffff url(/img/corner-grey-" + pointer_vert + "-" + pointer_horiz + ".gif) " + pointer_vert + " " + pointer_horiz + " no-repeat";

  target.onmouseover = mouseover_target(targ_id);
  target.onmouseout = make_mouseout_handler_tooltip(targ_id);
}

function get_popup_coordinates(ev) {
  var coords = new Array;
  var x = 50;
  var y = 50;
  var event_obj;
  var element_obj;

  if ( ev != null ) {
    event_obj = ev;
  } else  {
    event_obj = window.event;
  }
  
  if (event_obj.pageX || event_obj.pageY)   {
    x = event_obj.pageX;
    y = event_obj.pageY;
  }
  else if (event_obj.clientX || event_obj.clientY)   {
    x = event_obj.clientX + document.body.scrollLeft
      + document.documentElement.scrollLeft;
    y = event_obj.clientY + document.body.scrollTop
      + document.documentElement.scrollTop;
  }
  coords = Array(x,y);
  return coords;
}

//////////////////////////////////////////////////////////////////////////////////////////////////

//                       Standard interactive element: Option 2

//////////////////////////////////////////////////////////////////////////////////////////////////

function init_fold_text(text_folder, folded_text) {

  var element = document.getElementById(folded_text);
  element.innerHTML += '<p class="close"><a href="javascript://" onclick="toggle_fold(\'' + folded_text + '\')">close</a></p>';
  element.style.display = 'none';

  var folder = document.getElementById(text_folder);
  folder.onclick = make_fold_handler(folded_text);
}

function make_fold_handler(m) {
  return function() { toggle_fold(m) };
}

function toggle_fold(text_to_fold) {
  var element = document.getElementById(text_to_fold);
  if (element.style.display == 'none' ) {
    element.style.display = 'block';
  }
  else {
    element.style.display = 'none';
  }
}

////////////////////////////////////////////

//           Characters typed

////////////////////////////////////////////

function init_characters_typed(chars_typed_box, chars_typed_info, max_num) {
  var box = document.getElementById(chars_typed_box);
  var info = document.getElementById(chars_typed_info);
  update_characters_typed(box, info, max_num );
  box.onchange = make_chars_typed_handler(box, info, max_num);
  box.onkeypress = make_chars_typed_onkeypress_handler(box, info, max_num);
  box.onkeyup = make_chars_typed_handler(box, info, max_num);
}


function make_chars_typed_handler(m,n,o) {
  return function() {
    update_characters_typed(m,n,o);  
  };
}

function make_chars_typed_onkeypress_handler(m,n,max_num) {
  return function() {
    update_characters_typed(m,n,max_num);  
    var num_chars = m.value.length;
    if(num_chars > max_num) {
      alert('Please type no more than ' + max_num + ' characters.');
    }
  };
}


function update_characters_typed(box, info, max_num) {

  var num_chars = box.value.length;

  if(num_chars == 1) { var characters = " character"; }
  else { var characters = " characters"; }

  info.innerHTML = num_chars + characters; 
}


////////////////////////////////////////////

//              Checklists

////////////////////////////////////////////

function init_multiple_block_expand(b,start_num) {
  var base_block_name = b + '-item';
  var block;
  var a_tag;
  var contracted_section;
  var checkbox;
  var checkbox_label;
  var n = start_num;
  if ( start_num == 0 ) {
    // add handler for expand all link
    init_expand_all(b);
    n += 1;
  }
  while (document.getElementById(base_block_name + "-" + n)) {
    block = base_block_name + "-" + n;
    a_tag = block + '-a-tag';
    contracted_section = b + '-contracted-section-' + n;
    init_fold_text (a_tag,contracted_section);
    checkbox = b + '-checkbox-' + n;
    checkbox_label = b + '-checkbox-label-' + n;
    // Dynamic checkboxes
    // init_dynamic_checkbox(checkbox, checkbox_label);
    if (document.getElementById(checkbox)) {
       click_checklist_checkbox(checkbox, contracted_section, checkbox_label, a_tag);
      document.getElementById(checkbox).onclick = make_checkbox_handler(b, checkbox, contracted_section, checkbox_label, a_tag);
    }

    n++;
  }
  check_checkbox_completion(b);
}

function init_expand_all(b) {
  var base_block_name = b + '-item';
  var block;
  var expand_all_id = b +'-item-0';
  var expand_all_a_tag = expand_all_id +'-a-tag';
  var contracted_sections = new Array;
  
  if (document.getElementById(expand_all_a_tag)){
    var n = 0;

    while (document.getElementById(base_block_name + "-" + n)) {
      block = base_block_name + "-" + n;
      contracted_sections[n] = b + '-contracted-section-' + n;
      n += 1;
    }
  }
  document.getElementById(expand_all_a_tag).onclick = make_expand_all_handler(expand_all_a_tag, contracted_sections);
}

function make_expand_all_handler(m,n) {
  return function() { toggle_expand_all(m,n) };
}

function toggle_expand_all(expand_all_a_tag, sections_to_fold) {
  var element;
  if (document.getElementById(expand_all_a_tag).innerHTML == checklist_expand_all_text[0]) {
    document.getElementById(expand_all_a_tag).innerHTML = checklist_expand_all_text[1]
    for ( var i=0; i < sections_to_fold.length; i++ ) {
      if(document.getElementById(sections_to_fold[i])) {
        element = document.getElementById(sections_to_fold[i]);
        element.style.display = 'block';
      }
    }
  } else {
    document.getElementById(expand_all_a_tag).innerHTML = checklist_expand_all_text[0]
    for ( var i=0; i < sections_to_fold.length; i++ ) {
      if(document.getElementById(sections_to_fold[i])) {
        element = document.getElementById(sections_to_fold[i]);
        element.style.display = 'none';
      }
    }
  }
}

function make_checkbox_handler(b, checkbox, contracted_section, checkbox_label, a_tag) {
  return function () { 
    click_checklist_checkbox(checkbox, contracted_section, checkbox_label, a_tag);
    check_checkbox_completion(b);
  };
}

function click_checklist_checkbox(checkbox, contracted_section, checkbox_label, a_tag) {
  var checkbox_label_text = 'Completed&nbsp;';
  // if checkbox is now checked
  if (document.getElementById(checkbox).checked) {
    // Firstly hide the block
    var element = document.getElementById(contracted_section);
        element.style.display = 'none';
    // also add the checkbox_label_text
    if (document.getElementById(checkbox_label)) {
      document.getElementById(checkbox_label).innerHTML = checkbox_label_text;
    }
    // also change heading colour a_tag
    if (document.getElementById(a_tag)) {
      document.getElementById(a_tag).style.color = '#b2dbf0';
    }
  } else {
    element = document.getElementById(contracted_section);
    // also add the checkbox_label_text
    if (document.getElementById(checkbox_label)) {
      document.getElementById(checkbox_label).innerHTML = '';
    }
    // also change heading colour a_tag
    if (document.getElementById(a_tag)) {
      document.getElementById(a_tag).style.color = '#707176';
    }
  }
}

function check_checkbox_completion(b) {
  var checkboxes = 0;
  var num_checked = 0;
  for ( var i=0; i<page_form.length; i++ ) {
    var name = page_form.elements[i].name;
    var value = page_form.elements[i].value;
    if( page_form.elements[i].type && page_form.elements[i].type == 'checkbox' && page_form.elements[i].id.indexOf(b)>-1 ) {
      checkboxes++;
      if (page_form.elements[i].checked) {
        num_checked++;
      }
    }
  }
  var percentage = num_checked / checkboxes * 100;
  if( document.getElementById('progress-meter') ) {
    move_progress_meter( percentage );
  }
  if( document.getElementById('my_checklists_progress_text') ) {
//    change_my_checklists_progress_text( percentage );
    document.getElementById('my_checklists_progress_text').innerHTML = percentage;
  }
}

////////////////////////////////////////////

//          Greyout with popup

////////////////////////////////////////////

//  Naming Convention

//  id="greyout-popup-1
//  id="greyout-popup-1-close

function init_greyout(greyout, greyout_popup, greyout_message) {
  var close_link = greyout_popup + '-close';
  if (greyout_message) {
    document.getElementById(greyout).innerHTML = '<a href="javascript://" class="greyout-link">' + greyout_message + '</a>';
  }
  document.getElementById(greyout_popup).style.display = 'none';
  document.getElementById(greyout).onclick = make_greyout_handler(greyout_popup);
  if (document.getElementById(close_link)) {
    document.getElementById(close_link).onclick = make_greyout_handler(greyout_popup);
  }
}

function make_greyout_handler(m) {
  return function() { toggle_greyout(m) };
}

function toggle_greyout(greyout_popup) {
  var element = document.getElementById(greyout_popup);
  if (element.style.display == 'none') {
    element.style.display = 'block';
  } else {
    element.style.display = 'none';
  }
}

//////////////////////////////////////

//    Progress Meter

//////////////////////////////////////

function init_progress_meter(init_percent){ //, meter_width, x_offset, y_offset, text_x_offset, text_y_offset) {
  var init_val = parseInt( progress_meter_meter_width * (init_percent / 100) );
  var needle = document.getElementById('progress-meter-needle');
  var needle_left = init_val + progress_meter_x_offset;
  needle.style.left = needle_left + 'px';
  needle.style.top = progress_meter_y_offset + 'px';
  var completed_bg = document.getElementById('progress-meter-completed');
  completed_bg.style.width = init_val+'px';
  var text = document.getElementById('progress-meter-needle-text');
  var text_num = document.getElementById('progress-meter-needle-text-num');
  var text_left = init_val + progress_meter_text_x_offset;
  text.style.left = text_left + 'px';
  text.style.top = progress_meter_text_y_offset + 'px';
  text_num.innerHTML = init_percent;
}

function move_progress_meter(init_percent){ //, meter_width, x_offset, y_offset, text_x_offset, text_y_offset) {
  var value = parseInt( progress_meter_meter_width * (init_percent / 100) );
  var needle = document.getElementById('progress-meter-needle');
  var needle_left = value + progress_meter_x_offset;
  needle.style.left = needle_left + 'px';
  needle.style.top = progress_meter_y_offset + 'px';
  var completed_bg = document.getElementById('progress-meter-completed');
  completed_bg.style.width = value+'px';
  var text = document.getElementById('progress-meter-needle-text');
  var text_num = document.getElementById('progress-meter-needle-text-num');
  var text_left = value + progress_meter_text_x_offset;
  text.style.left = text_left + 'px';
  text.style.top = progress_meter_text_y_offset + 'px';
  text_num.innerHTML = init_percent;
}

//////////////////////////////////////

//      Bubbling-up/Shuffling/ 
//   rearranging order of elements

//////////////////////////////////////

function init_shuffling(container_div) {
  var container_element = document.getElementById(container_div);
  var li = container_element.getElementsByTagName('li');
  var real_li = new Object;
  var j = 0;
  for(var i = 0; li[i]; i++ ) {
    if ( li[i].id.indexOf('links-') >= 0) {
      real_li[j] = li[i];
      if( document.getElementById(real_li[j].id + '-hide')) {
        document.getElementById(real_li[j].id + '-hide').style.display = 'none';
      }
      if(document.getElementById(real_li[j].id + '-bubble-link')) {
        document.getElementById(real_li[j].id + '-bubble-link').onclick = shuffle_li;
      }
      real_li[j].setAttribute('class', '');
      real_li[j].setAttribute('className', '');
      j++;
    }
  }
}

function shuffle_li() {
  var parent = this.parentNode;
  var li_array = parent.parentNode.getElementsByTagName('li');
  var hide;
  if (document.getElementById(li_array[0].id + '-hide')) {
    document.getElementById(li_array[0].id + '-hide').style.display = 'none';
    document.getElementById(li_array[0].id).className = '';
  }
//  this.style.className = ;  
  parent.parentNode.insertBefore( parent, li_array[0] );
  if (document.getElementById(parent.id + '-hide')) {
    document.getElementById(parent.id + '-hide').style.display = 'block';
    document.getElementById(parent.id).className = 'active';
  }
}