/*
 * Returns a new XMLHttpRequest object, or false if this browser
 * doesn't support it
 */
function newXMLHttpRequest() {

  var xmlreq = false;

  if (window.XMLHttpRequest) {

    // Create XMLHttpRequest object in non-Microsoft browsers
    xmlreq = new XMLHttpRequest();

  } else if (window.ActiveXObject) {

    // Create XMLHttpRequest via MS ActiveX
    try {
      // Try to create XMLHttpRequest in later versions
      // of Internet Explorer

      xmlreq = new ActiveXObject("Msxml2.XMLHTTP");

    } catch (e1) {

      // Failed to create required ActiveXObject

      try {
        // Try version supported by older versions
        // of Internet Explorer

        xmlreq = new ActiveXObject("Microsoft.XMLHTTP");

      } catch (e2) {

        // Unable to create an XMLHttpRequest with ActiveX
      }
    }
  }

  return xmlreq;
}

function addToFavorites(type,id,userid) {

  // Obtain an XMLHttpRequest instance
  var req = newXMLHttpRequest();

  // Set the handler function to receive callback notifications
  // from the request object
  if(type=='article')
  {
	var handlerFunction = getReadyStateHandler(req, updateFavoriteArticle,"type="+ type+"&userid="+userid);
  }
  else
  {
  	var handlerFunction = getReadyStateHandler(req, updateFavoriteCategory,"type="+ type+"&userid="+userid);
  }
  
  req.onreadystatechange = handlerFunction;

  // Open an HTTP POST connection to the shopping cart servlet.
  // Third parameter specifies request is asynchronous.
  req.open("POST", "favorites.do", true);

  // Specify that the body of the request contains form data
  req.setRequestHeader("Content-Type", 
                       "application/x-www-form-urlencoded");

  // Send form encoded data stating that I want to add the 
  // specified item to the cart.
  req.send("action=add&type="+type+"&id="+id+"&userid="+userid);
  
  //updateFavoritesBox(type,userid);
}

/*
 * Returns a function that waits for the specified XMLHttpRequest
 * to complete, then passes its XML response to the given handler function.
 * req - The XMLHttpRequest whose state is changing
 * responseXmlHandler - Function to pass the XML response to
 */
function getReadyStateHandler(req, responseXmlHandler,args) {

  // Return an anonymous function that listens to the 
  // XMLHttpRequest instance
  return function () {

    // If the request's status is "complete"
    if (req.readyState == 4) {
      // Check that a successful server response was received
      if (req.status == 200) {
        // Pass the XML payload of the response to the 
        // handler function
        responseXmlHandler(req.responseXML,args);
      } else {

        // An HTTP problem has occurred
        alert("HTTP error: "+req.status);
      }
    }
  }
}

function updateFavoriteArticle(favoritesXml,args)
{
	var fav = favoritesXml.getElementsByTagName("favorite")[0].firstChild.nodeValue;
	if(fav=='true')
	{
		document.getElementById("makefavorite").innerHTML = "this article is now a favorite!";
	}
	updateFavoritesBox(args);
}

function updateFavoriteCategory(favoritesXml,args)
{
	var fav = favoritesXml.getElementsByTagName("favorite")[0].firstChild.nodeValue;
	if(fav=='true')
	{
		document.getElementById("makefavorite").innerHTML = "this category is now a favorite!";
	}
	updateFavoritesBox(args);
}

function updateFavoritesBox(args)
{
	// the args argument is appended to the query string
	var req = newXMLHttpRequest();

	var handlerFunction = getReadyStateHandler(req, updatesFavoritesDisplay);
	req.onreadystatechange = handlerFunction;
	req.open("POST", "favorites.do", true);
	req.setRequestHeader("Content-Type", 
	                       "application/x-www-form-urlencoded");
	req.send("action=update&" + args);
}

function updatesFavoritesDisplay(favoritesXml)
{
	var html = "";
	var fav = favoritesXml.getElementsByTagName("favorites")[0];
	
	var userId = fav.getAttribute("userid");
	var items = fav.getElementsByTagName("item");	
	var q = "";
	if(fav.getAttribute("type")=='article')
	{
		q = "a";
	}
	else
	{
		q = "c";
	}
	html = "<table width=\"100%\">";
	for(var i=0;i<items.length;i++)
	{
		var item = items[i];
		var count = i + 1;
		var id = item.getElementsByTagName("id")[0].firstChild.nodeValue;
		
		var title = item.getElementsByTagName("title")[0].firstChild.nodeValue;
		html += "<tr><td valign=\"top\" width=\"25\"><span class=\"small\" style=\"color:orange;font-weight:bold;\">" + count + ".</span></td>";
		html += "<td><span class=\"small\"><a href=\"" + fav.getAttribute("type")+ ".jsp?" +q + "=" + id + "\">" + title + "</a></span></td>";
		html += "<td valign=\"top\" class=\"small\" align=\"right\"><a href=\"javascript:deleteFavorite('" + userId + "','" + id + "','" + fav.getAttribute("type")+ "')\">delete</a></td>";
	}
	html += "</table>";
	if(fav.getAttribute("type")=='article')
	{
		document.getElementById("favoritearticles").innerHTML = html;
	}
	else
	{
		document.getElementById("favoritecategories").innerHTML = html;
	}
	
}

