// Author: I.Plisco (igor at plisco dot ru)
// Aim: Javascript for loading page elements.
// $Id: loader.js,v 1.4 2006/08/14 11:37:20 temik Exp $

var elems = new Array();	// array of elements to load
var tries = 1;	// attempts to load an element
var loop_count = 0;	// incremental counter
var loop_count_max = 10000;	// Any large number
//var html_wait = "<img src=http://img.novoteka.ru/i/wait.gif>";	// sand clock
var html_wait = "Загружаем с сервера, ждите.";	// HTML shown before loading
var img_plus = "[+]";	// plus sign
var img_minus = "[&ndash;]";	// minus sign
//var img_plus = "<img src=http://img.novoteka.ru/i/plus.gif>";	// plus sign
//var img_minus = "<img src=http://img.novoteka.ru/i/minus.gif>";	// minus sign
var loader_iframe = "loader";	// name of iframe of loader

//============================================================
function Elem(target, url, status) {
//============================================================
/*

Constructor. Creates new element (to load into page).

Property 'status' may be:
	0 - not tried to load
	1 - called loading of it into loader iframe
	2+ - next tries after unsuccessful loading
	tries+1 - successfully shown

Parameters:
	target - <div> to load into
	url - URL to load
	status - start status (optional, default is 0) 

*/
//------------------------------------------------------------

  this.url = url;
  this.target = target;
  this.status = status || 0;

}

//============================================================
function add_elem(target, url, status) {
//============================================================
/*

Adds new element to load to the end of list for delayed loading.

Usage:

  In element page:
  <body onLoad=";;self.parent.add_elem('target3', 'page3.html');;;">
  It prepares page3.html for loading into <div id="target3"> after
  loading of all other pages in the list.

Parameters:
	target - <div> to load into
	url - URL to load
	status - start status (optional, default is 0) 

Returns: Nothing.

*/
//------------------------------------------------------------

//  elems.push(new Elem(target, url, status));
  elems[elems.length] = new Elem(target, url, status);

}

//============================================================
function load_elem(target, url) {
//============================================================
/*

Adds new element to the list and starts loading it.

Usage:

  In element page:
  <div onClock=";;load_elem('target3', 'page3.html');;;">
  It starts loading of the page3.html into <div id="target3"> immediately.

Parameters:
	target - <div> to load into
	url - URL to load

Returns: Nothing.

*/
//------------------------------------------------------------

//  elems.push(new Elem(target, url));
  elems[elems.length] = new Elem(target, url);
  load_next();

}

