//  Edlets common javascript
//  (c) 2004 Nick Evan-Wong / Edlets <developers@discodog.co.uk>
//  ------------------------------------------------------------



// open popup window for images //DEPREACTED - USE LIGHTBOX INSTEAD
function imageWindow(url,w_name) {
	var win_name = "imageviewer";
	if (w_name) { win_name = w_name; }		
	winHandle = window.open(url,win_name,"titlebar=no,toolbar=no,width=100,height=100");
	winHandle.focus();
}


// open popup window for help documents
function helpWindow(url, w_name) {
	var win_name = "edletshelp";
	if (w_name) { win_name = w_name; }
	winHandle = window.open(url,win_name,"titlebar=no,toolbar=no,width=300,height=400");
	winHandle.focus();
}

// open popup window for T&C documents
function tandcWindow(url, w_name) {
	var win_name = "conditions";
	if (w_name) { win_name = w_name; }
	winHandle = window.open(url,win_name,"titlebar=no,toolbar=no,scrollbars=yes,width=500,height=600");
	winHandle.focus();
}


// options: * width, height, left, top, center, name, scrollbars, menubar, locationbar, resizable, focus
function open_window(href, options) {

	var args = '';
 
	if (typeof(options) == 'undefined') { var options = new Object(); }
	if (typeof(options.name) == 'undefined') { options.name = 'win' + Math.round(Math.random()*100000); }
 
	if (typeof(options.height) != 'undefined' && typeof(options.fullscreen) == 'undefined') {
		args += "height=" + options.height + ",";
	}
 
	if (typeof(options.width) != 'undefined' && typeof(options.fullscreen) == 'undefined') {
		args += "width=" + options.width + ",";
	}
 
	if (typeof(options.fullscreen) != 'undefined') {
		args += "width=" + screen.availWidth + ",";
		args += "height=" + screen.availHeight + ",";
	}
 
	if (typeof(options.center) == 'undefined') {
		options.x = 0;
		options.y = 0;
		args += "screenx=" + options.x + ",";
		args += "screeny=" + options.y + ",";
		args += "left=" + options.x + ",";
		args += "top=" + options.y + ",";
	}
 
	if (typeof(options.center) != 'undefined' && typeof(options.fullscreen) == 'undefined') {
		options.y=Math.floor((screen.availHeight-(options.height || screen.height))/2)-(screen.height-screen.availHeight);
		options.x=Math.floor((screen.availWidth-(options.width || screen.width))/2)-(screen.width-screen.availWidth);
		args += "screenx=" + options.x + ",";
		args += "screeny=" + options.y + ",";
		args += "left=" + options.x + ",";
		args += "top=" + options.y + ",";
	}
 
	if (typeof(options.scrollbars) != 'undefined') { args += "scrollbars=1,"; }
	if (typeof(options.menubar) != 'undefined') { args += "menubar=1,"; }
	if (typeof(options.locationbar) != 'undefined') { args += "location=1,"; }
	if (typeof(options.resizable) != 'undefined') { args += "resizable=1,"; }
  	
	var win = window.open(href, options.name, args);
		
	if (typeof(options.focus) != 'undefined') { win.focus(); }
	
	return false;
 
}

// generic enumeration
Function.prototype.forEach = function(object, block, context) {
  for (var key in object) {
    if (typeof this.prototype[key] == "undefined") {
      block.call(context, object[key], key, object);
    }
  }
};

// Dean Edwards - http://dean.edwards.name/weblog/2006/07/enum/
// globally resolve forEach enumeration
var forEach = function(object, block, context) {
  if (object) {
    var resolve = Object; // default
    if (object instanceof Function) {
      // functions have a "length" property
      resolve = Function;
    } else if (object.forEach instanceof Function) {
      // the object implements a custom forEach method so use that
      object.forEach(block, context);
      return;
    } else if (typeof object.length == "number") {
      // the object is array-like
      resolve = Array;
    }
    resolve.forEach(object, block, context);
  }
};


