function isIE()
{
  var detect = navigator.userAgent.toLowerCase();
  var place = detect.indexOf('msie') + 1;
  return place;
}

function utf8_decode(utftext) 
{
	var string = "";
	var i = 0;
	var c = c1 = c2 = 0;
	while ( i < utftext.length ) 
	{
		c = utftext.charCodeAt(i);
		if (c < 128) 
		{
			string += String.fromCharCode(c);
			i++;
		}
		else if((c > 191) && (c < 224)) 
		  {
			c2 = utftext.charCodeAt(i+1);
			string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
			i += 2;
		}
		else 
		  {
			c2 = utftext.charCodeAt(i+1);
			c3 = utftext.charCodeAt(i+2);
			string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
			i += 3;
		}
	}
	return string;
}

function base64_decode(data) 
{
  var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, dec = "", tmp_arr = []; 
  if (!data) return data;
  data += '';
  while(data.length % 4 != 0) data += "=";

  do
  {  
    h1 = b64.indexOf(data.charAt(i++));
    h2 = b64.indexOf(data.charAt(i++));        
    h3 = b64.indexOf(data.charAt(i++));
    h4 = b64.indexOf(data.charAt(i++));

    bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
    o1 = bits >> 16 & 0xff;
    o2 = bits >> 8 & 0xff;
    o3 = bits & 0xff;

    if (h3 == 64) tmp_arr[ac++] = String.fromCharCode(o1);
    else if (h4 == 64) tmp_arr[ac++] = String.fromCharCode(o1, o2);
    else tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);        
  } 
  while (i < data.length);

  dec = tmp_arr.join('');
  dec = utf8_decode(dec); 
  return dec;
}

function isLeapYear(year)
{
  return ( ((year)>0) && !((year)%4) && ( ((year)%100) || !((year)%400) ) );
}
  
function monthDays(month,year)
{
  month = parseInt(month);
  year = parseInt(year);
  switch(month)
  {
    case 1: return 31;
    case 2: 
      if(year == 0 || isLeapYear(year)) 
        return 29; 
      else 
        return 28;
      break;
    case 3: return 31;
    case 4: return 30;
    case 5: return 31;
    case 6: return 30;
    case 7: return 31;
    case 8: return 31;
    case 9: return 30;
    case 10: return 31;
    case 11: return 30;
    case 12: return 31;
    default: return 31;
  }
}

function submitenter(myfield,e)
{
  var keycode;
  if (window.event) keycode = window.event.keyCode;
  else if (e) keycode = e.which;
  else return true;
  
  if (keycode == 13)
  {
   myfield.form.submit();
   return false;
  }
  else return true;
}

function submit_func(func, e)
{
  var keycode;
  if (window.event) keycode = window.event.keyCode;
  else if (e) keycode = e.which;
  else return true;
  
  if (keycode == 13)
  {
   func();
   return false;
  }
  else return true;
}

function isValidIdentifier(ident, minlength)
{
  var reg = new RegExp("^[A-Za-z0-9_\-]{" + minlength.toString() + ",}$");
  return reg.test(ident);
}

function isValidEntityName(entityname)
{
  var reg = new RegExp("^[A-Za-z0-9_\-]{2,}(\.[A-Za-z0-9_\-]{2,})*$");
  return reg.test(entityname);
}

function isValidFilename(filename)
{
	var reg = new RegExp("^[^\\\/\:\*\?\"\<\>\|\.]+(\.[^\\\/\:\*\?\"\<\>\|\.]+)*$");
	if(!reg.test(filename)) return false;
	filename = filename.toLowerCase();
	var reg = new RegExp("^com[1-9]$");
	if(reg.test(filename)) return false;
	var reg = new RegExp("^lpt[1-9]$");
	if(reg.test(filename)) return false;
	return (filename != "con" && filename != "aux" && filename != "nul");
}

