function populateCloseDayLink() {
	var table = document.getElementById("days-table");
	var noOfRows = table.rows.length;
	var lastRow = null;
	var lastRowIndex = 0;
	for (var i=noOfRows-1; i>=0; i--) {
		lastRow = table.rows[i];
		lastRowIndex = i;
		if (lastRow.className != "space")
			break;
	}
	var rowCells = lastRow.cells;
	var disabled = false;
	for (var i=rowCells.length-1; i>=0; i--) {
		if (rowCells[i].className == "day_disabled") {
			if (lastRowIndex == 0) return;
		}
		else if (rowCells[i].className == "day") {
			addCloseDayLink (rowCells[i]);
			return;
		}
	}	
}

function disableLastDay (row) {
	for (var i=row.cells.length-1; i>=0; i--) {
		if (row.cells[i].className == "day") {
			row.cells[i].className = "day_disabled";
			return;
		}
	}
}

function addCloseDayLink (cell) {
	var divTags = cell.getElementsByTagName ("div");
	for (var i=0; i<divTags.length; i++) {
		if (divTags[i].id == "day-box") {
			divTags[i].className = "";
		}
	}	
}

function removeCloseDayLink (cell) {
	var divTags = cell.getElementsByTagName ("div");
	for (var i=0; i<divTags.length; i++) {
		if (divTags[i].id == "day-box") {
			divTags[i].className = "not-last";
		}
	}	
}

function InitializeDay (cell) {
	var ulTags = cell.getElementsByTagName ("ul");
	for (var i=0; i<ulTags.length; i++) {
		ulTags[i].innerHTML = "";
	}
}

function updateDayCountDisplay() {
	var daysTable = document.getElementById("days-table");
	var rowCells = daysTable.tBodies[0].rows[0].cells;
	var days = [];
	for (var i=0; i<rowCells.length; i++) {
		if (rowCells[i].className == "day")
			days.push(rowCells[i]);
	}
	var dayCount = days.length;
	//update in the display element
	document.getElementById("dayCountDisplay").innerHTML = dayCount+"("+curFirstDay+"-"+curLastDay+")";
}

function closeDay2() {
	var ans = confirm("Are you sure? Added sites (if any) will be removed!");
	if (!ans)
		return;
	var daysTable = document.getElementById("days-table");
	var row = daysTable.tBodies[0].rows[0];
	var rowCells = row.cells;
	var days = [];
	for (var i=0; i<rowCells.length; i++) {
		if (rowCells[i].className == "day")
			days.push(rowCells[i]);
	}
	var noOfDays = days.length;
	//scroll the days
	if (daysScrollPrev() == false)
		curLastDay--;
	
	//delete the last day (i.e. last day td)
	row.removeChild(days[noOfDays-1]);
	noOfDays--;


	//populate close day link on the prev day - but not on the first day
	if (row.cells.length > 1) {
		addCloseDayLink(days[noOfDays-1]);
	}

	//update the daycount display
	updateDayCountDisplay();
}

function closeDay() {
	var ans = confirm("Are you sure? Added sites (if any) will be removed!");
	if (!ans)
		return;
	var table = document.getElementById("days-table");
	var noOfRows = table.rows.length;
	var lastRow = null;
	var lastRowIndex = 0;
	for (var i=noOfRows-1; i>=0; i--) {
		lastRow = table.rows[i];
		lastRowIndex = i;
		if (lastRow.className != "space")
			break;
	}
	var rowCells = lastRow.cells;
	var disabled = false;
	for (var i=rowCells.length-1; i>=0; i--) {
		if (rowCells[i].className == "day_disabled") {
//			alert ("diabled td found");
			disabled = true;
		}
		else if (rowCells[i].className == "day") {
			if (disabled == true) {
//				alert("disabled is true ... so deleting row");
				table.deleteRow(lastRowIndex);
				break
			}
			else {
				InitializeDay(rowCells[i]);
				rowCells[i].className = "day_disabled";
				break;
			}
		}
	}
	// add close day link in the previous day
	populateCloseDayLink();	
}

function getNextId(id) {
	var nid = Number(id.substring(3));
	nid++;
	return "day"+nid;
}

var curFirstDay = 1;	//first display day
var curLastDay = 1;		//last display day

function daysScrollNext(showLatest) {
	if (typeof(showLatest) == 'undefined')
		showLatest = false;
	var daysTable = document.getElementById("days-table");
	var rowCells = daysTable.tBodies[0].rows[0].cells;
	var days = [];
	for (var i=0; i<rowCells.length; i++) {
		if (rowCells[i].className == "day")
			days.push(rowCells[i]);
	}
	var x=0, y=0;
	var temp = curFirstDay;
	if ((days.length - temp+1) > 3) {
		x = 3;
		if (showLatest) {
			x = (days.length - temp);
		}
		for (var i=temp-1,c=1; c<=(x-3)+1; i++,c++) {
			days[i].style.visibility = "hidden";
			days[i].style.display = "none";
			curFirstDay++;
		}
		temp = i;
	}
	for (var i=temp-1+1; i<days.length && y<3; i++) {
//		var dayNumber = Number(days[i].id.split("_")[1]);
		if (days[i].style.visibility == "hidden") {
			days[i].style.visibility = "visible";
			days[i].style.display = "";
			curLastDay++;
		}
		y++;
	}
	//update the daycount display
	updateDayCountDisplay();
}