// Get browser viewable screen size
function get_viewable_screen() {
	var viewportwidth;
 	var viewportheight; 
 	// the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight 
 	if (typeof window.innerWidth != 'undefined') {
    	viewportwidth = window.innerWidth,
      	viewportheight = window.innerHeight
	} 
	// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
 	else if (typeof document.documentElement != 'undefined' && typeof document.documentElement.clientWidth !='undefined' && document.documentElement.clientWidth != 0) {
    	viewportwidth = document.documentElement.clientWidth,
       	viewportheight = document.documentElement.clientHeight
 	} 
 	// older versions of IE
 	else {
    	viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
       	viewportheight = document.getElementsByTagName('body')[0].clientHeight
	}			 			

	rtn = { 'width': viewportwidth, 'height': viewportheight};
	return(rtn);
}

// Bookmark page
function bookmark(url,title){
  if ((navigator.appName == "Microsoft Internet Explorer") && (parseInt(navigator.appVersion) >= 4)) {
  window.external.AddFavorite(url,title);
  } else if (navigator.appName == "Netscape") {
    window.sidebar.addPanel(title,url,"");
  } else {
    alert("Press CTRL-D (Netscape) or CTRL-T (Opera) to bookmark");
  }
}

// Confirmation dialog
function confirm_action(msg) {

  var response = confirm(msg);
  if (response) { 
	return true ; 
  } else {
	return false ; 
  }

}

function checkAll(form,elem_id,set) {
	var elem = 0;
	var i = 0;
	while (elem = form.elements[i]) {
	    if (elem_id && elem.name == elem_id) { 
		
			if (set) {
				elem.checked = true;
			} else {
	            elem.checked = false;
			}
		}
		i++;
	}
return true;
}

// focus a form field if exists
function focus_field(field_name) {
	if (document.getElementById(field_name)) {
		document.getElementById(field_name).focus();
	}
}




// Leigeber's tooltip function (modifed)
var tooltip=function(){
	var id = 'tt';
	var top = 3;
	var left = 3;
	var maxw = 500;
	var speed = 10;
	var timer = 20;
	var endalpha = 95;
	var alpha = 0;
	var tt,t,c,b,h;
	var ie = document.all ? true : false;
	return{
		show:function(v,w){
		  if(v) {
			if(tt == null){
				tt = document.createElement('div');
				tt.setAttribute('id',id);
				t = document.createElement('div');
				t.setAttribute('id',id + 'top');
				c = document.createElement('div');
				c.setAttribute('id',id + 'cont');
				b = document.createElement('div');
				b.setAttribute('id',id + 'bot');
				tt.appendChild(t);
				tt.appendChild(c);
				tt.appendChild(b);
				document.body.appendChild(tt);
				// remove fade overhead - nick 22/08/2008 11:52
				//tt.style.opacity = 0;
				//tt.style.filter = 'alpha(opacity=0)';
				document.onmousemove = this.pos;
			}
			tt.style.display = 'block';
			c.innerHTML = v;
			tt.style.width = w ? w + 'px' : 'auto';
			if(!w && ie){
				t.style.display = 'none';
				b.style.display = 'none';
				tt.style.width = tt.offsetWidth;
				t.style.display = 'block';
				b.style.display = 'block';
			}
			if(tt.offsetWidth > maxw){tt.style.width = maxw + 'px'}
			h = parseInt(tt.offsetHeight) + top;
			// remove fade overhead - nick 22/08/2008 11:52
			//clearInterval(tt.timer);
			//tt.timer = setInterval(function(){tooltip.fade(1)},timer);			
		  }
		},
		pos:function(e){			
			// For IE6 compatibity - nick 22/08/2008 11:32
			var u = 0, l = 0;
			if( typeof( window.pageYOffset ) == 'number' ) {
				//Netscape compliant
				u = window.pageYOffset;
    			l = window.pageXOffset;
  			} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
    			//DOM compliant
    			u = document.body.scrollTop;
    			l = document.body.scrollLeft;
  			} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
    			//IE6 standards compliant mode
    			u = document.documentElement.scrollTop;
    			l = document.documentElement.scrollLeft;
  			}						
			u = ie ? event.clientY + u : e.pageY;
			l = ie ? event.clientX + l : e.pageX;
			tt.style.top = (u - h) + 'px';
			tt.style.left = (l + left) + 'px';
		},
		fade:function(d){
			var a = alpha;
			if((a != endalpha && d == 1) || (a != 0 && d == -1)){
				var i = speed;
				if(endalpha - a < speed && d == 1){
					i = endalpha - a;
				}else if(alpha < speed && d == -1){
					i = a;
				}
				alpha = a + (i * d);
				tt.style.opacity = alpha * .01;
				tt.style.filter = 'alpha(opacity=' + alpha + ')';
			}else{
				//clearInterval(tt.timer);
				if(d == -1){tt.style.display = 'none'}
			}
		},
		hide:function(){
			// remove fade overhead - nick 22/08/2008 11:52
			if (tt) { tt.style.display = 'none'; }
			//clearInterval(tt.timer);
			//tt.timer = setInterval(function(){tooltip.fade(-1)},timer);
			
		}
	};
}();