function getViewPortHeight()
{
  if (typeof window.innerWidth != 'undefined') // Mozilla
  {
    return window.innerHeight;
  }
  else if (typeof document.documentElement != 'undefined'
      && typeof document.documentElement.clientWidth !=
      'undefined' && document.documentElement.clientWidth != 0) // IE Standards compliant
  {
    return document.documentElement.clientHeight;
  }
  else // Old IE
  {
    return document.getElementsByTagName('body')[0].clientHeight;
  }  
}

function prepareIE(height, overflow)
{
  bod = document.getElementsByTagName('body')[0];
  bod.style.height = height;
  bod.style.overflow = overflow;
  
  htm = document.getElementsByTagName('html')[0];
  htm.style.height = height;
  htm.style.overflow = overflow; 
}
	
function toggleSelects(visibility)
{
  selects = document.getElementsByTagName('select');
  for(i = 0; i < selects.length; i++) 
  {
  	selects[i].style.visibility = visibility;
  }
}

function shade()
{
	if(isIE())
	{
    prepareIE('100%', 'hidden');
		//setScroll(0,0);	  
	  toggleSelects("hidden");
	  $('shader').style.top = document.body.scrollTop + "px";
	}
	
  $('shader').setStyle({ opacity: 0.60 });
  $('shader').style.display = "block";
  $('lightbox').style.display = "block";
}

function unshade()
{
	if(isIE())
	{
		prepareIE("auto","auto");
		toggleSelects("visible");
    $('shader').hide();
    $('lightbox').hide();
	}
	else
	{
		$('lightbox').hide();
		Effect.Fade($('shader'), { duration: 0.4 });  
	}
}

function centerWindow(id)
{
  var wnd = $(id);
  var viewheight = getViewPortHeight();
  var winheight = wnd.offsetHeight;
  var newtop = (viewheight - winheight)/2;
  if(isIE())
  {
  	newtop += document.body.scrollTop;
  }
  wnd.style.top = newtop.toString() + "px";
}

function openWindow(id)
{
  shade();
  var window = $(id);
  selects = window.getElementsByTagName('select');
  for(i = 0; i < selects.length; i++) selects[i].style.visibility = "visible";
  window = window.remove();
  $('lightbox').appendChild(window);
  window.show();
  if(isIE())
  {
    new Draggable(window, { revert: false, handle: "windowframe-handle", starteffect: null, endeffect: null });
  }
  else
  {
  	new Draggable(window, { revert: false, handle: "windowframe-handle" });
  }
  window.setStyle({ opacity: 1.00 });
  centerWindow(id);
}

function closeWindow(id)
{
	var window = $(id);
  window.hide();
  unshade();
}

function showHint(elem)
{
  elem = $(elem);
  var container = elem.up();
  var hintLeft = (elem.offsetLeft + elem.offsetWidth + 5).toString() + "px";
  var hintTop = (elem.offsetTop).toString() + "px";
  
  var div = Builder.node("div", { className: 'hint-top', style: "left: " + hintLeft + "; top: " + hintTop + ";" }, [
    Builder.node("div", { className: 'hint-bottom' }, [
      Builder.node("div", { className: 'hint-content' }, elem.alt )
    ])
  ]);
  
  if( elem.next() == null )
    container.appendChild(div);  
  else
    container.insertBefore(div, elem.next());  
}

function hideHint(elem)
{
  elem = $(elem);
  var hint = elem.next();
  if( hint != null ) hint.remove();
}

function showSuccess(txt)
{
  var adminSuccess = $('admin-success');
	adminSuccess.innerHTML = txt;
	adminSuccess.show();
	new PeriodicalExecuter(function(pe) {
    pe.stop();
    Effect.Fade(adminSuccess);
	}, 8);
}

track_id = 0;
track_rel = "";

function track(rel, lookup, recursive, referer, url)
{
	track_rel = rel;
  var params = "&w=" + screen.width;
  params = params + "&h=" + screen.height;
  params = params + "&c=" + screen.colorDepth;
  params = params + "&l=" + lookup;
  params = params + "&r=" + recursive;
  params = params + "&ref=" + referer;
  params = params + "&url=" + encodeURIComponent(url);
  var ajax = new Ajax.Request('ajax.php',
    {method: 'post', evalScripts: true, parameters: 's=' + rel + '/callback/track.php' + params, onComplete: track_complete }
  );
}