function daysScrollPrev() {
	var daysTable = document.getElementById("days-table");
	var rowCells = daysTable.tBodies[0].rows[0].cells;
	var days = [];
	for (var i=0; i<rowCells.length; i++) {
		if (rowCells[i].className == "day")
			days.push(rowCells[i]);
	}
	if ((curLastDay - 1+1) > 3) {
		days[curFirstDay-1-1].style.visibility = "visible";
		days[curFirstDay-1-1].style.display = "";
		days[curLastDay-1].style.visibility = "hidden";
		days[curLastDay-1].style.display = "none";
		curFirstDay--;
		curLastDay--;

		//update the daycount display
		updateDayCountDisplay();
		return true;
	}

	//update the daycount display
	updateDayCountDisplay();
	return false;
}

function addDay2() {
	var daysTable = document.getElementById("days-table");
	var rowCells = daysTable.tBodies[0].rows[0].cells;
	var days = [];
	for (var i=0; i<rowCells.length; i++) {
		if (rowCells[i].className == "day")
			days.push(rowCells[i]);
	}

	// getting the td of the latest day
	var oldLastDayTD = days[days.length-1];

	//cloning the latest day and appending
	var newDayTD = oldLastDayTD.cloneNode(true);
	daysTable.tBodies[0].rows[0].appendChild(newDayTD);
	
	//removing closedaylink on the latest day
	removeCloseDayLink(oldLastDayTD);
	//adding closedayLink on the new day
	addCloseDayLink(newDayTD);
	
	//making the newtd style hidden - default for every new day added
	newDayTD.style.visibility = "hidden";
	newDayTD.style.display = "none";
	
	// getting the date from the latest day
	var ele = newDayTD.getElementsByTagName ("td");
	for (var j=0; j<ele.length; j++) {
		if (ele[j].id == "date") {
			latDate = Number (ele[j].innerHTML);
		}
		else if (ele[j].id == "day") {
			latDay = ele[j].innerHTML;
		}
		else if (ele[j].id == "month") {
			temp = ele[j].innerHTML;
		}
	}
	var ulTags = newDayTD.getElementsByTagName("ul");
	id = ulTags[0].id;
	
	// calculating the next date and next id
	var tempArray = new Array();
	tempArray = temp.split(' ');
	latMonth = tempArray[0];
	latYear = tempArray[1];
	var date = new Date();
	date.setFullYear(latYear);
	date.setMonth(getMonthIndex(latMonth));
	date.setDate(latDate);
	date = getNextDate(date);
	var nextId = getNextId (id);
	
	//setting the new calculated date and id
	for (var j=0; j<ele.length; j++) {
		if (ele[j].id == "date") {
			ele[j].innerHTML = date.getDate();
		}
		else if (ele[j].id == "day") {
			ele[j].innerHTML = GS_days[date.getDay()];
		}
		else if (ele[j].id == "month") {
			ele[j].innerHTML = GS_months[date.getMonth()]+" "+date.getFullYear();
		}
	}
	InitializeDay (newDayTD);
	ulTags[0].id = nextId;
	
	//making the ul sortable
	makeSortable();
	
	//reset the day note
	resetDayNote(newDayTD);
	
	//move the scroll
	daysScrollNext(true);
	
	//update the daycount display
	updateDayCountDisplay();
}

function addDay() {
	var table = document.getElementById("days-table");
	var noOfRows = table.tBodies[0].rows.length;
	var lastRow = null;
	for (var i=noOfRows-1; i>=0; i--) {
		lastRow = table.tBodies[0].rows[i];
		if (lastRow.className != "space")
			break;
	}
	var rowCells = lastRow.cells;
	for (var i=0; i<rowCells.length; i++) {
		if (rowCells[i].className == "day_disabled") {
			rowCells[i].className = "day";
			addCloseDayLink (rowCells[i]);
			GroupCreateGroup();
			makeSortable();
			resetDayNote(rowCells[i]);
			return;
		}
		else if (rowCells[i].className == "day") {
			removeCloseDayLink (rowCells[i]);
		}
	}
	
	// Even no. of days present. Add a row to the day-table
	var newRow = lastRow.cloneNode(true);
	table.tBodies[0].appendChild(newRow);
	var latDate,latMonth, latYear, latDay, temp, id;
	for (var i=newRow.cells.length-1; i>0; i--) {
		if (newRow.cells[i].className == "day") {
//			var date = newRow.getElementById("date");
//			alert(date[0].innerHTML);
			var ele = newRow.cells[i].getElementsByTagName ("td");
			for (var j=0; j<ele.length; j++) {
				if (ele[j].id == "date") {
					latDate = Number (ele[j].innerHTML);
				}
				else if (ele[j].id == "day") {
					latDay = ele[j].innerHTML;
				}
				else if (ele[j].id == "month") {
					temp = ele[j].innerHTML;
				}
			}
			var ulTags = newRow.cells[i].getElementsByTagName("ul");
			id = ulTags[0].id;
			break;
		}
	}
	var tempArray = new Array();
	tempArray = temp.split(' ');
	latMonth = tempArray[0];
	latYear = tempArray[1];
//	var nextDate = getNextDate (latDate, latMonth, latYear, latDay);
	var date = new Date();
	date.setFullYear(latYear);
	date.setMonth(getMonthIndex(latMonth));
	date.setDate(latDate);
	date = getNextDate(date);
	var nextId = getNextId (id);
	for (var i=0; i<newRow.cells.length; i++) {
		if (newRow.cells[i].className == "day") {
			var ele = newRow.cells[i].getElementsByTagName ("td");
			for (var j=0; j<ele.length; j++) {
				if (ele[j].id == "date") {
					ele[j].innerHTML = date.getDate();
				}
				else if (ele[j].id == "day") {
					ele[j].innerHTML = GS_days[date.getDay()];
				}
				else if (ele[j].id == "month") {
					ele[j].innerHTML = GS_months[date.getMonth()]+" "+date.getFullYear();
				}
			}
			InitializeDay (newRow.cells[i]);
			var ulTags = newRow.cells[i].getElementsByTagName("ul");
			ulTags[0].id = nextId;
			date = getNextDate (date);
			nextId = getNextId (nextId);
		}
	}
	for (var i=0; i<newRow.cells.length; i++) {
		if (newRow.cells[i].className == "day") {
			addCloseDayLink(newRow.cells[i]);
			break;
		}
	}
	disableLastDay(newRow);
	resetDayNote(newRow);
	
	// Edit className to not-last in the prev last day
	var divTags = lastRow.getElementsByTagName ("div");
	for (var i=0; i<divTags.length; i++) {
		if (divTags[i].id == "day-box") {
			divTags[i].className = "not-last";
		}
	}
	GroupCreateGroup();
	makeSortable();
}