// Open an inline 'window' for HTML content

// preload required images
var image_close = new Image(15,15);
image_close.src = '/images/close.jpg';
var image_load_anim = new Image(24,24);
image_load_anim.src = '/images/load-anim.gif';

var inline_window=function(){
	var id = 'dialog_win';	
	var dialog_el,title_el,content_el,width,height, divobj, waitifrm;
	var ie = document.all ? true : false;
	return{
		create:function(title,content,w,h,modal){
		  	
		  	if (document.getElementById(id)!=undefined) { inline_window.destroy(); }		  	
		  	
			dialog_el = document.createElement('div');
			dialog_el.setAttribute('id',id);						
			document.body.appendChild(dialog_el);					
			dialog_el.style.border = '1px solid';
			dialog_el.style.padding = '0px 0px 0px 0px';
			dialog_el.style.position = 'absolute';
			dialog_el.style.zIndex = '101';
			if (!content || content=='') { content= "<table width='100%' height='100%' bgcolor='#FFFFFF'><tr><td align='center' valign='top'><img src='/images/load-anim.gif' border='0' /><h2>Please wait</h2></td></tr></table>"; }
			var c_height = h-12;
			dialog_el.innerHTML = '<table cellpadding=\"2\" cellspacing=\"0\" width=\"'+w+'\" height=\"'+h+'\"><tr><td height=\"12\" class=\"table_title\" valign=\"middle\">' + title + '</td><td class=\"table_title\" align=\"right\"><a href=\"#\" onclick=\"inline_window.destroy(); return(false)\"  title=\"Close\"><img src=\"/images/close.jpg\" border=\"0\" /></a></td></tr><tr><td colspan=\"2\" class=\"table_data\" valign=\"top\" height=\"' + c_height + '\"><div id=\"content_el\" name=\"content_el\" style=\"padding: 4px\">' + content + '</div></td></tr></table>';
			dialog_el.style.display = 'none';
			width = w;
			height = h;
			dialog_el.style.width = w ? w + 'px' : 'auto';;
			dialog_el.style.height = h ? h + 'px' : 'auto';				
		  	this.set_pos();
		  if (modal) { this.show_mask(); dialog_el.setAttribute('z-index','101'); }
		  dialog_el.style.display = 'block';		  
		  this.content_el = document.getElementById('content_el');		  		  		  
		  return this;
		},
		
		// destructor
		destroy:function() {						
			dialog_el.parentNode.removeChild(dialog_el);
			dialog_el = undefined;
			waitifrm.style.display = divobj.style.display = "none"; 
		},
		
		// position window in the centre of the viewport
		set_pos:function(){						
			var dimensions = get_viewable_screen();
			var top = (dimensions['height']/2) - (height/2);
			var left = (dimensions['width']/2) - (width/2);
			if (top < 0) { top = 0; }
			if (left<0) { left = 0; }
			dialog_el.style.left = left;
			dialog_el.style.top = top;			
		},
				
		// show mask (for modal windows)
		show_mask:function() {			
		 if(!document.getElementById("xdivmasking")) {   
          var divEle = document.createElement('div');   
          divEle.setAttribute("id","xdivmasking");   
          document.body.appendChild(divEle);   
          var divSty = document.getElementById("xdivmasking").style;   
          divSty.position = "absolute"; divSty.top="0px"; divSty.left="0px";   
          divSty.zIndex = "46"; divSty.opacity = ".50"; divSty.backgroundColor = "#000";   
          divSty.filter = "alpha(opacity=50)";   
  
          var divFram = document.createElement('iframe');   
          divFram.setAttribute("id","xmaskframe");   
          document.body.appendChild(divFram);   
          divSty = document.getElementById("xmaskframe").style;   
          divSty.position = "absolute"; 
          divSty.top = "0px"; divSty.left = "0px"; divSty.zIndex = "45"; divSty.border = "none"; divSty.filter = "alpha(opacity=0)";
        }   
  
        divobj = document.getElementById("xdivmasking");   
        waitifrm = document.getElementById("xmaskframe");   
        
        var D = document;                   
        var doc_sw = D.documentElement.scrollWidth;   
        var doc_cw = D.documentElement.clientWidth;                     
        var bdw = (doc_sw>doc_cw)?doc_sw:doc_cw;          	   
    	var doc_height =  Math.max(
        	Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
        	Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
        	Math.max(D.body.clientHeight, D.documentElement.clientHeight)
    	);		  
        waitifrm.style.height = divobj.style.height = doc_height+'px';   
        waitifrm.style.width = divobj.style.width = bdw+'px';     
        waitifrm.style.display = divobj.style.display = "block";   
	  }	
		
	};
}();