function track_complete(xhr)
{
	eval("track_id=" + xhr.responseText);
}

/*
 *  Global responders for Ajax events.
 *  OnCreate   - an Ajax request was initiated. Show the throbbing loader.
 *  OnComplete - an Ajax request was completed. Hide the throbbing loader 
 *               (but only when there are no more active requests).
 *
 */
/* var globalResponders = 
{
  onCreate: function()
  {
    Element.show('loader');
  },
  onComplete: function() 
  {
    if(Ajax.activeRequestCount == 0)
    {
      Element.hide('loader');
    }
  }
};
Ajax.Responders.register(globalResponders); */


Event.observe(window, 'load', function() {
  /*
   *  Add automatic hint display for form fields.
   */
  var inputs = $$('textarea[alt]', 'input[alt]');
  inputs.each(function(input) {
    input.onfocus = function() { showHint(input); return false; };
    input.onblur = function() { hideHint(input); return false; };
  });
  
  /*
   *  Add automatic Artemis button highlighting.
   */  
  var buttons = $$('div.artemis-button');
  buttons.each(function(btn) {
    btn.onmouseover = function() { $(this).style.backgroundPosition='0px -26px'; return false; };
    btn.onmouseout  = function() { $(this).style.backgroundPosition='0px 0px'; return false; };
  });  
});

/*
 *  Add automatic link tooltips.
 *  (should by called only by admin interface)
 *  Pass elem=null to initialize all tooltips in browser, or an element reference
 *  to initialize all tooltips within that element.
 */
function InitializeTooltips(elem)
{
  var links = elem == null ? $$('a') : elem.select('a');
  links.each(function(lnk) {
    var t = lnk.getAttribute("title");
    if(t != null && t.length != 0)
    {
      lnk.setAttribute("title", "");
      lnk.onmouseover = function(e) { locate_tooltip(e); $('tooltip-top').innerHTML = t; $('tooltip').show(); return false; };
      lnk.onmouseout  = function(e) { $('tooltip').hide(); return false; };
      lnk.onmousemove = locate_tooltip;    
    }
  });  
}

function getViewPortWidth()
{
  if (typeof window.innerWidth != 'undefined') // Mozilla
  {
    return window.innerWidth;
  }
  else if (typeof document.documentElement != 'undefined'
      && typeof document.documentElement.clientWidth !=
      'undefined' && document.documentElement.clientWidth != 0) // IE Standards compliant
  {
    return document.documentElement.clientWidth;
  }
  else // Old IE
  {
    return document.getElementsByTagName('body')[0].clientWidth;
  }  
}

function locate_tooltip(e)
{
  var posx = 0;
  var posy = 0;
  var hor_middle = getViewPortWidth() / 2;
  var vert_middle = getViewPortHeight() / 2 + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
  var tooltip = $('tooltip');
  
  if(e == null) e = window.event;
  if(e.pageX || e.pageY)
  {
    posx=e.pageX; posy=e.pageY;
  }
  else if(e.clientX || e.clientY)
  {
    if(document.documentElement.scrollTop)
    {
      posx = e.clientX + document.documentElement.scrollLeft;
      posy = e.clientY + document.documentElement.scrollTop;
    }
    else
    {
      posx = e.clientX + document.body.scrollLeft;
      posy = e.clientY + document.body.scrollTop;
    }
  }
  
  var dim = tooltip.getDimensions();
  var x = posx >= hor_middle ? (posx - 255) : (posx + 15);
  var y = posy >= vert_middle ? (posy - dim.height - 10) : (posy + 22);
  tooltip.style.left = x.toString() + "px";
  tooltip.style.top  = y.toString()+"px";  
}

/*
 *  Finish tracking on unload.
 */
Event.observe(window, 'unload', function() {
	if(track_id != 0)
	{
    var ajax = new Ajax.Request('ajax.php',
      {method: 'post', evalScripts: true, parameters: 's=' + track_rel + '/callback/track_finish.php&id=' + track_id }
    );
  }
});

var uploadControlList = {};

