// webapps.js - implement shared JS for managing articles and user msgs
//
// NOTE:  This file must be in utf-8 encoding!
//
// V1.0 - 2007-11-07
// V1.1 - 2008-12-3: support LoadObjValueAsync() to apply msg to value attr; add global var _openwinBaseUrl for _openwin()
// V1.2 - 2009-01-15: move fcns shared by site pages from ET site template
// V1.2.1 - 2009-02-12: handle full http:// URLs in _openwin()
// V1.2.2 - 2010-04-28: add Popup()

var parseObjTpl, parsedResultContainer, nextAsyncFunc;
var _openwinBaseUrl = '';		// V1.1

// Locate DOM element by its ID. Adopted from MM_findobj v4.01
function findObj(n, d) {
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}   /* findObj */

function validateForm() {
  var i,p,q,nm,test,num,min,max,errors='',args=validateForm.arguments;
  for (i=0; i<(args.length-2); i+=3) { test=args[i+2]; val=findObj(args[i]);
    if (val) { nm=val.name; if ((val=val.value)!="") {
      if (test.indexOf('isEmail')!=-1) { p=val.indexOf('@');
        if (p<1 || p==(val.length-1)) errors+='- 電郵地址不正確。\n';
      } else if (test!='R') { num = parseFloat(val);
        if (isNaN(val)) errors+='- 數字欄位輸入不正確。\n';
        if (test.indexOf('inRange') != -1) { p=test.indexOf(':');
          min=test.substring(8,p); max=test.substring(p+1);
          if (num<min || max<num) errors+='- '+nm+' 的值必須介乎 '+min+' 和 '+max+' 之間。\n';
    } } } else if (test.charAt(0) == 'R') errors += '- 必須輸入有 * 的欄位。\n'; }
  } if (errors) alert('發生以下錯誤：\n'+errors);
  document._returnValue = (errors == '');
}   /*validateForm */

// Cleanup tasks when all Ajax handling has finished (or timed out)
function cleanupAjax()
{
  curAjaxHandling = "";
}   /* cleanupAjax */

// Return the 1st child of given element identified by given tag name
function getFirstChild(element, tagname)
{
  return element.getElementsByTagName(tagname).item(0).firstChild;
}   /* getFirstChild */

// Return the value of the 1st child of given element identified by given tag name
function getFirstChildValue(element, tagname)
{
  return getFirstChild(element, tagname).data;
}   /* getFirstChildValue */

// Jump to photo album index page
function GotoPhotos(fto_php)
{
  url = fto_php+'?tag='+randFtoTag;
  goToURL('parent',url);
}   /* GotoPhotos */

function goToURL() { //v3.0
  var i, args=goToURL.arguments; document.MM_returnValue = false;
  for (i=0; i<(args.length-1); i+=2) eval(args[i]+".location='"+args[i+1]+"'");
}

// Handle return from AJAX call to LoadMsgAsync.
function HandleLoadMsgAjaxReturn()
{
  try  {
    var xmlResponse = xmlHttp.responseXML;
    xmlRoot = xmlResponse.documentElement;
    result = getFirstChildValue (xmlRoot, "result");
    if (result == "OK") {
	  msg = xmlRoot.getElementsByTagName('msg').item(0).firstChild.data;
	  if (msg == '')
	    html = '';
	  else {
	    html = new String(parseObjTpl);
	    html = html.replace('[msg]', msg);
	  }
    } else
	  html = '';
  } catch (e) {
    xmlHttpError = "Error: "+ e.toString();
	html = '';
  }
  if (parsedResultContainer) {
	if (parseObjTpl == '')	// V1.1 - apply to value attr if no tpl
	  parsedResultContainer.value = msg;
	else
	  parsedResultContainer.innerHTML = html;
  }
  if (nextAsyncFunc)
    nextAsyncFunc();
}	/* HandleLoadMsgAjaxReturn */

// Handle return from AJAX call to LoadObjListAsync.
function HandleObjListAjaxReturn()
{
  try  {
    var xmlResponse = xmlHttp.responseXML;
    xmlRoot = xmlResponse.documentElement;
    result = getFirstChildValue (xmlRoot, "result");
    if (result == "OK") {
	  objItemList = xmlRoot.getElementsByTagName('item');
	  html = ParseObjList();
    }
  } catch (e) {
    html = "Error: "+ e.toString();
  }
  if (parsedResultContainer)
	parsedResultContainer.innerHTML = '<p>'+html+'</p>';
  if (nextAsyncFunc)
    nextAsyncFunc();
}	/* HandleObjListAjaxReturn */