// XMLRPC handlers


// handle img_fview
function img_fview(acc_id, img_no) {
	
	if (!acc_id) { 
		document.getElementById('img_fview').innerHTML = "<center><h2>No information</h2></center>";
		return (false); 		
	}	
	        	    
    xmlrpc_call('image_fview', 'public', 'img_fview', {'acc_id' : acc_id, 'img_no' : img_no});   				
    return(false);
}


// handle public  calendar
function load_public_cal(acc_id, start_date, end_date) {
	
	if (!acc_id) { 
		document.getElementById('public_cal').innerHTML = "<center><h2>No information</h2></center>";
		return (false); 		
	}	
	var s_date = (start_date && start_date!='None') ? start_date : '';
	var e_date = (end_date && end_date!='None') ? end_date : '';                    
    var cal_html = '';
        	    
    xmlrpc_call('get_public_cal', 'public', 'public_cal', {'acc_id' : acc_id, 'start_date' : s_date, 'end_date' : e_date});
   				
   	return(false);
}




// load accommodation list in acc viewer panel via XMLRPC	
function viewer_load(acc_types, batch_start) {
		
		var  url = "/XMLRPC/public";
    	var came_from = "/";
    	var xmlrpc = imprt("xmlrpc");    
    	var viewer_service = 'Undefined';   
    	var pane = document.getElementById("preview_pane")
    	var display_cols = 4;
        var display_html = "<table border='0' width='100%' align='center'><tr>";
                	
    	try {
        	viewer_service = new xmlrpc.ServiceProxy(url, ['get_accommodation_panel_data']); 
        
		} catch(e) {
              display_html += "<tr><td><font size='1'>Service unavailable: please try again later</font></td></tr></table>";
              pane.innerHTML = display_html;
              return false;
		}
	    	
    	if (batch_start==null) { batch_start = 0; }
    		
    	var result;
        try {        	
			result = viewer_service.get_accommodation_panel_data(acc_types, batch_start);
        } catch(e) {
        	display_html += "<tr><td><font size='1'>Error:<br />" + e + "</font></td></tr></table>";
        	pane.innerHTML = display_html;
        	return false;
        }
        
        // Generate controls
        if (result['previous_start']!=null) { display_html += "<td valign='top' nowrap='nowrap' align='left' width='17%'><a href='#' onclick=\"viewer_load('"+ acc_types + "', " + result['previous_start'] +"); return false;\"><img align=\"bottom\" src=\"/images/button_view_previous.gif\" border=\"0\" /> <font size=\"2\" color=\"#009C31\"> Last " + result['previous_length'] + "</font></a></td>"; }
        else { display_html += "<td width='17%'><font size='1'>&nbsp;</font></td>"; }
        display_html += "<td valign='top' width='74%' align='center'><font size='1'>" + result['page_links'] + "</font></td>"
        if (result['next_start']!=null) { display_html += "<td valign='top' nowrap='nowrap' align='right' width='17%'><a href='#' onclick=\"viewer_load('"+ acc_types + "', " + result['next_start'] +"); return false;\"><font size=\"2\" color=\"#009C31\"> Next " +  result['next_length'] + " <img align=\"bottom\" src=\"/images/button_view_next.gif\" border=\"0\" /></font></a></td>"; }
		else	 { display_html += "<td width='17%'><font size='1'>&nbsp;</font></td>"; }
		
        display_html += "</tr></table>";
        display_html += "<table border='0' cellspacing='6'>";        
        display_html += "<tr>";
        
        acc_results = result['acc_results']
        
        var col_count = 0;
        for (i=0;i<acc_results.length;i++) {          
          if (acc_results[i]['title']) {
        	col_count++;
        	var a = acc_results[i]; 
        	var sleeps_str = "";
        	if (a['capacity'] > 0) {
        		sleeps_str = "Sleeps " + a['capacity'];
        	}
        	var bedrooms_str = "";
        	if (a['bedrooms'] > 0) {
        		plural = '';        		
        		if (a['bedrooms'] > 1) { plural = 's'; }
        		if (a['capacity'] > 0) { bedrooms_str = " ("; } 
        		bedrooms_str = bedrooms_str + a['bedrooms'] + " bedroom"+plural+")";
        	}
        	acc_title= a['title'].substr(0,22);
        	display_html += "<td valign='top' align='center' nowrap='nowrap'> <a href='" + a['absolute_url'] + "?came_from=" + came_from + "'><img border='0' height='120' width='120' src='"+ a['default_image_url'] + "'><br /><p style='font-size: 55%;  color: #006C35'><b>" + acc_title + "</b><br />" + a['location'] + ", " + a['city'] + "</b><br />" + sleeps_str + bedrooms_str + "</p></a></td>";
        	if (col_count == display_cols) {         		
        		display_html += "</tr><tr>"; 
        		col_count = 0;
        	}        	
          }
        }
        display_html += "</tr></table>";
        
        pane.innerHTML = display_html;
}