var UploadControl = Class.create(
{
  initialize: function(elem, postbackurl, dir, fcancel, translations )
  {
    this.elem = $(elem);
    this.postbackurl = postbackurl;
    this.dir = dir;
    this.filecount = 0;
    this.fcancel = fcancel;
    this.translations = translations ? translations : {};
    
    if (this.hasFlash()) 
    {
      this.initialize_flash(fcancel);
    }
    else
    {
      this.initialize_js(fcancel);
    }
  },
  
  hasFlash: function()
  {
  	return false;
    //return swfobject.hasFlashPlayerVersion("9.0.0");
  },
  
  initialize_flash: function()
  {
    var upload_link = Builder.node("a", { href: "#" }, [ this.translations.btn_upload ? this.translations.btn_upload : "Upload" ]);
    upload_link.onclick = this.uploadFiles.bind(this);
    var cancel_link = Builder.node("a", { href: "#" }, [ this.translations.btn_cancel ? this.translations.btn_cancel : "Cancel" ]);
    cancel_link.onclick = this.onCancel.bind(this);
    
    var header = Builder.node("div", { className: "header" }, [
      Builder.node("div", { className: "name" }, [ this.translations.hdr_file ? this.translations.hdr_file : "File" ]),
      Builder.node("div", { className: "size" }, [ this.translations.hdr_size ? this.translations.hdr_size : "Size" ]),
      Builder.node("div", { className: "options" }, [ this.translations.hdr_remove ? this.translations.hdr_remove : "Remove?" ])
    ]);
    
    var list = Builder.node("div", { className: "list" });
    
    var control = Builder.node("div", { className: "control" }, [
      Builder.node("div", { className: "files" }, ["0 " + (this.translations.str_files ? this.translations.str_files : "files") ]),
      Builder.node("div", { className: "add" },[
        Builder.node("div", { id: this.elem.id+"_flashhost" })
      ]),
      Builder.node("div", { className: "totalsize" }, [ (this.translations.str_total ? this.translations.str_total : "Total") + ": 0 bytes"]),
      Builder.node("div", { className: "upload", style: "display:none" }, [ upload_link ]),
      Builder.node("div", { className: "cancel" }, [ cancel_link ])
    ]);
    
    var form = Builder.node("form", { method: "post" });
    
    this.elem.className = "uploadcontrol-container";    
    this.elem.appendChild(header);
    this.elem.appendChild(list);
    this.elem.appendChild(control);
    this.elem.appendChild(form);
    
    swfobject.embedSWF(
      this.dir + "upload.swf", 
      this.elem.id+"_flashhost", 
      "80", "20", "9", 
      false,
      { elem: this.elem.id, url: this.postbackurl, label: (this.translations.btn_add ? this.translations.btn_add : "Add more") },
      { wmode: "transparent", allowScriptAccess: "sameDomain" }, 
      { id: this.elem.id+"_flash" } );
    
  	uploadControlList[this.elem.id] = this;    
  },
  
  initialize_js: function()
  {
    var upload_link = Builder.node("a", { href: "#" }, [this.translations.btn_upload ? this.translations.btn_upload : "Upload"]);
    upload_link.onclick = this.uploadJSFiles.bind(this);
    var cancel_link = Builder.node("a", { href: "#" }, [this.translations.btn_cancel ? this.translations.btn_cancel : "Cancel"]);
    cancel_link.onclick = this.onCancel.bind(this);
    var header = Builder.node("div", { className: "header" }, [
      Builder.node("div", { className: "name" }, [this.translations.hdr_file ? this.translations.hdr_file : "File"]),
      Builder.node("div", { className: "size" }, ["-"]),
      Builder.node("div", { className: "options" }, [this.translations.hdr_remove ? this.translations.hdr_remove : "Remove?"])
    ]);
    var list = Builder.node("form", { className: "list", method: "post", enctype: "multipart/form-data" });
    var fileinput = Builder.node("input", { type: "file", size: "10", value: ""});
    var control = Builder.node("div", { className: "control" }, [ 
      Builder.node("div", { className: "files" }, ["0 " + (this.translations.str_files ? this.translations.str_files : "files")]),
      Builder.node("div", { className: "browse"}, [ fileinput ]),
      Builder.node("div", { className: "upload", style: "padding-right:10px; display:none" }, [ upload_link ]),
      Builder.node("div", { className: "cancel" }, [ cancel_link ])
    ]);
    this.elem.className = "uploadcontrol-container";   
    this.elem.appendChild(header);
    this.elem.appendChild(list);
    this.elem.appendChild(control);
	  this.id = 0;
    this.addElement(fileinput);
  },
  
  uploadJSFiles: function()
  {
    this.elem.down().next().submit();
  },
  
  addElement: function(element)
  {
		element.name = 'file_' + this.id++;
		element.uploadcontrol = this;
		var myself = this;
		element.onchange = function()
    {
      if(myself.alreadyHasFile(this.value))
      {
        this.value = "";
      }
      else
      {
        var new_element = Builder.node("input", { type: "file", size: "10" });
  			this.parentNode.insertBefore( new_element, this );
  			this.uploadcontrol.addElement( new_element );
  			this.uploadcontrol.addListRow( this );
  	  }		
		};
  },
  
  updateJSInfo: function()
  {
    var countstr = this.filecount == 1 ? ("1 " + (this.translations.str_file ? this.translations.str_file : "file")) : this.filecount.toString() + " " + ((this.translations.str_files ? this.translations.str_files : "files"));
    this.elem.down().next().next().down().innerHTML = countstr;
    
    // Show upload div
    var uploaddiv = this.elem.down().next().next().down().next().next();
    uploaddiv.hide(); if( this.filecount > 0 ) uploaddiv.show();
  },
  
	addListRow: function( element )
	{
	  element = $(element);
	  element.style.position = "absolute"; 
	  element.style.left = "-1000px";
	  element.remove();
		var list = this.elem.down().next();
    var delete_link = Builder.node("a", { className: "deletelink", href: "#" }, [ this.getDeleteImg() ]);
    var myself = this;
		delete_link.onclick = function() { myself.filecount--; myself.updateJSInfo(); $(this).up().up().remove(); return false; };
    var block = Builder.node("div", { className: "block" }, [
      Builder.node("div", { className: "bytes" }, [ element ] ),
      Builder.node("div", { className: "name" }, [ element.value ] ),
      Builder.node("div", { className: "size" }, [ "-" ] ),
      Builder.node("div", { className: "options" }, [ delete_link ] )
    ]);
    list.appendChild(block);
	  this.filecount++;
	  this.updateJSInfo();    
	},  
	
	alreadyHasFile: function( filename )
	{
	  var result = false;
	  var list = this.elem.down().next();
	  list.select("input").each (function(input)
	  {
	    if(input.value == filename) result = true;
	  });
	  return result;
	},
  
  round2: function(val)
  {
    var rounded = Math.round(val*100).toString();
    var frac = ((Math.round(val*100))/100).toString();
    if(frac.length == rounded.length) frac += "0";
    return frac;
  }, 
  
  bytesToString: function(bytes)
  {
    if( bytes > 1048576 ) return this.round2(bytes/1048576) + " MB";
    else if( bytes > 1024 ) return this.round2(bytes/1024) + " KB";
    else return bytes.toString() + " bytes";    
  },
  
  updateInfo: function()
  {
    // Calc total size
    var totalsize = 0;
    this.elem.down().next().select("div.block").each (function(block) {
      var size = parseInt(block.down().innerHTML);
      totalsize += size;
    });
    this.elem.down().next().next().down().next().next().innerHTML = (this.translations.str_total ? this.translations.str_total : "Total") + ": " + this.bytesToString(totalsize);    
    
    var countstr = this.filecount == 1 ? ("1 " + (this.translations.str_file ? this.translations.str_file : "file")) : this.filecount.toString() + " " + ((this.translations.str_files ? this.translations.str_files : "files"));
    this.elem.down().next().next().down().innerHTML = countstr;
    
    // Show upload div
    var uploaddiv = this.elem.down().next().next().down().next().next().next();
    uploaddiv.hide(); if( this.filecount > 0 ) uploaddiv.show();
  },
  
  deleteFile: function(link)
  {
    var filename = $(link).up().previous().previous().innerHTML;
    $(this.elem.id+"_flash").jsRemoveFile(filename);
    var block = $(link).up().up();
    block.remove(); 
    this.filecount--;
    this.updateInfo();
    return false;
  },
  
  onCancel: function()
  {
    if ( this.hasFlash()) 
    {
      $(this.elem.id+"_flash").jsRemoveAllFiles();
      this.elem.down().next().innerHTML = "";
      this.filecount = 0;
      this.updateInfo();        
    }
    else
    {
      this.elem.down().next().innerHTML = "";
      this.filecount = 0;
      this.updateJSInfo();      
    }
    
    this.fcancel();
  },
  
  getDeleteImg: function()
  {
    var delete_img = Builder.node("img", { src: this.dir + "delete.gif" });
    var myself = this;
    delete_img.onmouseover = function () { this.src = myself.dir + "delete_highlighted.gif"; return false; };
    delete_img.onmouseout = function () { this.src = myself.dir + "delete.gif"; return false; };    
    return delete_img;
  },
  
  onAddFile: function(filename, bytes)
  {
    var list = this.elem.down().next();
    
    // Determine size as string
    var sizestr = this.bytesToString(bytes);
    
    var delete_link = Builder.node("a", { className: "deletelink", href: "#" }, [ this.getDeleteImg() ]);
    delete_link.onclick = this.deleteFile.bind(this, delete_link);
    
    var block = Builder.node("div", { className: "block" }, [
      Builder.node("div", { className: "bytes" }, [ bytes.toString() ] ),
      Builder.node("div", { className: "name" }, [ filename ] ),
      Builder.node("div", { className: "size" }, [ sizestr ] ),
      Builder.node("div", { className: "options" }, [ delete_link ] ),
      Builder.node("div", { className: "progress_bk", style: "display: none" }, [
        Builder.node("div", { className: "progress" }, [ "0%" ] )
      ])
    ]);
    list.appendChild(block);
    
    this.filecount++;
    this.updateInfo();
  },
  
  uploadFiles: function()
  {
    $(this.elem.id+"_flash").jsUploadFiles();
    this.elem.down().next().next().down().next().next().next().hide();
    this.elem.down().next().next().down().next().next().next().next().hide();
  },
  
  findBlock: function(filename)
  {
    var blocks = this.elem.down().next().select("div.block");
    for(var i = 0; i < blocks.length; i++)
    {
      var blockfilename = blocks[i].down().next().innerHTML;
      if(blockfilename == filename) return blocks[i];
    }
    return null;
  },

  onOpen: function(filename)
  {  
    var block = this.findBlock(filename);
    block.down().next().next().next().hide();
    block.down().next().next().next().next().show();  
  },
  
  onProgress: function(filename, bytesLoaded, bytesTotal)
  {
    var percentage = Math.round(bytesLoaded * 100 / bytesTotal);
    var offset = Math.round(68 - (bytesLoaded * 68 / bytesTotal));
    var block = this.findBlock(filename);
    var progressbar = block.down().next().next().next().next().down();
    progressbar.style.backgroundPosition = "-" + offset.toString() + "px 0px";
    progressbar.innerHTML = percentage.toString() + "%";    
  },
  
  onComplete: function(filename)
  {
    var block = this.findBlock(filename);
    var progressbar = block.down().next().next().next().next().down();
    progressbar.style.backgroundPosition = "0px 0px";
    progressbar.innerHTML = "100%";    

    this.filecount--;
    // downloads complete, submit form.
    if( this.filecount == 0 )
    {
      this.elem.down().next().next().next().submit();
    }
  }
});