// Handle AJAX call timeout
function HandleObjListAjaxTimeout()
{
  xmlHttp.abort();
  xmlHttpError = "Timeout iting for response.";
  clearTimeout(requestTimer);
  curAjaxHandling = '';
  if (nextAsyncFunc)
    nextAsyncFunc();
}   /* HandleObjListAjaxTimeout */

// Load a msg by given script and params.  Put parsed HTML code or error msg using given template code to targetObjId.
function LoadMsgAsync(script, params, tpl, targetObjId, nextFunc)
{
  parseObjTpl = tpl;
  if (parsedResultContainer = findObj(targetObjId)) {
    handleServerResponse = HandleLoadMsgAjaxReturn;
    nextAsyncFunc = nextFunc;
	timeoutHandler = _defaultTimeoutHandler;
    loadScriptAsync(script, params);
  }
}	/* LoadMsgAsync */

// Load a list of objects by given script and params.  Return HTML code or error msg using given template code.
function LoadObjList(script, params, tpl)
{
  var msg = loadScriptSync(script, params);
  if (msg == "OK") {
    try  {
      var xmlResponse = xmlHttp.responseXML;
      xmlRoot = xmlResponse.documentElement;
	  objItemList = xmlRoot.getElementsByTagName('item');
	  parseObjTpl = tpl;
	  msg = ParseObjList();
    } catch (e) {
      msg = "Error: "+ e.toString();
    }
  }
  return msg;
}	/* LoadObjList */

// Load a list of objects by given script and params.  Put parsed HTML code or error msg using given template code to targetObjId.
function LoadObjListAsync(script, params, tpl, targetObjId, nextFunc)
{
  parseObjTpl = tpl;
  if (parsedResultContainer = findObj(targetObjId)) {
    handleServerResponse = HandleObjListAjaxReturn;
    nextAsyncFunc = nextFunc;
	timeoutHandler = HandleObjListAjaxTimeout;
    loadScriptAsync(script, params);
  }
}	/* LoadObjListAsync */

// Load a text value by given script and params.  Put value to targetObj.value.
function LoadObjValueAsync(script, params, targetObjId, nextFunc)
{
  LoadMsgAsync(script, params, "", targetObjId, nextFunc);
}	/* LoadObjValueAsync */

// load a random photo from an array generated periodically and returns from randfto.php
function LoadRandPhoto(tn_path)
{
  randFtoIdx = parseInt(Math.random() * RandFtoUrls.length);
  findObj("RandomPhoto").src=tn_path+RandFtoUrls[ randFtoIdx ];
  randFtoTag = RandFtoTags[ randFtoIdx ];
}   /* LoadRandPhoto */

// function to load recommneded list
function LoadReommendedArticles(sitehome)
{
  if (!rec_articles_loaded) {
    curAjaxHandling = 'LoadRecommendedArticles';
    LoadObjListAsync(PATH_RELROOT+'loadfile.php', 'xml='+sitehome+'/best_articles.xml', 
  	 			'<a href="'+PATH_RELROOT+'view.php?doc=[id]" title="[recommend] 次" class="bullets_in">[name]</a>', 'recommend_articles', cleanupAjax);
		rec_articles_loaded = true;
	}
}   /* LoadReommendedArticles */

// Load a script by given params.  Return error msg or "OK" if success (xmlHttp.responseXML contains the XML data)
function loadScriptSync(script, params)
{
  if (xmlHttp) {
    try  {  // submit to given program
      xmlHttp.open("POST", script, false);	// sync rather than AJAX
      xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      xmlHttp.send(params);

      var xmlResponse = xmlHttp.responseXML;
	  result = checkXmlStructure(xmlResponse);
	  if (result != "") {
		return "Error: "+ result;
	  } else {
        xmlRoot = xmlResponse.documentElement;
        result = getFirstChildValue (xmlRoot, "result");
	    return result;
	  }
    } catch (e) {
      return "Exception: "+ e.toString();
    }
  }
  return "Error: No xmlHttp object.";
}	/* loadScriptSync */

// function to load recommneded list
function LoadTopArticles(sitehome)
{
  if (!top_articles_loaded) {
    curAjaxHandling = 'LoadTopArticles';
    LoadObjListAsync(PATH_RELROOT+'loadfile.php', 'xml='+sitehome+'/top_articles.xml', 
		  '<a href="'+PATH_RELROOT+'view.php?doc=[id]" title="[cnt] 次" class="bullets_in">[name]</a>', 'top_articles', cleanupAjax);
		top_articles_loaded = true;
	}
}   /* LoadTopArticles */