function rateArticle(userid,articleid,categoryid,rating)
{
	var req = newXMLHttpRequest();
	var handlerFunction = getReadyStateHandler(req, updateRatingHandler);
	req.onreadystatechange = handlerFunction;
	req.open("POST", "rate.do", true);
	req.setRequestHeader("Content-Type", 
                       "application/x-www-form-urlencoded");
	req.send("userid="+userid+"&a="+articleid+"&c="+categoryid+"&rating="+rating);
}

function updateRatingHandler(ratingXml)
{
	var value = ratingXml.getElementsByTagName("rating")[0].firstChild.nodeValue;
	if(value=='true')
	{
		document.getElementById("rating").innerHTML = "thank you for rating this article";
	}
}


function deleteFavorite(userid,id,type)
{
	var req = newXMLHttpRequest();
	var handlerFunction = getReadyStateHandler(req, deleteFavoriteHandler,"type="+type+"&userid="+userid);
	req.onreadystatechange = handlerFunction;
	req.open("POST", "favorites.do", true);
	req.setRequestHeader("Content-Type", 
	                       "application/x-www-form-urlencoded");
	req.send("action=delete&type="+type+"&userid="+userid+"&id="+id);
	
	//updateFavoritesBox(type,userid);
}

function deleteFavoriteHandler(favoriteXml,args)
{
	updateFavoritesBox(args);
}

function showEmail(userId,articleId)
{
	var html = "<table width=\"100%\"><tr><td class=\"titleSecondary\"><table cellpadding=0 cellspacing=0 style=\"font-family:Verdana;font-size:10pt;font-weight:bold;color:white\" width=\"100%\"><tr><td>email this article to your friend(s)</td><td align=\"right\"><a style=\"text-decoration:none;color:white\" href=\"javascript:hideEmail()\">x</a>&nbsp;</td></tr></table></td></tr>";
	html += "<tr><td class=\"panelSecondary\"><form name=\"emailFriend\"><span class=\"small\"><b>email address:&nbsp;</b><input type=\"text\" size=\"50\" name=\"addresses\" id=\"addresses\"></br>";
	html += "<p>separate up to 5 email addresses by commas</p>";
	html += "<b>message:&nbsp;</b></br>";
	html += "<textarea name=\"body\" rows=8 cols=50></textarea></form>";
	html += "<p><span id=\"sendButton\"><a class=\"highlight\" href=\"javascript:sendEmail(" + userId + "," + articleId + ",'addresses','body')\">send&gt;&gt;</a></span></p>";
	html += "</span></td></tr></table>";
	var email = document.getElementById("email");
	email.innerHTML = html;
	email.style.visibility = 'visible';
	fade("email",'10','5','95');
}

function fade(element,step,opacity,limit)
{
	var item = document.getElementById(element).style;
	if(item.MozOpacity == limit/100) // has to be exact or this will fail
	{
		if(item.MozOpacity == 0)
		{
			document.getElementById(element).innerHTML = "";
			item.visibility = "hidden";
		}
		return;
	}
	
	item.MozOpacity = opacity/100;
	var newOpacity = step/1 - 0 + opacity/1;
	var call = "fade('" + element + "'," + step + "," + newOpacity + "," + limit + ")";
	//alert(call);
	setTimeout(call,1);
	//alert(step + ", " + limit + "," + item.MozOpacity);
	
}

function hideEmail()
{
	fade("email",'-15','90','0');
	//document.getElementById("email").innerHTML = "";
	//document.getElementById("email").style.visibility = "hidden";
}

function sendEmail(userId,articleId,toField,emailBody)
{
	document.getElementById("sendButton").innerHTML = "sending...";
	var addresses = document.emailFriend[toField].value;
	addresses = addresses.replace(new RegExp(/;/g),",");
	var addressArray = addresses.split(",");
	var check = true;
	var badAddresses = "";
	var address2 = "";
	for(var i=0; i<addressArray.length; i++)
	{
		var address = addressArray[i];
		if(!emailCheck(address))
		{
			check = false;
			badAddresses += address + ",";
		}
	}
	if(!check)
	{
		alert("There is a problem with the emailaddress[es] " + badAddresses.substring(0,badAddresses.length-1) + ". Please check the format and retry.");
		document.emailFriend[toField].focus();
		return;
	}
	body = document.emailFriend[emailBody].value;
	emailFriends(userId,articleId,addresses,body);
}

function askToLogin(div)
{
	document.getElementById(div).innerHTML = "you must login or register to save favorites or email articles";
}


function emailFriends(userId,articleId,addresses,body)
{
	var req = newXMLHttpRequest();
	var handlerFunction = getReadyStateHandler(req, emailFriendsHandler,userId + "," + articleId);
	req.onreadystatechange = handlerFunction;
	req.open("POST", "emailfriend.do", true);
	req.setRequestHeader("Content-Type", 
	                       "application/x-www-form-urlencoded");
	var sendString = "userid="+userId+"&articleid="+articleId+"&addresses="+addresses+"&body="+body;
	req.send(sendString);
	
}