function uploadcontrol_onAddFile(elem, filename, bytes)
{
  uploadControlList[elem].onAddFile(filename, bytes);
}

function uploadcontrol_onOpen(elem, filename)
{
  uploadControlList[elem].onOpen(filename);
}

function uploadcontrol_onProgress(elem, filename, bytesLoaded, bytesTotal)
{
  uploadControlList[elem].onProgress(filename, bytesLoaded, bytesTotal);
}

function uploadcontrol_onComplete(elem, filename)
{
  uploadControlList[elem].onComplete(filename);
}



function artemis_table_init_column(guid, idx, tablewidth, columncount)
{
  new Draggable(guid+'-drag-'+idx, { constraint: 'horizontal',  onEnd: function(draggable, mouseevent) { artemis_table_column_resized(draggable, mouseevent, guid, idx, tablewidth, columncount, true); }, change: function(draggable) { artemis_table_column_resized(draggable, null, guid, idx, tablewidth, columncount, false); } });
}

function artemis_table_column_resized(draggable, mouseevent, guid, idx, tablewidth, columncount, mustupdate)
{
  var lpadding = 10;
  var rpadding = 10;
  var div = $(guid+'-drag-'+idx);
  
  // Get position of left margin.
  var lmargin = 0;
  if(idx > 1)
  {
    var position = $(guid+'-drag-'+(idx-1)).positionedOffset();
    lmargin = position.left;
  }
  
  // Get position of right margin.
  var rmargin = tablewidth;
  if (idx < columncount - 1)
  {
    var position = $(guid+'-drag-'+(idx+1)).positionedOffset();
    rmargin = position.left;
  }
  
  // Get dragged position of divider.
  var position = div.positionedOffset();
  position = position.left;
  
  // Make sure final position is between margins, with some padding.
  if(position < lmargin + lpadding) position = lmargin + lpadding;
  if(position > rmargin - rpadding) position = rmargin - rpadding;
  
  // Set final position.
  div.style.left = position + "px";
  
  // Determine width of left-hand and right-hand columns.
  var leftwidth = position - lmargin;
  var rightwidth = rmargin - position;
  
  // Set left-hand width.
  var tablediv = $(guid).down();
  var lcolumn = idx == 1 ? tablediv.down() : (idx == 2) ? tablediv.down().next() : tablediv.down().next(idx-2);
  lcolumn.style.width = leftwidth + "px";
  // Set right-hand width.
  var rcolumn = idx == 1 ? tablediv.down().next() : tablediv.down().next(idx-1);
  rcolumn.style.left = position + "px";
  rcolumn.style.width = rightwidth + "px";
  
  if(mustupdate)
  {
    // Get all widths:
    var cols = "";
    tablediv.immediateDescendants().each(function(col) {
      var wstr = col.style.width.toString();
      var width = wstr.substr(0, wstr.length - 2);
      if(cols == "") 
        cols = width.toString();
      else 
        cols = cols + "-" + width.toString();
    });
    
    // Send widths to Artemis:
    var ajax = new Ajax.Request('ajax.php',
      { method: 'post', evalScripts: true, parameters: 's=' + artemis_rel + '/base/ajaxtable-widths.php&session=admin&guid=' + guid + "&columns=" + cols });
  }
}