// function to load weather info
function LoadWeatherOnce()
{
  if (!weather_loaded) {
    LoadWeather(Location, YahooCode);
		weather_loaded = true;
	}
}   /* LoadWeatherOnce */

// function to load recommneded list
function LoadWmNotice()
{
  curAjaxHandling = 'LoadWmNotice';
  LoadMsgAsync(PATH_RELROOT+'loadfile.php', 'msg=wm_announce', '<p class="wm_announce">[msg]</p>', 'wm_announcement', cleanupAjax);
}   /* LoadWmNotice */

// Open a window with URL and given size
function OpenMovieWin(theURL)
{
  _openwin(theURL, 'moviewin', 'width=450,height=370');
}   /* OpenMovieWin */

// Open a window with given params
function _openwin(theURL, winName, features)
{
  if ((theURL.substring(0,1) != '/') && (theURL.substring(0,5) != 'http:') && (theURL.substring(0,4) != 'ftp:'))
    window.open(_openwinBaseUrl+theURL, winName, features);
  else
    window.open(theURL, winName, features);
}   /* _openwin */

// Open a window with given URL and window size
function OpenWin(theURL, w, h)
{
  _openwin(theURL, "_blank", 'width='+w+',height='+h);
}   /* OpenWin */

// Parse the list of objects in objItemList.  Return HTML code or error msg using parseObjTpl as template code.
function ParseObjList()
{
  try  {
	msg = '';
	for (var i=0;  i<objItemList.length;  i++) {
	  obj = objItemList.item(i);
	  html = new String(parseObjTpl);
	  html = html.replace('[cnt]', obj.getAttribute('cnt'));
	  html = html.replace('[id]', obj.getAttribute('id'));
	  html = html.replace('[name]', obj.firstChild.data);
	  html = html.replace('[recommend]', obj.getAttribute('recommend'));
	  msg += html;
	}
  } catch (e) {
	msg = "Error: "+ e.toString();
  }
  return msg;
}	/* ParseObjList */

// Hide/unhide a block with given id (state = 'show' or 'hide')
function Popup(id, state)
{
  _MM_showHideLayers(id, '', state);
}	/* Popup */

	// internal fcn for Popup() only
	function _MM_showHideLayers() { //v9.0
	  var i,p,v,obj,args=_MM_showHideLayers.arguments;
	  for (i=0; i<(args.length-2); i+=3) 
	  with (document) if (getElementById && ((obj=getElementById(args[i]))!=null)) { v=args[i+2];
		if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v=='hide')?'hidden':v; }
		obj.visibility=v; }
	}

var art_recommended=false;

// Recommend guven article and disable the button
function RecommendArticle(rel_root, aid, button)
{
  if (xmlHttp)	// ajax.js should be loaded already
	  if (art_recommended)
	    alert('已收到您的讚賞，謝謝!!!');
	  else {
		xmlHttp.abort();
		xmlHttp.open("POST", rel_root+'msg_submit.php', true);
		xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		xmlHttp.send('recommend=art'+aid);
		// No iting for return...
		art_recommended = true;
		if (button) {
		  button.value = ' 謝謝讚賞!!! ';
		  button.style.background = '#CCFFCC';
		}
	  }
}   /* RecommendArticle */

// Set text content of given HTML element obj
function SetInnerText(obj, txt) {
  var hasInnerText = (document.getElementsByTagName("body")[0].innerText != undefined)
  if(hasInnerText){
    obj.innerText = txt;
  } else{
    obj.textContent = txt;
  }
}

// function to set parameters for retrival of online weather data later
function SetWeatherCodes(loc, code)
{
  findObj('WeatherBox').style.display = 'block';
  Location = loc;
  YahooCode = code;
}   /* SetWeatherCodes */

// Toggle display of given list box div (show if new state = true).  Return new state.
// function to sp showing of link/element with id xxx_link/xxx respectively.  show=true to show the element and hink the link.
function ToggleElementDisplay(element, show)
{
  if (show) {
    findObj(element+'_link').style.display = 'none';
  findObj(element).style.display = 'inline';
  } else {
    findObj(element+'_link').style.display = 'inline';
  findObj(element).style.display = 'none';
  }
}   /* ToggleElementDisplay */

function ToggleListbox(box, state)
{
	state = !state;
	findObj(box+"_clickimg").src = PATH_RELROOT+"image/arrow_"+(state ? "up.gif" : "dn.gif");
  findObj(box).style.display = (state ? 'block' : 'none');
  return state;
}   /* ToggleListbox */

// End of file