function GSDate1 (date_, month_, year_, day_) {
	this.date = date_;
	this.month = GS_months[month_-1];
	this.year = year_;
	this.day = GS_days[day_-1];
}
function getShortMonthIndex (month) {
	switch (month) {
	case "Jan":
		return 0;
	case "Feb":
		return 1;
	case "Mar":
		return 2;
	case "Apr":
		return 3;
	case "May":
		return 4;
	case "Jun":
		return 5;
	case "Jul":
		return 6;
	case "Aug":
		return 7;
	case "Sep":
		return 8;
	case "Oct":
		return 9;
	case "Nov":
		return 10;
	case "Dec":
		return 11;
	}	
}
function getMonthIndex (month) {
	switch (month) {
	case "January":
		return 0;
	case "February":
		return 1;
	case "March":
		return 2;
	case "April":
		return 3;
	case "May":
		return 4;
	case "June":
		return 5;
	case "July":
		return 6;
	case "August":
		return 7;
	case "September":
		return 8;
	case "October":
		return 9;
	case "November":
		return 10;
	case "December":
		return 11;
	}	
}
function getNextDay (day) {
	switch(day) {
	case "Monday":
		return "Tuesday";
	case "Tuesday":
		return "Wednesday";
	case "Wednesday":
		return "Thursday";
	case "Thursday":
		return "Friday";
	case "Friday":
		return "Saturday";
	case "Saturday":
		return "Sunday";
	case "Sunday":
		return "Monday";
	}
}
function getNextMonth (month) {
	switch (month) {
	case "January":
		return "February";
	case "February":
		return "March";
	case "March":
		return "April";
	case "April":
		return "May";
	case "May":
		return "June";
	case "June":
		return "July";
	case "July":
		return "August";
	case "August":
		return "September";
	case "September":
		return "October";
	case "October":
		return "November";
	case "November":
		return "December";
	case "December":
		return "January";
	}
}

function getNextDate(date) {
	date.setDate(date.getDate()+1);
	return date;
}

function makeSortable () {
	var table = document.getElementById("days-table");
	var rows = table.rows;
	var idArray = new Array();
	for (var i=0; i<rows.length; i++) {
		for (var j=0; j<rows[i].cells.length; j++) {
			if (rows[i].cells[j].className == "day") {
				var ulTags = rows[i].cells[j].getElementsByTagName("ul");
				if (ulTags.length != 1) {
					alert("some error");
					return;
				}
				idArray.push(ulTags[0].id);
			}
		}
 	}
	var i=1;
	while (true) {
		var id = "draggable_"+i++;
		var ele = document.getElementById(id);
		if (ele == null || i>20)
			break;
		idArray.push(id);
	}
//	idArray.push("drag_container");
	for (var i=0; i<idArray.length; i++) {
		if (idArray[i].search("draggable_") == -1) {
			Sortable.create(idArray[i],{tree:true, dropOnEmpty:true, handle:'drag_it', containment:idArray, constraint:false, scroll:window, onUpdate:function(element){GSTrip.UpdateGroup(element);}});
		}
	}
}

function deleteSite(o) {
	var parentlinode = GSJSLib.Misc.parentNode(o, "li");
	parentlinode.parentNode.removeChild(parentlinode);
}

function popupSiteDetails(siteid) {
	var url = "/SiteInfoString.action?id="+siteid;
	var text = GSJSLib.Ajax.LoadTEXT (url);
	var xmlDoc = GSJSLib.XML.parseXMLString (text);
	var siteid, sitename, siteurl, sitedesc;
	var site = xmlDoc.firstChild;
	siteid = site.getAttribute("id");
	siteurl = site.getAttribute("url");
	sitename = site.getAttribute("name");
/*	var childNodes = xmlDoc.childNodes;
	for (var i=0; i<childNodes.length; i++) {
		alert(childNodes[i].nodeName);
		if (childNodes[i].nodeType == "ATTRIBUTE_NODE") {
			var nodeName = chidlNodes[i].nodeName;
			var nodeValue = childNodes[i].nodeValue;
			if (nodeName == "id")
				siteid = nodeValue;
			else if (nodeName == "name")
				sitename = nodeValue;
			else if (nodeName == "url")
				siteurl = nodeValue;
		}
	}
*/	sitedesc = xmlDoc.getElementsByTagName("desc")[0].childNodes[0].nodeValue;
		
	var imageSRC = "/image.action?id="+siteid+"&type=t";
	var siteHTML = "<div class=\"close\"><img title=\"Close\" src=\"/images/site-details-close.png\" onclick=\"Effect.SwitchOff('site-details-pop-up'); return false;\" /></div>	<table class=\"details-table\"><tr><td class=\"thumbnail\"><img src=\""+imageSRC+"\" /></td><td class=\"details\"><table><tr><td class=\"site-name\">"+sitename+"</td></tr><tr><td class=\"desc\">"+sitedesc+"</td></tr><tr><td class=\"cat\"></td></tr></table></td></tr></table><div class=\"links\"><ul><li><a target=\"_blank\" href=\""+siteurl+"#userReviews"+"\" >read reviews</a></li><li><a target=\"_blank\" href=\""+siteurl+"\" >more</a></li></ul></div>";
	var div = $('site-details-pop-up');
	if (null==div) {
		div = document.createElement('div');
		div.id = "site-details-pop-up";
		div.style.left=((document.body.offsetWidth-450)/2)+'px';
		div.style.top=((document.body.offsetHeight-300)/2)+'px';
		document.body.appendChild(div);
	}
	div.innerHTML = siteHTML;
	Effect.Appear('site-details-pop-up');
	window.scrollTo(0,0);
}