function artemis_table_update(guid, p0, p1, p2, p3, p4)
{
  $(guid+"-loader").show();
  var params = "";
  if(p0) params += "&p0="+p0;
  if(p1) params += "&p1="+p1;
  if(p2) params += "&p2="+p2;
  if(p3) params += "&p3="+p3;
  if(p4) params += "&p4="+p4;
  var ajax = new Ajax.Request('ajax.php', 
    { method: 'post', evalScripts: true, parameters: 's=' + artemis_rel + '/base/ajaxtable.php&session=admin&guid=' + guid + "&cmd=update" + params, 
      onComplete: function(xhr) { artemis_table_complete(guid, xhr); } } );
}

function artemis_table_offset(guid, offset)
{
  $(guid+"-loader").show();
  var ajax = new Ajax.Request('ajax.php', 
    { method: 'post', evalScripts: true, parameters: 's=' + artemis_rel + '/base/ajaxtable.php&session=admin&guid=' + guid + "&cmd=offset&offset=" + offset, 
      onComplete: function(xhr) { artemis_table_complete(guid, xhr); } } );  
}

function artemis_table_sort(guid, col)
{
  $(guid+"-loader").show();
  var ajax = new Ajax.Request('ajax.php', 
    { method: 'post', evalScripts: true, parameters: 's=' + artemis_rel + '/base/ajaxtable.php&session=admin&guid=' + guid + "&cmd=sort&col=" + col, 
      onComplete: function(xhr) { artemis_table_complete(guid, xhr); } } );  
}

