//// Utilities to help handle updates from server.
////
//// For inclusion by updates pages

// Compatibility function - substitutes the unescape
// function for decodeURIComponent if that is not
// defined by the browser.
//
if (!window.decodeURIComponent) {
  decodeURIComponent = unescape;
}

// Refers to the "main window" this update applies to.
// Not set until iw__isUpdate confirms that this is an update
// and thereby that the parent is initialized.
//
var iw_main;

// Will be the query string for this page.
var iw_search;

// Query string inputs to this page.
// Simple set of name/value bindings.
//
var iw_inputs;

// Defaults for iw_inputs when nothing supplied.
// Loaded from element with ID "iw_data".
var iw_data;


// Set the body onload handler of "update pages" to this.  It checks
// whether the page is loaded as part of an update if so, updates the
// main window calling iw_main.update, runs the child's update
// function if it has one, and saves parent state if the browser's
// support for onunload needs help.
//
function iw_loadUpdate() {
  if (iw__isUpdate()) {
    iw_main.iw_toolState.currentRequest = null;

    iw_search = iw_main.useXMLHttpRequest
      ? iw_main.iw_updateQuery
      : location.search;
    // Mainly good for demos:
    iw_inputs = iw_main.iw_parseQuery(iw_search);
    // BEGIN: dev
    if (iw_main.iw_devMode) {
      var vars = iw_main.iw_element("iw_data");
      iw_data = vars ? iw_main.iw_node2Object(vars) : new iw_main.IW_Hash;

      // Perform text substitutions
      var update = iw_main.iw_findAction("Update");
      if (iw_main.iw_devMode && !iw_main.isOpera) {
        update.innerHTML = iw_main.iw_replaceAll
	  (update.innerHTML, /\$([a-zA-Z_]\w*)( ?\$)?/,
	   function(match, name) {
            var newer = iw_inputs[name];
            if (newer==null) {
              newer = iw_data[name];
            }
            newer = newer || "";
            // This fixup for IE won't correctly set the contents of a
            // TEXTAREA.  We may someday need special variable names
            // to request this special substitution.
            newer = newer.replace(/\r?\n/g, "<br>");
            return newer;
          });
      }
    }
    // END: dev
    
    iw_main.iw_doUpdate();
    if (window.update)
      window.update();
    if (iw_main.saveAtIntervals) {
      iw_main.saveState();
    }
  }
}


// Call from a child onload handler to distinguish loading
// of an update versus a main page load/reload.
//
function iw__isUpdate() {
  // If the window is loading as part of a page load or reload
  // the current (child) window onload runs first, before the
  // parent.  Only on actual updates is the parent already
  // loaded in the child onload handler.
  if (parent.iw_loaded) {
    iw_main = parent.iw_mainFrame;
    iw_inputs = new iw_main.IW_Hash;
    return iw_main.iw_getCurrentRequest();
  } else {
    return false;
  }
}


// Registers this window's library.  This may be an indirect
// descendant of the main window,  Every library should call
// this, for example in its onload handler.
// FIXME: Appears to be obsolete! -cp
// 
function iw_setupLibrary() {
  for (var w=window; w!=top&&!w.iw_registerLibrary; w=w.parent) {}
  if (w.iw_registerLibrary) {
    w.iw_registerLibrary(document.getElementById("library"));
    // w.iw_expandAll(document.body);
  }
}


// Capture the query string for this update page into iw_inputs.
// Mainly good for demos.
//
function iw_captureQuery() {
  if (!iw_inputs)
    iw_inputs = iw_main.parseQuery(iw_search);
}


// Simple description for the state of a simple form.  The form must
// be given as a DOM element, and it may be a pseudo-form, but must
// have an ID or NAME.  Can handle radio buttons, but not
// multiple-selection items.
//
// Return value is a hash from element name to string value.
function iw_formInfo(formName) {
  var result = new Object();
  iw_main.setupFormsAccess();
  var fields = iw_main.allFields[formName];
  for (var i=0; i<fields.length; i++) {
    var field = fields[i];
    var name = field.name || field.id;
    var v = iw_main.iw_eltv(field);
    if (v) {
      result[name] = v;
    }
  }
  return result;
}

// Field that has a non-empty value will match this.
var iw_filled = /./;

// Field without the "#" character in its value will match this.
var iw_valid = /^[^#]*$/;



// Prepare to initialize:
//
window.onload = iw_loadUpdate;