var GS_months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var GS_days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
function TripStartDate(sDate, format) {
	var tempD = GSJSLib.Misc.getDateFromString(sDate,"DD/MM/YYYY");
	if (tempD == null) {
		alert("Please select a valid date");
		return;
	}
	var date = tempD;
//	var arr = sDate.split("/");
//	var date = new Date();
//	date.setFullYear(arr[2]);
//	date.setMonth(arr[1]-1);
//	date.setDate(arr[0]);
	var daysTable = document.getElementById("days-table");
	var rowCells = daysTable.tBodies[0].rows[0].cells;
	var days = [];
	for (var i=0; i<rowCells.length; i++) {
		if (rowCells[i].className == "day")
			days.push(rowCells[i]);
	}
	
	for (var i=0; i<days.length; i++) {
		var ele = days[i].getElementsByTagName("td");
		for (var j=0; j<ele.length; j++) {
			if (ele[j].id == "date") {
				ele[j].innerHTML = date.getDate();
			}
			else if (ele[j].id == "day") {
				ele[j].innerHTML = GS_days[date.getDay()];
			}
			else if (ele[j].id == "month") {
				ele[j].innerHTML = GS_months[date.getMonth()]+" "+date.getFullYear();
			}
		}
		date = getNextDate (date);
	}
}

/**
 * Ajax implementation for populating search suggestions in addDestinations Page (create CTrip)
 * @param element
 * @return
 */
function populateSearchSuggestions (element) {
	var ele = document.getElementById("search-suggestions");
	var ulTags = ele.getElementsByTagName ("ul");
	var ulTag;
	for (var i=0; i<ulTags.length; i++) {
		if (ulTags[i].id == "search-results-ui") {
			ulTag = ulTags[i];
			ulTag.innerHTML = "<img src=\"/images/loading-arrows.gif\" />";
			break;
		}
	}
	var queryString = element.value;
	var url = "/DestinationsString.action?q="+queryString;
	var text = GSJSLib.Ajax.LoadTEXT (url);		// format: <destinationid>:<destinationname>|<destinationid>:<destinationname>
	ulTag.innerHTML = "";
	if (text != "") {
		var sites = text.split('|');	// format: <destinationid>:<destinationname>
		for (var i=0; i<sites.length; i++) {
			var site = sites[i].split(':');
			var siteid = site[0];
			var sitename = site[1];
			sitename = sitename.replace(queryString, "<b>"+queryString+"</b>");
			var newLi = document.createElement ("li");
			newLi.innerHTML = "<p class=\"suggest-link\" onclick=\"Effect.Fade('search-suggestions', {duration: 0.0});populateSites("+siteid+")\" onmouseover=\"this.className='suggest-link-over'\" onmouseout=\"this.className='suggest-link'\">"+sitename+"</p>";
			ulTag.appendChild(newLi);
		}
		Effect.Appear ('search-suggestions', {duration: 0.0});
	}
	else {
		Effect.Fade ('search-suggestions', {duration: 0.0});
	}
}

/**
 * Ajax implementation for populating sites in addDestinations Page (create CTrip)
 * @param element
 * @return
 */
function populateSites (destid) {
	var ele = document.getElementById("div_drag_container");
	
	var url = "/SitesString.action?id="+destid;
	Effect.Appear ("fetch-loading", {duration:0.0});
	var text = GSJSLib.Ajax.LoadTEXT (url);		// format: 
	Effect.Fade ("fetch-loading", {duration:0.0});
	ele.innerHTML = "<table id=\"drag_container\">"+text+"</table>";

	GSTrip.InitializeGroup('drag_container');
	eval('GroupCreateGroup()');
//	Sortable.create('draggable',{tag:'li',handle:'drag_it',constraint:false,ghosting:true,scroll:window, onUpdate:function(element){GSTrip.UpdateGroup(element);}});
	makeSortable();
}

/**
 * Following strings are used as names for hidden fields:
 * Note: sitesListString, noteString, id, type - dont reuse for different purposes
 * @param form
 * @param id - trip id if updating a trip, else should not be used , should be undefined
 * @return
 */
function createTripSubmit (form) {
	with (form) {
		var tempD = GSJSLib.Misc.getDateFromString(startDate.value,"DD/MM/YYYY");
		if (tempD == null) {
			alert("Please select a valid date");
			return;
		}
	}
	var table = document.getElementById("days-table");
	var rows = table.rows;
	var hiddenString = "";
	var noteString = "";
	var curDay = 0;
	for (var i=0; i<rows.length; i++) {
		for (var j=0; j<rows[i].cells.length; j++) {
			if (rows[i].cells[j].className == "day") {
				curDay++;
				hiddenString += curDay+":";
				var ulTags = rows[i].cells[j].getElementsByTagName("ul");
				if (ulTags.length != 1) {
					alert("some error");
					return;
				}
				var liTags = ulTags[0].getElementsByTagName("li");
				for (var k=0; k<liTags.length; k++) {
					hiddenString += liTags[k].id;
					if ((k+1) != liTags.length)
//						hiddenString += "|";
//					else
						hiddenString += ",";
				}
				hiddenString += "|";
				var divTags = rows[i].cells[j].getElementsByTagName("div");
				var note, st_s, st_a, st_e;
				for (var k=0; k<divTags.length; k++) {
					if (divTags[k].id == "save-note") {
						st_s = divTags[k].className;
						if (st_s == "show") {
							alert ("Some notes are unsaved. Please save and proceed");
							return;
						}
    					var note = divTags[k].getElementsByTagName ("textarea")[0].value;
					}
				}
				if (note == "<gs_empty>" || note == "<gs_day_break>") {
					alert ("Invalid Input");
					return;
				}
				if (note == "")
					note = "<gs_empty>";
				noteString += note;
				noteString += "<gs_day_break>";
			}
		}
 	}
	hiddenString = hiddenString.substring(0,hiddenString.length-1);			//
	var el = document.createElement ("input");
	el.type = "hidden";
	el.name = "sitesListString";
	el.value = hiddenString;
	var el2 = document.createElement ("input");
	el2.type = "hidden";
	el2.name = "noteString";
	el2.value = noteString;
	form.appendChild (el);
	form.appendChild (el2);
	form.submit();
}