function artemis_table_complete(guid, xhr)
{
  //alert(xhr.responseText);
  var data; eval("data=" + xhr.responseText);
  
  var tablediv = $(guid).down();
  
  // Set column widths:
  var columns = tablediv.immediateDescendants();
  var posx = 0;
  for( var i = 0; i < data.columns.length; i++)
  {
    columns[i].style.left = posx.toString() + "px";
    columns[i].style.width = data.columns[i].toString() + "px";
    posx += parseInt(data.columns[i]);
  }
  
  // Clear sort column icons:
  var columns = tablediv.immediateDescendants();
  columns.each(function(column) {
    var columnheader = column.down();
    if(columnheader.down().immediateDescendants().length == 4)
    {
      columnheader.down(1).next().show();
      columnheader.down(1).next(1).hide();
      columnheader.down(1).next(2).hide();
    }
  });
  
  // Set sort column icon:
  columns[data.sortcol].down(2).next().hide();
  if(data.sortdir == 0)
    columns[data.sortcol].down(2).next(1).show();
  else
    columns[data.sortcol].down(2).next(2).show();
  
  // Empty cells:
  tablediv.select("div.ajaxtable-cell").each(function(cell) { cell.down().innerHTML = ""; });
  
  // Fill table:
  var scripts = [];
  for (var y = 0; y < data.rows.length; y++)
  {
    for (var x = 0; x < data.rows[y].length; x++)
    {
      var column = columns[x];
      var cell = column.down().next(y);
      var localscripts = data.rows[y][x].extractScripts();
      localscripts.each(function(s) { scripts.push(s) });
      cell.down().innerHTML = data.rows[y][x];
    }
  }
  
  // Execute any javascript found:
  scripts.each(function(s) { eval(s); });
  
  if(data.first != -1)
  {
    $(guid+"-first-on").show();
    $(guid+"-first-off").hide();
    $(guid+"-first-on").onclick = function() { artemis_table_offset(guid, data.first); return false; };
  }
  else
  {
    $(guid+"-first-off").show();
    $(guid+"-first-on").hide();
  }
  
  if(data.prev != -1)
  {
    $(guid+"-prev-on").show();
    $(guid+"-prev-off").hide();
    $(guid+"-prev-on").onclick = function() { artemis_table_offset(guid, data.prev); return false; };
  }  
  else
  {
    $(guid+"-prev-off").show();
    $(guid+"-prev-on").hide();
  }
  
  if(data.next != -1)
  {
    $(guid+"-next-on").show();
    $(guid+"-next-off").hide();
    $(guid+"-next-on").onclick = function() { artemis_table_offset(guid, data.next); return false; };
  }    
  else
  {
    $(guid+"-next-off").show();
    $(guid+"-next-on").hide();    
  }

  if(data.last != -1)
  {
    $(guid+"-last-on").show();
    $(guid+"-last-off").hide();        
    $(guid+"-last-on").onclick = function() { artemis_table_offset(guid, data.last); return false; };
  }      
  else
  {
    $(guid+"-last-off").show();
    $(guid+"-last-on").hide();        
  }  
  
  for(var i = 0; i < 7; i++)
  {
    var pager = data.pagers[i];
    var elem = $(guid+"-pager-"+i);
    if(pager.show)
    {
      elem.show();
      elem.down().innerHTML = pager.page;
      elem.down().name = pager.offset;
      elem.down().onclick = function() { artemis_table_offset(guid, $(this).name); return false; };
    }
    else
    {
      elem.hide();
    }
  }
  
  $(guid+"-count").innerHTML = "(" + data.count.toString() + ")";
  
  InitializeTooltips(tablediv);
  
  $(guid+"-loader").hide();
}