// Handle form elements

// Accommodation search form

// partyno field: update min_capacity field if present
function acc_search_form_partyno(partyno) {
	if (document.getElementById('field_min_capacity')) {
		document.getElementById('field_min_capacity').value = partyno;
	}
	
	return false;
}



// handle a data driven select element
function data_select(el_id, method, args) {
	//if (!name_field || !value_field ) { alert('Error: provide field mappings'); return(false); }
	if (!method) { alert('Error: specify data source'); return(false); }
	var element = document.getElementById(el_id);
	if (!element) { alert('Error: select element ('+el_id+') does not exist!'); return(false); }
	
	// empty select options
	element.options.length = 0;	
	var option = document.createElement('option');
	option.setAttribute('value','Loading..');
	option.appendChild(document.createTextNode('Loading..'));
	element.appendChild(option);
	
	// populate select field on callback
	var callback = function (res, err) {		
    	var result = res;    	
    	if (err) { 
    		element.options.length = 0;	
    		var option = document.createElement('option');
    		option.setAttribute('value','Error!');
			option.appendChild(document.createTextNode('Error'));
			element.appendChild(option);
			alert(err);
    	} 
		else {					
			element.options.length = 0;	
			var i=0;
			for (i=0;i<=res.length;i++) {
				var item = res[i];
				var option = document.createElement('option');
				option.setAttribute('value',item[1]);
				option.appendChild(document.createTextNode(item[0]));
				element.appendChild(option);
				if (args['selected']) { 
					if (args['selected']==item[1]) { element.selectedIndex = i; }
				}
			}						
		}
				
	}   	
	result = xmlrpc_service(method,'admin')(args, callback);			
   	return(false);
}




 
 