/**
 * AJAX implementation of discussion form in the showtrip page
 * only 3 max posts can be shown... so delete the old post when a new post is posted
 */
var DiscussionFormSmall = {
		form: null,
		displayElement: null,
		requestSent: function() {
		},
		requestInProcess: function() {
		},
		requestComplete: function(responseXML) {
			if (responseXML == "not_logged") {
				alert ("Please login to post a discussion");
				return;
			}
			else if (responseXML == "error") {
				alert ("Unknown Error. Please try again later");
				return;
			}
			/*
			 * xmlString format
			 * <comment id="" username="" time="">commentString</comment>
			 */
			var xmlDoc = GSJSLib.XML.parseXMLString (responseXML);
			var commentid, username, userid, time, commentString, userurl;
			var comment = xmlDoc.firstChild;
			commendid = comment.getAttribute ("id");
			username = comment.getAttribute ("username");
			time = comment.getAttribute ("time");
			userid = comment.getAttribute ("userid");
			userurl = "/traveller/"+userid+"/profile";		// hard coded ... can find a better solution
			commentString = comment.childNodes[0].nodeValue;
			var div = document.createElement ("div");
			div.className = "post";
			div.innerHTML = "<p class=\"post-header\"><span class=\"link\"><a href=\""+userurl+"\">"+username+"</a></span><span class=\"hinttext\">at "+time+"</span></p><p class=\"post-text\">"+commentString+"</p>"; 
			var ele = document.getElementById ("latestDiscPosts");
			var size = ele.getElementsByTagName ("div").length;
			if (document.getElementById ("no-discussion") != null) {
				if (size >= 4) {
					var temp = ele.getElementsByTagName ("div")[1];
					ele.removeChild (temp);
				}
				document.getElementById ("no-discussion").className = "hide";
			}
			else {
				if (size >= 3) {
					var temp = ele.getElementsByTagName ("div")[0];
					ele.removeChild (temp);
				}
			}
			ele.appendChild (div);
			this.form.elements[0].value = "write another comment ...";
		},
		getParameters: function() {
			var params = "";
			var elements = this.form.elements;
			for (var i=0; i<elements.length; i++) {
				params += elements[i].name+"="+elements[i].value;
				if ((i+1) != elements.length)
					params += "&";
			}
			return params;
		},
		SubmitForm: function(form) {
			this.form = form;
			var url = "/CTripAddDiscussion.action";
			GSJSLib.Ajax.SubmitForm (url, this);
		}
};

/**
 * AJAX Implementation of discussion form in the discussion board page
 * all the posts are shown ... so no deleting of the posts
 */
var DiscussionFormBig = {
		form: null,
		displayElement: null,
		requestSent: function() {
		},
		requestInProcess: function() {
		},
		requestComplete: function(responseXML) {
			if (responseXML == "not_logged") {
				alert ("Please login to post a discussion");
				return;
			}
			else if (responseXML == "error") {
				alert ("Unknown Error. Please try again later");
				return;
			}
			/*
			 * xmlString format
			 * <comment id="" username="" time="">commentString</comment>
			 */
			var xmlDoc = GSJSLib.XML.parseXMLString (responseXML);
			var commentid, username, userid, time, commentString, userurl;
			var comment = xmlDoc.firstChild;
			commendid = comment.getAttribute ("id");
			username = comment.getAttribute ("username");
			userid = comment.getAttribute ("userid");
			userurl = "/traveller/"+userid+"/profile";		// hard coded ... can find a better solution
			time = comment.getAttribute ("time");
			commentString = comment.childNodes[0].nodeValue;
			var div = document.createElement ("div");
			div.className = "post";
			div.innerHTML = "<p class=\"post-header\"><span class=\"link\"><a href=\""+userurl+"\">"+username+"</a></span><span class=\"hinttext\">at "+time+"</span></p><p class=\"post-text\">"+commentString+"</p>"; 
			var ele = document.getElementById ("latestDiscPosts");
			var size = ele.getElementsByTagName ("div").length;
			if (document.getElementById ("no-discussion") != null) {
				document.getElementById ("no-discussion").className = "hide";
			}
			ele.appendChild (div);
			this.form.elements[0].value = "write another comment ...";
		},
		getParameters: function() {
			var params = "";
			var elements = this.form.elements;
			for (var i=0; i<elements.length; i++) {
				params += elements[i].name+"="+elements[i].value;
				if ((i+1) != elements.length)
					params += "&";
			}
			return params;
		},
		SubmitForm: function(form) {
			this.form = form;
			var url = "/CTripAddDiscussion.action";
			GSJSLib.Ajax.SubmitForm (url, this);
		}
};

/**
 * AJAX Implementation of sending invitations for joining a trip.
 */