//============================================================
function getFromLoader() {
//============================================================
  var str_before = str_after = "";

  str_before = document.all ? document.frames[0].document.getElementById("txt").innerHTML : document.getElementById(loader_iframe).contentWindow.document.getElementById("txt").innerHTML;
  str_after = str_before.replace(/['"];;|;;['"]/g, '"');

  return str_after;
}

//============================================================
function load_next() {
//============================================================
/*

Loads next unloaded element from array elems[] into hidden frame.

Parameters: None.

Returns: 1 - after loading an element, 2 - if all elements are loaded yet. 

*/
//------------------------------------------------------------
  var element, i;

//  alert("load_next called");
//  debug_elems("load_next");

// Defence from infinite looping
  if(loop_count++ > loop_count_max) return 3;

// Defence from memory leak - cut loaded elements
  try {	// for IE 5.0
    while(elems.length && elems[0].status >= tries) {
      elems.shift();
    }
  } catch(e) {
    // do nothing
  }

// Go through elems[] and find first unloaded element
  for (i in elems) {
    if(elems[i].status >= tries) continue;	// for IE 5.0

// Give up loading element if there are server problems
//    if(elems[i].status == tries) {
//      elems[i].status++;
//      continue;
//    }

    element = elems[i];
    break;

  }

// Exit if all elements are loaded yet
  if(!element) return 2;

// Mark it as ready to load
  elems[i].status++;

// Clear element if url is empty
  if(!element.url) {
    document.getElementById(loader_iframe).src="";	// for Konqueror
    document.getElementById(element.target).innerHTML = "";
    load_next();

// Load chosen element if url is not empty
  } else {
    document.getElementById(element.target).innerHTML = html_wait;
    try {
      document.getElementById(loader_iframe).src="";
      document.getElementById(loader_iframe).src=element.url;
    } catch(e) {
//      alert("Error catched in load_next");
      load_next();
    }
  }

//  alert("On load_next exit: " + element.url + " --> " + element.target + " / " + element.status);

  return 1;

}

//============================================================
function show_me() {
//============================================================
/*

Puts element into target <div> after loading.
Then it starts loading next elements waiting for load by load_next().

Parameters: None.

Returns: 1 - after loading an element, 2 - if all elements are loaded yet. 

*/
//------------------------------------------------------------
  var element, i;

//  alert("show_me called");
//  debug_elems("show_me");

// Go through elems[] and show first unshown elements
  for (i in elems) {

//    if(elems[i].status > tries || elems[i].status == 0) continue;
    if(elems[i].status > tries || elems[i].status == 0 || elems[i].url == '') continue;

    element = elems[i];
    break;
  }

// Exit if all elements are shown yet (some error occured)
  if(!element) return 2;

// Load chosen element
  try {
    document.getElementById(element.target).innerHTML=getFromLoader();
    elems[i].status = tries + 1;	// mark it as shown
  } catch(e) {
//    alert("Error catched in show_me");
// do nothing
  }

//  alert("On show_me exit: " + element.url + " --> " + element.target + " / " + element.status);

// Do the same for next element in the list
  return load_next();

}


//============================================================
function open_close(id, url) {
//============================================================
/*

Opens given item if it's closed or closes it otherwise.

The item must have 2 relative items  with suffices "_pm" for plus/minus
sign and "_sub" for subitem.

Example:

<div onClick=";;open_close('target6', 'el6_sub.html');;;">

  <div id="target6_sign" style="display: inline;">
    <img src="http://img.novoteka.ru/i/plus.gif">
  </div>

  <h2 style="display: inline;">Some heading text</h2>

</div>

<div id="target6">
</div>

Dont't forget to write default image of plus sign in the "..._pm" field.

Parameters:
	id - item name
	url - URL to open in subitem

** TODO **
If url is empty - makes closed item (called by onLoad).

Returns: Nothing.

*/
//------------------------------------------------------------
  var el_sub, img;
  var empty_len = 10;	// empty <div> is shorter than empty_len
  var wants_open = 1;

  var id_pm = id + "_sign";	// plus/minus sign

// Caller wants to open subitem or not
  if(!url) {
    wants_open = 0;
  } else if(document.getElementById(id).innerHTML.length > empty_len) {
    wants_open = 0;
  }

// Determine current state of item by content of id
  if(wants_open) {
    img = img_minus;
    add_elem(id, url);
  } else {
    img = img_plus;
    add_elem(id, "");
  }

//// Write plus sign
//  if(url) {	// loaded yet
//    document.getElementById(id_pm).innerHTML = img;
//  } else {	// onLoad event in loader iframe
//    if(document.all) {	// hack?
//      document.frames[0].document.getElementById(id_pm).innerHTML = img;
//    } else {
//      document.getElementById(loader_iframe).contentWindow.document.getElementById(id_pm).innerHTML = img;
//    }
//  }
    if(document.getElementById(id_pm)) {
      document.getElementById(id_pm).innerHTML = img;
    }

  load_next();

}

//============================================================
function debug_elems(prefix) {
//============================================================
/*

Shows content of 'elems' array by alert().

Parameters:
	prefix - message prefix

Returns: Nothing.

*/
//------------------------------------------------------------
  
  var message = prefix + ": \n";

  for (i in elems) {
    message += elems[i].target +" - " +elems[i].url + " (" + elems[i].status + ")\n";
  }
  
  alert(message);

}