// return booking duration given start date and end date
function get_duration(start_date, end_date) {

	var a_day = 1000*60*60*24;
	var start = new Date(start_date);
	var end = new Date(end_date);
	
	var days = Math.ceil((end.getTime()-start.getTime())/(one_day));
	
	return(days);
}



// Javascript / Python helpers

// this function allows us to pass python DateTime strings around that will be converted to javascript Date objects
function DateTime(dt_str) {
	
	// split out elements
	var all_array = dt_str.split(' ');
	var date_array = all_array[0].split('/');
	
	// create a js date obj	
	var js_date = new Date();
	js_date.setFullYear(date_array[0]);
	js_date.setMonth(date_array[1]);
	js_date.setDate(date_array[2]);
	
	var time_array = undefined;	
	if (typeof all_array[1] != 'undefined') {
		time_array = all_array[1].split(':');
		js_date.setHours(time_array[0]);
		js_date.setMinutes(time_array[1]);
		js_date.setSeconds(time_array[2]);	
	}
	
	var tz = undefined;
	if (typeof all_array[2] != 'undefined') {
		tz = all_array[2];
		// TODO:: does js Date support TZ info?
	}
	//toLocaleString()
	return(js_date.toLocaleString());
	
}


// to allow values of None when passing Python dicts to to javascript via XMLRPC
// Return undefined instead of None
function None() {
	return undefined;
}





// Helpers for XMLRPC calls

// TODO:: remove non ascii chars (these will break an XMLRPC call)
function strip_non_ascii(t){   
  // parse t into arrays
  var t1 = (t.split(''));
  var t2 = [];
  for(i=0; i<t.length; i++) {
  	t2[i] = t.charCodeAt(i);
  }
  // copy arrays
  u1 = t1
  u2 = t2  
  u2[i] = 169; u2[i+1] = 188; u2[i+2] = 189;   // add special characters
  for(i=0; i<u2.length; i++) { 
  	u += String.fromCharCode(u2[i]);
  }
  var v = u;
  u1 = (u.split(''));
  alert('u = '+u+'\nu1 = '+u1+'\nu2 = '+u2); 
  //document.write("u = "+u+"<br>u1 = "+u1+"<br>u2 = "+u2+"<br><br>");   //return
  // t arrays are < 128.  u arrays are > 128. Now test for > 128
  //test the character representations 
  /*for(i=0; i<t2.length; i++) if(t2[i] <= 128) t3++ 
  if(t3 != t2.length) alert(t3-t2.length +" characters more than 128"); else alert(false)
  for(i=0; i<u2.length; i++) if(u2[i] >= 128) u3++
  if(u3 == u1.length) alert(true); else alert(u3+" characters more than 128")*/
}