var InvitationForm = {
		form: null,
		displayElement: null,
		requestSent: function() {
		},
		requestInProcess: function() {
		},
		requestComplete: function(responseText) {
			if (responseText != "success")
				this.displayElement.innerHTML = responseText;
			Effect.Fade("infoTextP1", {duration: 0.0});
			Effect.Appear("infoTextP2", {duration: 0.5});
		},
		getParameters: function() {
			var params = "";
	  	  	var inputs = this.form.getElementsByTagName("textarea");
	  	  	for (var i=0; i<inputs.length; i++) {
	  	  		if (inputs[i].name == "emails")
	  	  			params += "emails="+escape(inputs[i].value);
	  	  		else if (inputs[i].name == "emailText")
	  	  			params += "emailText="+escape(inputs[i].value);
	  	  				
	  	  	  	if ((i+1) != inputs.length)
	  	  	  		params += "&";
	  	  	}
	  	  	inputs = this.form.getElementsByTagName("input");
	  	  	if (inputs.length > 0) params += "&";
	  	  	for (var i=0; i<inputs.length; i++) {
	  	  		if (inputs[i].type == "hidden")
	  	  			params += inputs[i].name+"="+inputs[i].value;
	  	  		else if (inputs[i].type == "checkbox" && inputs[i].checked == true)
	  	  			params += inputs[i].name+"="+inputs[i].value;
	  	  		
	  	  		if ((i+1) != inputs.length)
	  	  			params += "&";
	  	  	}
	  	  	return params;
		},
		SubmitForm: function(form) {
			this.form = form;
			var inputs = form.getElementsByTagName("input");
			var url = "/CTripSendInvite.action";
			Effect.Appear("infoTextP1", {duration: 0.5});
			GSJSLib.Ajax.SubmitForm (url, this);
		}
};

/**
 * AJAX Implementation of Image commenting form
 */
var ImageCommentForm = {
		form: null,
		displayElement: null,
		requestSent: function() {
		},
		requestInProcess: function() {
		},
		requestComplete: function(responseXML) {
			/**
			 * xmlString format
			 * <comment id="" username="" time="">commentString</comment>
			 */
			var xmlDoc = GSJSLib.XML.parseXMLString (responseXML);
			var commentid, username, time, commentString;
			var comment = xmlDoc.firstChild;
			commendid = comment.getAttribute ("id");
			username = comment.getAttribute ("username");
			time = comment.getAttribute ("time");
			commentString = comment.textContent;
			var div = document.createElement ("div");
			div.className = "post";
			div.innerHTML = "<p class=\"post-header\"><span class=\"link\"><a href=\"\">"+username+"</a></span><span class=\"hinttext\">at "+time+"</span></p><p class=\"post-text\">"+commentString+"</p>"; 
			var ele = document.getElementById ("latestDiscPosts");
			var size = ele.getElementsByTagName ("div").length;
			if (document.getElementById ("no-discussion") != null) {
				document.getElementById ("no-discussion").className = "hide";
			}
			ele.appendChild (div);
			this.form.elements[0].value = "write another comment ...";
		},
		getParameters: function() {
			var params = "";
			var elements = this.form.elements;
			for (var i=0; i<elements.length; i++) {
				params += elements[i].name+"="+elements[i].value;
				if ((i+1) != elements.length)
					params += "&";
			}
			return params;
		},
		SubmitForm: function(form) {
			this.form = form;
			var url = "/CTripAddImageComment.action";
			GSJSLib.Ajax.SubmitForm (url, this);
		}
};

/**
 * Populates the dates in the trip itenerary in the showtrip page and tripItinerary page
 */
function populateDates (startDate, startMonth, startYear) {
	var pDate = new Date();
	pDate.setFullYear(startYear);
	pDate.setMonth(getShortMonthIndex(startMonth));
	pDate.setDate(startDate);

	var table = document.getElementById ("days-table");
	for (var i=0; i<table.rows.length; i++) {
		var tdElements = table.rows[i].getElementsByTagName ("td");
		for (var j=0; j<tdElements.length; j++) {
			if (tdElements[j].className == "date") {
				tdElements[j].innerHTML = "<span>"+pDate.getDate()+"</span>";
			}
			else if (tdElements[j].className == "month") {
				tdElements[j].innerHTML = "<span>"+GS_months[pDate.getMonth()]+" "+pDate.getFullYear()+"</span>";
			}
			else if (tdElements[j].className == "date-day") {
				tdElements[j].innerHTML = "<span>"+GS_days[pDate.getDay()]+"</span>";
			}
		}
		pDate = getNextDate (pDate);
	}
}

/**
 * Implementing closing and opening of the trip itinerary in showtrip page
 */
function itineraryAction (ele, action) {
	var parent = GSJSLib.Misc.parentNode (ele, "td");
	var dayDiv = parent.getElementsByTagName("div")[0].getElementsByTagName("div")[1];
	var tdElements = ele.getElementsByTagName ("td");
	var imageElement;
	for (var i=0; i<tdElements.length; i++) {
		if (tdElements[i].className == "close") {
			imageElement = tdElements[i].getElementsByTagName ("img")[0];
			break;
		}
	}
	Effect.toggle(dayDiv.id, 'slide', {duration: 0.5});
	if (imageElement.className == "hide-details") {
		imageElement.className = "show-details";
		imageElement.title = "Show Details";
		imageElement.alt = "Show Details";
	}
	else {
		imageElement.className = "hide-details";
		imageElement.title = "Hide Details";
		imageElement.alt = "Hide Details";
	}
/*	if (!itineraryShow) {
		Effect.SlideDown (dayDiv.id, { queue: { position: 'end', scope: dayDiv.id }, duration: 0.5 });
		imageElement.className = "hide-details";
		imageElement.title = "Hide Details";
		imageElement.alt = "Hide Details";
		itineraryShow = true;
	}
	else {
		Effect.SlideUp (dayDiv.id, { queue: { position: 'end', scope: dayDiv.id }, duration: 0.5 });
		imageElement.className = "show-details";
		imageElement.title = "Show Details";
		imageElement.alt = "Show Details";
		itineraryShow = false;
	}*/
}