function emailFriendsHandler(emailFriendXml,args)
{
	var value = emailFriendXml.getElementsByTagName("emailfriend")[0].firstChild.nodeValue;
	if(value=='true')
	{
		var html = "<table width=\"100%\"><tr><td class=\"titleSecondary\"><table cellpadding=0 cellspacing=0 style=\"font-family:Verdana;font-size:10pt;font-weight:bold;color:white\" width=\"100%\"><tr><td>email this article to your friend(s)</td><td align=\"right\"><a style=\"text-decoration:none;color:white\" href=\"javascript:hideEmail()\">x</a>&nbsp;</td></tr></table></td></tr>";
		html += "<tr><td class=\"panelSecondary\"><p class=\"highlight\">your email has been sent!  send another or <a href=\"javascript:hideEmail()\">close</a> this window.</p><form name=\"emailFriend\"><span class=\"small\"><b>email address:&nbsp;</b><input type=\"text\" size=\"50\" name=\"addresses\" id=\"addresses\"></br>";
		html += "<p>separate up to 5 email addresses by commas</p>";
		html += "<b>message:&nbsp;</b></br>";
		html += "<textarea name=\"body\" rows=8 cols=50></textarea></form>";
		var argArray = args.split(",");
		html += "<p><span id=\"sendButton\"><a class=\"highlight\" href=\"javascript:sendEmail(" + argArray[0] + "," + argArray[1] + ",'addresses','body')\">send&gt;&gt;</a></span></p>";
		html += "</span></td></tr></table>";
		var email = document.getElementById("email");
		email.innerHTML = html;
	}
	else
	{
		alert("There was a problem sending your email.  We apologize for the inconvenience.");
	}
}



function emailCheck (emailStr) {
/* The following pattern is used to check if the entered e-mail address
   fits the user@domain format.  It also is used to separate the username
   from the domain. */
var emailPat=/^(.+)@(.+)$/
/* The following string represents the pattern for matching all special
   characters.  We don't want to allow special characters in the address. 
   These characters include ( ) < > @ , ; : \ " . [ ]    */
var specialChars="\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
/* The following string represents the range of characters allowed in a 
   username or domainname.  It really states which chars aren't allowed. */
var validChars="\[^\\s" + specialChars + "\]"
/* The following pattern applies if the "user" is a quoted string (in
   which case, there are no rules about which characters are allowed
   and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
   is a legal e-mail address. */
var quotedUser="(\"[^\"]*\")"
/* The following pattern applies for domains that are IP addresses,
   rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
   e-mail address. NOTE: The square brackets are required. */
var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
/* The following string represents an atom (basically a series of
   non-special characters.) */
var atom=validChars + '+'
/* The following string represents one word in the typical username.
   For example, in john.doe@somewhere.com, john and doe are words.
   Basically, a word is either an atom or quoted string. */
var word="(" + atom + "|" + quotedUser + ")"
// The following pattern describes the structure of the user
var userPat=new RegExp("^" + word + "(\\." + word + ")*$")
/* The following pattern describes the structure of a normal symbolic
   domain, as opposed to ipDomainPat, shown above. */
var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$")


/* Finally, let's start trying to figure out if the supplied address is
   valid. */

/* Begin with the coarse pattern to simply break up user@domain into
   different pieces that are easy to analyze. */
var matchArray=emailStr.match(emailPat)
if (matchArray==null) {
  /* Too many/few @'s or something; basically, this address doesn't
     even fit the general mould of a valid e-mail address. */
	return false;
}
var user=matchArray[1]
var domain=matchArray[2]

// See if "user" is valid 
if (user.match(userPat)==null) {
    // user is not valid
    return false;
}

/* if the e-mail address is at an IP address (as opposed to a symbolic
   host name) make sure the IP address is valid. */
var IPArray=domain.match(ipDomainPat)
if (IPArray!=null) {
    // this is an IP address
	  for (var i=1;i<=4;i++) {
	    if (IPArray[i]>255) {
		return false;
	    }
    }
    return true
}

// Domain is symbolic name
var domainArray=domain.match(domainPat)
if (domainArray==null) {
    return false;
}

/* domain name seems valid, but now make sure that it ends in a
   three-letter word (like com, edu, gov) or a two-letter word,
   representing country (uk, nl), and that there's a hostname preceding 
   the domain or country. */

/* Now we need to break up the domain to get a count of how many atoms
   it consists of. */
var atomPat=new RegExp(atom,"g")
var domArr=domain.match(atomPat)
var len=domArr.length
if (domArr[domArr.length-1].length<2 || 
    domArr[domArr.length-1].length>3) {
   // the address must end in a two letter or three letter word.
  // alert("The address must end in a three-letter domain, or two letter country.")
   return false;
}

// Make sure there's a host name preceding the domain.
if (len<2) {
  // var errStr="This address is missing a hostname!"
   //alert(errStr)
   return false;
}

// If we've gotten this far, everything's valid!
return true;
}