//   a formulator form and return an empty list if passed or a list of error dicts if failed
// usage: validate_form(<relative_path_to_zope_formulator_instance>, <html_id_or ref_to_form>)
function validate_form(formulator_path,form,disable_errors) {
    
    // accept a ref to a form element or a string for "form_el" arg
    var form_el = form;        
    if (typeof(form_el)=='string') { form_el = document.getElementById(form); }    
        
    var args = {};    
    for (i = 0; i < form_el.length; i++) {
      var el_name = form_el.elements[i].name;
      var el_value = form_el.elements[i].value;      
      // extact the forumlator fields only
      if (el_name.substring(0,9)=='subfield_' || el_name.substring(0,6)=='field_') {
      	args[el_name] = el_value;      	
      }
  	}  	
    var result = undefined;            
    // validate via XMLRPC method
	result = xmlrpc_service('form_validator', 'public')(formulator_path, args);
	// mark each error on the form if required
	if (! disable_errors) {
		// hide all error markers
		for (item_index = 0; item_index < result.form_items.length; item_index++) {			
			error_img = document.getElementById('error_field_'+result.form_items[item_index]);
			if (error_img) {
				error_img.style.display = 'none';
			}
		}				
		if (result.errors.length) { 
		  // mark each form error
		  var error_msg = 'Error - please check the following values: \n\n';
		  for (er_index = 0; er_index < result.errors.length; er_index++) {
			var error_img = undefined;
			var field_error_msg = result.errors[er_index]['field_title'] + ": " + result.errors[er_index]['error_msg'];
			error_img = document.getElementById('error_field_'+result.errors[er_index]['field_id']);
			if (error_img) {
				error_img.src = "/images/error_bullet.gif";
				error_img.title = field_error_msg;
				error_img.style.display = 'block';
				error_img.onclick = function() { alert(field_error_msg); };
			}
			error_msg +=  field_error_msg + "\n";
      	  }
      	  // alert(error_msg); // this is annoying as users has to acknowledge dialog
      	  result['error_txt'] = error_msg;
  	}  	}
	return(result);
}


// Generic call to an xmlrpc method that returns html to an element
function xmlrpc_call(method, folder, display_el_id, args) {
    	
    var result = undefined;
    var display_el = undefined;        
    if (display_el_id && document.getElementById(display_el_id)) {
		display_el = document.getElementById(display_el_id);
		if (display_el) {
			display_el.setAttribute('class','transparent');
			display_el.setAttribute('className','transparent');
			// show progress icon 
			//progress_msg = "Loading..";
			//if (typeof(args['progress_msg']) != 'undefined') { progress_msg = args['progress_msg']; }
			//display_el.innerHTML = "<table width='100%' height='100%'><tr><td align='center' valign='top'><img src='/images/load-anim.gif' border='0' /><h2>" + progress_msg + "</h2></td></tr></table>";
			//var loader_div = document.createElement('div');
			//loader_div.id = 'loader';
			//loader_div.innerHTML="<table width='100%' height='100%'><tr><td align='center' valign='top'><img src='/images/load-anim.gif' border='0' /><h2>" + progress_msg + "</h2></td></tr></table>";
			//display_el.parentNode.appendChild(loader_div);
			//TODO:set timeout + display error			
		}
    }					    
    var callback = function (res, err) {    			
    	var result = res;
    	if (err) {     		
    		result = "Error: " +err;
    		// TODO::handle errors for the unauthencated 
    	} 
		
		if (display_el) {
			display_el.setAttribute('class','');
			display_el.setAttribute('className','');
			display_el.innerHTML = result;
		} 
	}   
	
	// strip non ascii characters from args (else XMLRPC call will fail)
	for (a=0; a<=args.length; a++) {
		//args[a] = escape(args[a]);
		
	}
	
	result = xmlrpc_service(method, folder)(args, callback);    
	return(false);
}


// return a reference to an XMLRPC service (method)
function xmlrpc_service(method_id, folder) {
	if (!folder) { folder = 'public'; }
	var url = "/XMLRPC/" + folder;
	var xmlrpc = imprt("xmlrpc");
	var xmlrpc_service = undefined;				    	
        
    // connect to service
   	try {
       	xmlrpc_service = new xmlrpc.ServiceProxy(url, [method_id]);
	} catch(e) {				
		alert("Service not available");		
	}	
	
	return xmlrpc_service[method_id]		
}