/**
 * Ajax Implementation of adding a trip to user favourites
 * @param url - url to hit for ajax response
 * @param ele - html element concerned
 * @return
 */
function AddToFavourite (url, ele)  {
  	var div = ele;
  	var response = GSJSLib.Ajax.LoadTEXT (url);
  	if (response == "success") {
  	  	div.innerHTML = "Successfully Added";
  	}
  	else if (response == "failure") {
  	  	div.innerHTML = "Sorry! Cannot Add to Favourites at this moment. Please try again later";
  	}
  	else if (response == "denied") {
  	  	div.innerHTML = "You seems to be a trip member. Cannot add to your favourites list";
  	}
  	else if (response == "not_logged") {
  	  	div.innerHTML = "Please login to add to your favourite list";
  	}
  	else if (response == "duplicate") {
  	  	div.innerHTML = "Trip is already in your favourites list";
  	}
  	else {
  	  	div.innerHTML = "Sorry! Cannot Add to Favourites at this moment. Please try again later";
  	}
//  	div.className = "show";
  	Effect.Appear (div.id, {duration: 0.5});
  	GSJSLib.Effects.Fade (div.id, 2000);
}

/**
 * Ajax Implementation of removing a trip from user favourites
 * @param url - url to hit for ajax response
 * @param ele - html element concerned
 * @return
 */
function RemoveFromFavourite (url, ele, tripdivid)  {
  	var div = ele;
  	var response = GSJSLib.Ajax.LoadTEXT (url);
  	if (response == "success") {
  	  	div.innerHTML = "Successfully Removed";
  	}
  	else if (response == "failure") {
  	  	div.innerHTML = "Sorry! Cannot Remove from the Favourites at this moment. Please try again later";
  	}
  	else if (response == "not_logged") {
  	  	div.innerHTML = "Please login to remove from your favourite list";
  	}
  	else {
  	  	div.innerHTML = "Sorry! Cannot Remove from the Favourites at this moment. Please try again later";
  	}
//  	Effect.Appear (div.id, { queue: { position: 'end', scope: tripdivid }, duration: 0.5 });
//  	Effect.SlideUp (tripdivid, { queue: { position: 'end', scope: tripdivid }, duration: 0.5 });
  	Effect.SlideUp (tripdivid, {duration: 0.5});
//  	GSJSLib.Effects.Fade (div.id, 2000);
}

/**
 * Validates user sign up form on home page and register page
 * @param thisform
 * @return
 */
function validateSignUpForm(thisform) {
	with (thisform)
	{
		if (GSJSLib.FormValidation.ValidateRequiredField(firstName)==false) {
			alert ("First Name can't be blank");
			firstName.focus();return false;
		}
		if (GSJSLib.FormValidation.ValidateRequiredField(lastName)==false) {
			alert ("Last Name can't be blank");
			lastName.focus();return false;
		}
		if (GSJSLib.FormValidation.ValidateRequiredField(userName)==false) {
			alert ("Email can't be blank");
			userName.focus();return false;
		}
		if (GSJSLib.FormValidation.ValidateRequiredField(password)==false) {
			alert ("Password can't be blank");
			password.focus();return false;
		}
		if (GSJSLib.FormValidation.ValidateRequiredField(password_retype)==false) {
			alert ("Password can't be blank");
			password_retype.focus();return false;
		}
		if (GSJSLib.FormValidation.emailCheck(userName.value)==false) {
			alert ("Enter a valid email");
			userName.value="";
			userName.focus();
			return false;
		}
		if (password.value != password_retype.value) {
			alert("Passwords should match");
			password_retype.focus();
			return false;
		}
	}
	return true;
}  

/**
 * Validates user sign in form on home page and login page
 * @param thisform
 * @return
 */
function validateLoginForm(thisform) {
	with (thisform) {
		if (GSJSLib.FormValidation.ValidateRequiredField(userName)==false) {
			alert("Email can't be blank");
			userName.focus();return false;
		 }
		if (GSJSLib.FormValidation.ValidateRequiredField(password)==false) {
			alert("Password can't be blank");
			password.focus();return false;
		}
	}
	return true;
}

/**
 * Validates Facebook user sign up form on home page and register page
 * @param thisform
 * @return
 */
function validateFBSignUpForm(thisform) {
	with (thisform)
	{
		if (GSJSLib.FormValidation.ValidateRequiredField(firstName)==false) {
			alert ("First Name can't be blank");
			firstName.focus();return false;
		}
		if (GSJSLib.FormValidation.ValidateRequiredField(lastName)==false) {
			alert ("Last Name can't be blank");
			lastName.focus();return false;
		}
		if (GSJSLib.FormValidation.ValidateRequiredField(userName)==false) {
			alert ("Email can't be blank");
			userName.focus();return false;
		}
		if (existingmember.checked){
			if (GSJSLib.FormValidation.ValidateRequiredField(passwd)==false) {
				alert ("Password can't be blank");
				passwd.focus();return false;
			}
		}else{
			if (GSJSLib.FormValidation.ValidateRequiredField(password)==false) {
				alert ("Password can't be blank");
				password.focus();return false;
			}
			if (GSJSLib.FormValidation.ValidateRequiredField(password_retype)==false) {
				alert ("Password can't be blank");
				password_retype.focus();return false;
			}
			if (password.value != password_retype.value) {
				alert("Passwords should match");
				password_retype.focus();
				return false;
			}
		}
		if (GSJSLib.FormValidation.emailCheck(userName.value)==false) {
			alert ("Enter a valid email");
			userName.value="";
			userName.focus();
			return false;
		}
	}
	return true;
}  

/**
 * Gets suggestions for destination names from the server - ajax hit
 * @class
 * @scope public
 */
function DestinationSuggestions(query) {
	var url = "/DestinationsString.action?q="+query;
	var response = GSJSLib.Ajax.LoadTEXT (url);		// format: <destinationid>:<destinationname>|<destinationid>:<destinationname>
	return response;
}

/**
 * Request suggestions for the given autosuggest control. 
 * @scope protected
 * @param oAutoSuggestControl The autosuggest control to provide suggestions for.
 */
DestinationSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl /*:AutoSuggestControl*/,
                                                          bTypeAhead /*:boolean*/) {
    var aSuggestions = [];
    var sTextboxValue = oAutoSuggestControl.textbox.value;

    
    if (sTextboxValue.length > 0){
    	suggestions = DestinationSuggestions(sTextboxValue);
	if (suggestions != "") {
		var sites = suggestions.split('|');	// format: <destinationid>:<destinationname>
		for (var i=0; i<sites.length; i++) {
			aSuggestions.push(sites[i]);
		}
	}
    }

    //provide suggestions to the control
    oAutoSuggestControl.autosuggest(aSuggestions, bTypeAhead);
};


/***
 * Mouse position tracker code below ... used to display help text onmouseover
 */
var cX = 0; var cY = 0; var rX = 0; var rY = 0;
function UpdateCursorPosition(e){ cX = e.pageX; cY = e.pageY;}
function UpdateCursorPositionDocAll(e){ cX = event.clientX; cY = event.clientY;}
if(document.all) { document.onmousemove = UpdateCursorPositionDocAll; }
else { document.onmousemove = UpdateCursorPosition; }
function AssignPosition(d) {
	if(self.pageYOffset) {
		rX = self.pageXOffset;
		rY = self.pageYOffset;
	}
	else if(document.documentElement && document.documentElement.scrollTop) {
		rX = document.documentElement.scrollLeft;
		rY = document.documentElement.scrollTop;
	}
	else if(document.body) {
		rX = document.body.scrollLeft;
		rY = document.body.scrollTop;
	}
	if(document.all) {
		cX += rX;
		cY += rY;
	}
	d.style.left = ((cX+10)-(document.body.offsetWidth-960)/2) + "px";
	d.style.top = (cY+10) + "px";
}

function HideText(d) {
	if(d.length < 1) { return; }
	document.getElementById(d).style.display = "none";
}

function ShowText(d) {
	if(d.length < 1) { return; }
	var dd = document.getElementById(d);
	AssignPosition(dd);
	dd.style.display = "block";
}

function ReverseContentDisplay(d) {
	if(d.length < 1) { return; }
	var dd = document.getElementById(d);
	AssignPosition(dd);
	if(dd.style.display == "none") { dd.style.display = "block"; }
	else { dd.style.display = "none"; }
}

/************************
 * End of mouse tracker code
 */


/*************************
 * Rating stars code
 */
var selectedRatingRate = 0;
var selectedRatingReview = 0;
var defaultRateImgSrc = "http://static.guidingshadow.com/images/star-grey-empty.png";
var rateImgSrc = "http://static.guidingshadow.com/images/star-grey-full.png";
var ratedImgSrc = "http://static.guidingshadow.com/images/star-black-full.png";

var GS_RateTexts = ["", "Poor", "Not Bad", "Good", "Excellent", "Must Visit"];

function highlightImg(no, type, ref) {
	var name = "";
	if (type == 'review') {
		name = "reviewImg";
	}
	else if (type == 'rate') {
		name = "rateImg";
	}else{
		name = type;
	}
	var k = Number(no)+1;
	for (var j=k; j<=5; j++) {
		var imgId = name+j;
		document.getElementById(imgId).src = defaultRateImgSrc;
	}
	for (var i=no; i>0; i--) {
		var imgId = name+i;
		document.getElementById(imgId).src = rateImgSrc;
	}
	var rating = Number(no);
	GSJSLib.Misc.parentNode(ref, "td").getElementsByTagName("span")[0].innerHTML = GS_RateTexts[rating];
}
function lowLightImg(type, ref) {
	var name = "";
	var selectedRating ;
	if (type == 'review') {
		name = "reviewImg";
		selectedRating = selectedRatingReview;
	}
	else if (type == 'rate') {
		name = "rateImg";
		selectedRating = selectedRatingRate;
	}else{
		name = type;
		selectedRating = document.getElementById(type+"-rating").value ;
	}
	for (var j=1; j<=selectedRating; j++) {
		var imgId = name+j;
		document.getElementById(imgId).src = ratedImgSrc;
	}
	var k = Number(selectedRating)+1;
	for (var i=k; i<=5; i++) {
		var imgId = name+i;
		document.getElementById(imgId).src = defaultRateImgSrc;
	}
	GSJSLib.Misc.parentNode(ref, "td").getElementsByTagName("span")[0].innerHTML = GS_RateTexts[selectedRating];
}
function rate(no, type) {
	var name = "";
	if (type == 'review') {
		name = "reviewImg";
		selectedRatingReview = no;
		document.getElementById("freviewRating").value = no;
	}
	else if (type == 'rate') {
		name = "rateImg";
		selectedRatingRate = no;
		document.getElementById("frateRating").value = no;
	}else{
		name = type;
		document.getElementById(type+"-rating").value = no;
	}
	for (var i=1; i<=no; i++) {
		var imgId = name+i;
		document.getElementById(imgId).src = ratedImgSrc;				
	}
}



