/*toggle visibility of an element given ID
-- blog/archive

*/

function toggle(id) {
    var p = getElement(id);	
(computedStyle(p,'display')=='none')?showElement(p):hideElement(p);
    return true;
}
/* change status bar at the bottom
-- blog/archive
 */
function viewMsg(evt) {
    if (evt.eventType == 'onmouseover') {
        window.status = "Preview";
        return true;
    }
    else if (evt.eventType == 'onmouseout') {
        window.status = "";
        return true;
    }
    else
        return false;
}

/* does a dom update a soon as possible */
function schedule(objectID, functionCall)
{
	if (document.getElementById(objectID))
	{
		eval(functionCall);
	}
	else
	{
		setTimeout("schedule('" + objectID + "', '" + functionCall + "')", 1);
	}
	
	return true;
}

// Use this as the onclick handler of the master checkbox to control
// a group or list of checkboxes. 
// Arguments:
//	master -- the master controller checkbox
//	name   -- the name of every checkbox in the group or list
function checkControl(checkbox, name) {
	var elts = document.getElementsByName(name);
	if (!elts || elts == [])
		return;
	len = elts.length;
	for (var i = 0 ; i < len; i++) {
		elts[i].checked = checkbox.checked;
	}
}

// Uncheck the master when one of the list entry boxes is unchecked.
// Assumes the id of the master checkbox is 'master'
// picker.tmpl, groups.tmpl, list_all.tmpl
function uncheckMaster(checkbox) {
	var master = document.getElementById('master');
	if (!master) return;
	if (checkbox.checked == false) {
		master.checked = false;
	}
}

//Secondary master uncheck that takes ID as an argument.
//Use this for pages that have multiple master checkboxes.
//remember to put the form's ID into the argument of the repeated checkboxes
//see connections/index.tmpl for reference
function uncheckMasterId(checkbox,id) {
	var master = getElement(id);
	if (!master) return;
	if (checkbox.checked == false) {
		master.checked = false;
	}
}

function ghostText(id, text, normalColor, ghostColor) {
	if (normalColor == undefined)
		normalColor = "#575757";

	if (ghostColor == undefined)
		ghostColor = "#ABABAB";

	var input = $(id);
	if (!input) return;
	connect(input, 'onblur', partial(ghostBlur,  ghostColor));
	connect(input, 'onfocus', partial(ghostFocus, normalColor));
	connect(input, 'onsubmit', ghostSubmit);
	input.ghostText = text;
    if(input.value == "" || input.value == text) {
        input.style.color = ghostColor;
        input.value = input.ghostText;
	} else {
        input.style.color = normalColor;
    }
}

function ghostBlur(c, e) {
	if(e.src().value == "") {
		e.src().style.color = c;
		e.src().value = e.src().ghostText;
	}
}

function ghostFocus(c, e) {
	if(e.src().value == e.src().ghostText) {
		e.src().value = "";
		e.src().style.color = c;
	}
}

function ghostSubmit(id) {
    if ( $(id) ) {
    	if($(id).value == $(id).ghostText) {
    		$(id).value = "";
    		$(id).style.color = c;
    	}
	}
}

/* open/close the RSS subscribe menu for directory/listing pages*/
setupRss=function() {
	MochiKit.Signal.connect("rssFeedIcon","onclick",toggleRss);
	MochiKit.Signal.connect("xIcon","onclick",toggleRss);
	MochiKit.Signal.connect("wrapper","onclick",hideRss);
	return false;
}

function toggleRss(e) {
	var rss = getElement( 'syndicationBox' );
	toggleElementClass( 'noDisplay', rss );	
	e.stop();
	return false;
}

function hideRss(e){
	var rss = getElement( 'syndicationBox' );
	setElementClass( rss , 'noDisplay');
}

function nearbyAjax (url) {
	var d = loadJSONDoc(url);
	d.addCallback(function (result) { 
			$('resultList').innerHTML = result["data"];
			//$('resultList').innerHTML += result["gmaplog"];
			markers = result["gmap"].concat(result["newMarkers"]).concat(result["newXMarkers"]);
			frames['gmframe'].ajaxUpdateNearBy(markers);
		});
}

/*
**  Toggle client-side notifiers and server-generated notification snippets
**
*/
function toggleNotify(on) {
    if (! $('js-notify')) return;
    if (on) {
        if ($('mcNotifier'))
            hideElement('mcNotifier');
        removeElementClass('js-notify', 'noDisplay');
        showElement('js-notify');
    } else {
        if ($('mcNotifier'))
            showElement('mcNotifier');
        hideElement('js-notify');
    }
}
/*
** Ajax calls to get reviews from external sites

** Calling template/script must set this to the URL for external reviews
** Parameters: cid company id
**						 site: scraper website name, set to dummy 'XYZ'

** This is all static because of the difficulties of dealing
** with setInterval, whose function argument's arguments are evaluated
** in global scope. I could get around this by using a singleton pattern,
** but WTF.
*/

MC_ExternalReviews =  {
	baseURL : '',
	wsn: '',
	tid : null,
	numdots : 0,
	dots : ['.', '. .', '. . .', '. . . .', '. . . . .'],
	displayName : '',
	reviewListID : 'review-list',
	selectID : 'reviewSite',
	current_site: ''
}

MochiKit.Base.update(MC_ExternalReviews, {

	setBaseURL: function(url) {MC_ExternalReviews.baseURL = url;},
	setWsn : function(wsn) {MC_ExternalReviews.wsn = wsn;},
	searching : function (){
		var s = '<span class="note">Searching for reviews on ' 
				+ MC_ExternalReviews.displayName + '</span>';
		var idx = MC_ExternalReviews.numdots % 5;
		$(MC_ExternalReviews.reviewListID).innerHTML = 
			s + MC_ExternalReviews.dots[idx];
		MC_ExternalReviews.numdots++;
	}, 

	getExternalReviews: function()
	{
		var select = $(MC_ExternalReviews.selectID);
		var site = select.options[select.options.selectedIndex].value;
		MC_ExternalReviews.displayName = 
				select.options[select.options.selectedIndex].text;
		if (MC_ExternalReviews.tid != null) {
			clearInterval(MC_ExternalReviews.tid);
			MC_ExternalReviews.tid = null;
			MC_ExternalReviews.numdots = 0;
		}
		if (site != 'merchantcircle') {
			MC_ExternalReviews.tid = setInterval('MC_ExternalReviews.searching()', 500);
			document.body.style.cursor = 'wait';
		}
		var url = "/ajax/xreviews/" + MC_ExternalReviews.wsn + "/" + site;
		var d = loadJSONDoc(url);
			d.addCallbacks(function (result) { 
				if (MC_ExternalReviews.tid != null) {
					clearInterval(MC_ExternalReviews.tid);
					MC_ExternalReviews.tid = null;
					MC_ExternalReviews.numdots = 0;
					document.body.style.cursor = 'default';
				}
				$(MC_ExternalReviews.reviewListID).innerHTML = result["data"];
			},
			function(result, site) {
				if (MC_ExternalReviews.tid != null) {
					clearInterval(MC_ExternalReviews.tid);
					MC_ExternalReviews.tid = null;
					MC_ExternalReviews.numdots = 0;
					document.body.style.cursor = 'default';
				}
	
				$(MC_ExternalReviews.reviewListID).innerHTML = 
						'<span class="note">There was an error searching ' + 
						MC_ExternalReviews.displayName +
						'. Try again later</span>';
			}
			);
		return false;
	},
	
	autoScrapeExternalReviews: function( site )
	{
		loadJSONDoc("/ajax/xreviews/" + MC_ExternalReviews.wsn + "/local.yahoo.com/1").addCallback(
			function (result) {
				if (result['count'] > 0) {
					$(MC_ExternalReviews.reviewListID).innerHTML = result["data"];
					$(MC_ExternalReviews.selectID).options.selectedIndex =  map(partial(itemgetter('value')),
					 	$(MC_ExternalReviews.selectID).options).indexOf('local.yahoo.com')
				}
			}
		);
	}
});


/*
** For character text limit in textarea fields.
*/

function textLimit(field, maxlen) {
if (field.value.length > maxlen + 1)
if (field.value.length > maxlen)
field.value = field.value.substring(0, maxlen);
}


/*
** JSON namespacing
*/

var mc = {};
mc.app = {};
mc.app.subscriber = function() {};
mc.app.subscriber.prototype = {
	fromSelect:null,
	toSelect:null,
	limit:null,
	limitAction:null,
	nonlimitAction:null,
	init:function (fromSelect,toSelect,limit,limitAction,nonlimitaction) {
		this.fromSelect = fromSelect;
		this.toSelect = toSelect;
		this.limit = limit;
		this.limitAction = limitAction;
		this.nonlimitAction = nonlimitaction;
		var checkCurrent = $(toSelect).options.length;
		if (checkCurrent >= this.limit) {
			this.disableOption(this.fromSelect);
		}
		return this;
	},
	makeOption:function(option) {
		return OPTION({"value": option.value}, option.text);
	},
	moveOption:function( fromSelect, toSelect, check )
	{
		if (check && $('subscribed').options.length >= mcApp.merchant.selector.limit) {
			if (mcApp.merchant.selector.limitAction)
				mcApp.merchant.selector.limitAction();	
			return;
		}
		// mov
		appendChildNodes(toSelect,
		    map( mcApp.merchant.selector.makeOption,
		    	 ifilter(itemgetter('selected'), $(fromSelect).options))
		);

		replaceChildNodes(fromSelect,
			list(ifilterfalse(itemgetter('selected'), $(fromSelect).options))
		);

		updateNodeAttributes($('ids'),
			{'value' : repr(map(itemgetter('value'), $('subscribed').options)) }
		);
		if ($('subscribed').options.length >= mcApp.merchant.selector.limit) {
			mcApp.merchant.selector.disableOption(mcApp.merchant.selector.fromSelect);
		} else {
			mcApp.merchant.selector.enableOption(mcApp.merchant.selector.fromSelect);
			if (mcApp.merchant.selector.nonlimitAction)
				mcApp.merchant.selector.nonlimitAction();
		}
	},
	disableOption: function(fromSelect)
	{
		$(fromSelect).disabled=true;
		$(fromSelect).backgroundColor='#ddd';
	},
	enableOption: function(fromSelect)
	{
		$(fromSelect).disabled=false;
		$(fromSelect).backgroundColor='#fff';		
	}
};


mc.app.ghostText = function() {};
mc.app.ghostText.prototype = {
	_normalColor:null,
	_ghostColor:null,
	_formId:null,
	_fieldId:null,
	_ghostMsg:null,
	_ghostErrMsg:null,
	init: function (formid,fieldid,normalColor,ghostColor,ghostMsg,ghostErrMsg) {
		this._formid = formid;
		this._fieldid = fieldid;
		this._normalColor = normalColor;
		this._ghostColor = ghostColor;
		this._ghostMsg = ghostMsg;
		this._ghostErrMsg = ghostErrMsg;
		return this;
	},
	ghostText: function (id, text, normalColor, ghostColor) {
		if (normalColor == undefined)
			normalColor = "#575757";

		if (ghostColor == undefined)
			ghostColor = "#ABABAB";

		var input = $(id);
		if (!input) return;
		connect(input, 'onblur', partial(mcApp.ghost.ghostBlur,  ghostColor));
		connect(input, 'onfocus', partial(mcApp.ghost.ghostFocus, normalColor));
		input.ghostText = text;
	    if(input.value == "" || input.value == text) {
		input.style.color = ghostColor;
		input.value = input.ghostText;
		} else {
		input.style.color = normalColor;
	    }
	},

	ghostBlur: function (c, e) {
		if(e.src().value == "") {
			e.src().style.color = c;
			e.src().value = e.src().ghostText;
		}
	},

	ghostFocus: function (c, e) {
		if(e.src().value == e.src().ghostText) {
			e.src().value = "";
			e.src().style.color = c;
		}
	},

	ghostSubmit: function (e) {
		if (mcApp.ghost) {
			var id =  mcApp.ghost._fieldid; 
			t = $(id).value;
			//prevent submit event from finishing  
			if (t.match(mcApp.ghost._ghostMsg)) { 
				alert(mcApp.ghost._ghostErrMsg);
				e.stop(); 
				return false;
			}
		}
	}
};


/* Top Nav Bar
**************/

var login = new linkObject("Login","/auth/login",false);
var logout = new linkObject("Logout","/auth/logout",false);
var dash = new linkObject("Merchant Dashboard","/merchant",true);
var invite = new linkObject("Invite","/merchant/invite",true);
var dir = new linkObject("Directory","/directory",true);
var help = new linkObject("Help","/corporate/educenter/index.html",true);
var cpn = new linkObject("Coupons","/coupon-wallet",true);
var website = new linkObject("View My Listing","/r?a=w",true);
var advertise = new linkObject("Advertise with Us", "/corporate/sponsoredListing.html",true);
var cartHref = 'https://' + document.location.host + '/secure/cart'
var cart = new linkObject("Shopping Cart",cartHref,true);

function publicNavBar(){
	var target='extraLinks';
	try {
		getElement(target).innerHTML='';
	}
	catch (err) {
		target="topMenu";
		getElement(target).innerHTML='';
	}

	//logged in user
	if (getSessionUserName()) {
		//dashboard, invite, directory, help, logout
		map(partial(buildLinks,target),[dash,invite,dir,help,logout]);
	}
	//returning user
	else if (getProfileEmail())	{
		//invite, directory, help, login
		map(partial(buildLinks,target),[dir,help,login]);
	}
	//new user
	else {
		//directory, help, coupons, login
		map(partial(buildLinks,target),[dir, advertise, help,login]);
	}
}

function merchantNavBar() {
	var target='miniNav';
	getElement(target).innerHTML='';
	//logged in user
	if (getSessionUserName()) {
		//dashboard, invite, directory, help, logout
		map(partial(buildLinks,target),[website,cart,help,logout]);
		}
	//returning user
	else if (getProfileEmail())	{
		//invite, directory, help, login
		map(partial(buildLinks,target),[help,login]);
		}
	//new user
	else {
		var helpSpecial = new linkObject("Help","/corporate/help.html",false);
		map(partial(buildLinks,target),[helpSpecial]);
	}
}

function linkObject(title,href,divider) {
	this.title=title;
	//this.href=href;
	if (href.search(/https/) == 0) {
	    this.href = href;
	}  else {
	    this.href = 'http://' + document.location.host + href;
	}
	this.divider=divider;
}

//expects object(href) and object(menu)
function buildLinks(target,obj) {
	var a = A({'href':obj.href},obj.title);
	appendChildNodes(target,a);
	if (obj.divider) {
		appendChildNodes(target, ' | ');
	}
}

/* END Top Nav Bar
**************/

/* Picture Flipper
******************/

var flipperBaseUrl;
var displayedPicture = 0;
var displayedPictureIndex = 0;
var imageInfo = null;

function setFlipperBaseUrl(url) {flipperBaseUrl = url;}

function setImageInfo(s) {
	imageInfo = s; 
}

function setDisplayIndex(idx) {
	for (var i = 0; i < imageInfo.length; i++) {
		if (imageInfo[i].id == idx) {
			displayedPictureIndex = i;
			displayedPicture = idx;
			break;
		}	
	}
}

function getImageContent(kind, pindex, selected) {
	var url = flipperBaseUrl;
	var div_id = kind + '_flipper' ;
	url = url.replace(/XX/,div_id);
	if (kind != 'photo') {
		url = url.replace(/photo/, kind);
	}
	if (pindex) {
		url += '/' + pindex;
	}
	if (selected) {
		url += '?selected=' + selected;
		setDisplayIndex(selected);
	}
	var d = loadJSONDoc(url);
   d.addCallback(function (result) { 
			$(div_id).innerHTML = result["data"];
		});
	return false;
}

var has_videos = false;
var has_photos = false;

function setFlags(videos, photos) {
	log('setFlags: videos, photos', videos, photos);
	has_videos = videos > 0;
	has_photos = photos > 0;
}

function initTabs() {
	var photo_tab = $('photo_tab');
	var video_tab = $('video_tab');
	if (has_photos && has_videos) {
		switchTabs('photo');
	} else if (has_photos) {
		photo_tab.innerHTML = 'Photos';
		video_tab.innerHTML = '<span class="inactive">Videos</span>'
		getImageContent('photo', 0);
		$('photo_flipper').style.display = 'block';
		$('video_flipper').style.display = 'none';
	 	displayedPicture = imageInfo[0].id;
		displayedPictureIndex = 0;
		showElement('slideshow_link');
//		hideElement(video_tab);
	} else if (has_videos) {	
		video_tab.innerHTML = 'Videos';
		photo_tab.innerHTML = '<span class="inactive">Photos</span>'
		getImageContent('video', 0);
		$('photo_flipper').style.display = 'none';
		$('video_flipper').style.display = 'block';
		hideElement('slideshow_link');
//		hideElement(photo_tab); 
	} else {
		hideElement(photo_tab); 
		hideElement(video_tab); 
		hideElement(photo_flipper); 
		hideElement(video_flipper); 
		hideElement('slideshow_link');
	}
}

function switchTabs(which) {
	var photo_tab = $('photo_tab');
	var video_tab = $('video_tab');
	getImageContent(which, 0);
	if (which == 'photo') {
		photo_tab.innerHTML = 'Photos';
		var link = A(
			{'href':'javascript:void(0)','onclick':'switchTabs("video")'},
			'Videos');
		replaceChildNodes(video_tab, link);
		$('photo_flipper').style.display = 'block';
		$('video_flipper').style.display = 'none';
	 	displayedPicture = imageInfo[0].id;
		displayedPictureIndex = 0;
		showElement('slideshow_link');
	} else {
		stop();
		video_tab.innerHTML = 'Videos';
		var link = A(
			{'href':'javascript:void(0)','onclick':'switchTabs("photo")'},
			'Photos');
		replaceChildNodes(photo_tab, link);
		$('photo_flipper').style.display = 'none';
		$('video_flipper').style.display = 'block';
		hideElement('slideshow_link');
	}
}
function div_appear(i) {
	var image = imageInfo[i];
	var div = $('highlighted_image');
	var snippet = image.snippet;
	snippet = snippet.replace(/&lt;/g, '<');
	snippet = snippet.replace(/&gt;/g, '>');
	div.innerHTML = snippet;
	MochiKit.Visual.appear(div);		
}

function loadImage(i) {
	var image = imageInfo[i];
	var div = $('highlighted_image');
	if (!div) {
		log("Couldn't find highlighted image div");
		return;
	}
	var snippet = image.snippet;
	snippet = snippet.replace(/&lt;/g, '<');
	snippet = snippet.replace(/&gt;/g, '>');

	MochiKit.Visual.fade(div, {'to':0.1, 'from':1.0});
	
	displayedPictureIndex = i;
	displayedPicture = image.id;
	setTimeout("div_appear(" + i + ")", 1000);
/*
		// Nice, but doesn't work in IE
		function(div, snippet) {
			div.innerHTML = snippet;
			MochiKit.Visual.appear(div);
		}, 1000, div, snippet);
*/
}

function next() {
	var idx = displayedPictureIndex + 1 ;
	if (idx >= imageInfo.length)
			idx = 0;
	loadImage(idx);
}

var lock = new DeferredLock();
var tid;
var stopAnchor = A({'href':'javascript:void(0)','id':"slideshow_link",
									  'class':'extraTabLinkStop'}, "Stop Slideshow");
connect(stopAnchor, 'onclick', stop);
var playAnchor = A({'href':'javascript:void(0)', 'id':"slideshow_link",
									  'class':'extraTabLink'}, "View Slideshow");
connect(playAnchor, 'onclick', play_slideshow);

function play_slideshow() {
	var slink = $('slideshow_link');
	swapDOM(slink, stopAnchor);
	var d = lock.acquire();
	var fired = d.fired;
	if (fired != 0) return;
	next();
	tid = setInterval('next()', 5000);
}

function stop() {
	var slink = $('slideshow_link');
	swapDOM(slink, playAnchor);
	_stop();
}

function _stop() {
	try {
		clearInterval(tid);
	lock.release();
	} catch(e) {
	}
}

//createLoggingPane();

/* END Picture Flipper
******************/

/* Rank
******************/
// This file depends on functions defined in cookie.js

if ( typeof(readCookie) != undefined)
{
	function set_uid() {
		var gProfile = unencodeCookie("P");
		if (!gProfile || !gProfile["p"]) {
			return null;
		} else {
			return gProfile["p"];
		}
	}

	function rate_company_inline(id, rating) {
		var uid = set_uid();
		if (uid != null) {
			var d = loadJSONDoc('/ajax/rank?'+queryString({'uid':uid, 'id':id, 'rating':rating }));
			d.addCallback(function (result) {
				 $('rankContentLinks'+id).innerHTML = result["data"]; }
			);
		}
	}

	function lightStars(id, star, path) {
		if (! path ) {
			path = '/static/img/icons/stars/';
		}
		for (var x=star; x > 0 ; x--) {
			element = 'c'+id + "-" + x;
			$(element).src = path + 'star_red.gif';
		}
	}

	function starMouseOut(id, star, color, path) {
		if (! path ) {
			path = '/static/img/icons/stars/';
		}
		for (var x=star; x > 0 ; x--) {
			element = 'c' + id + "-" + x;
			if ($(element).className == 'star-1') {
				$(element).src =  path + 'star_half.gif';
			}
			else if ($(element).className == 'star-2') {
				$(element).src =  path + 'star.gif';
			}
			else {
				$(element).src =  path + 'star_gray.gif';
			}
		}
	}

	function blankAllStars(id,total) {
		for (var x=1; x<=total; x++) {
			element='c'+id+'-'+x;
			$(element).src = '/static/img/icons/stars/star_gray.gif';
		}
	}
	
	function updateHiddenStars(id, stars, frm) {
	    $(id).value = stars;
	    frm.submit();
	}
}

/* END Rank
******************/

/* from mcGsearch.js
******************/

/* get all the dirt on an object. Probably not a good idea to have a recursive version :)
**
*/
function dirt(o) {
	result = '';
	if (o) {
		for (k in o) {
			result += k + ' = ' + o[k] + "\n";
		}
	}
	return result;
}
var _unescape;
if (typeof (decodeURIComponent)!="undefined") {
    _unescape = decodeURIComponent;
    _escape = encodeURIComponent;
}
else {
    _unescape = unescape;
    _escape = escape;
}

/* 
** Convenience function to get the url of a search item.
*/
function getResultUrl(result) {
	switch (result.GsearchResultClass) {
		case 'GlocalSearch': 
		{
			return _unescape(result.ddUrl);
			break;
		}
		case 'GblogSearch':
		{
			return _unescape(result.postUrl);
			break;
		}
		case 'GwebSearch':
		case 'GvideoSearch':
		case 'GnewsSearch':
		{
			return _unescape(result.url);
			break;
		}
		default: break;
	}
	return null;
}

/*
** Our little Google search item mapper class
*/
function MCSearchResultMap(result) {
	this.title = '';
	this.content = '';
	this.url = '';
	this.phones = '';
	if (result.phoneNumbers) {
		for (i = 0; i < result.phoneNumbers.length; i++) {
			n = result.phoneNumbers[i];
			this.phones += (i>0?'<br/>':'') + n.number + ' (' + n.type + ')';
		}
	}
	if (result.GsearchResultClass) {
		switch (result.GsearchResultClass) {
			case 'GlocalSearch': 
			{
				this.title = result.titleNoFormatting;
				this.content = result.streetAddress + '<br />' +
					result.city + ',' + result.region + '<br />' + this.phones;
				this.url = _unescape(result.ddUrl);
				break;
			}
			case 'GwebSearch':
			{
				this.title = result.titleNoFormatting;
				this.content = result.content;
				this.url = _unescape(result.url);
				break;
			}
			case 'GblogSearch':
			{
				this.title = result.titleNoFormatting;
				this.content = result.content;
				this.url = _unescape(result.postUrl);
				break;
			}
			case 'GnewsSearch':
			{
				this.title = result.titleNoFormatting;
				this.content = result.content;
				this.url = _unescape(result.url);
				break;
			}
			case 'GvideoSearch':
			{
				this.title = result.titleNoFormatting;
				this.content = result.content;
				this.url = _unescape(result.url);
				break;
			}
			default: break;
		}
		this.url_truncated = this.url;
		if (this.url_truncated.length > 50)
			this.url_truncated = this.url_truncated.substring(0,50) + '...';
	}
}
/*
** this is the method that inserts our formatted item. The variable "template" must
** be defined in the calling document, since it's a separate snippet that gets written in.
*/
MCSearchResultMap.prototype.insert = function() {
	var html = '';
	html = template.replace(/%%title%%/, this.title);
	html = html.replace(/%%content%%/, this.content);
	html = html.replace(/%%url%%/g, 'href="' + this.url + '"');
	html = html.replace(/%%url_truncated%%/, this.url_truncated);
	var div = DIV({'class':'infoData'});
	div.innerHTML = html;
	$('gResults').appendChild(div);
}

/*
** The Google AJAX Search API requires an object and a method for search callbacks.
** We also keep track of urls to avoid duplicates and try to avoid recursion.
*/
function Searcher() {
    this.urls = [];
}
// Not sure if this is really needed, since it's not really a lock...
var lock = new MochiKit.Async.DeferredLock();

/*
** The callback function for search completion
*/
Searcher.prototype.sc = function(t) {
	lock.acquire()
	if (t.results) {
	    var m, r, url, kind;
		for (var i = 0; i < t.results.length; i++) {
		    r = t.results[i]; // a GsearchResult object
	        url = getResultUrl(r);
	        if (MochiKit.Base.findValue(this.urls, url) > -1) {
                log('found duplicate', url);
                continue;
            }
	        this.urls.push(url);
			m = new MCSearchResultMap(r);
			kind = r.GsearchResultClass;
			m.insert();
			delete m;
		}
		t.clearResults();
		delete t;
		hideElement('webSearchText');
		hideElement('newsSearchText');
		hideElement('blogSearchText');
		hideElement('videoSearchText');
		hideElement('emptySearchText');
		if (kind) {
		    kind = kind.replace(/^G/, '').replace(/$/, 'Text');
		    showElement(kind);
		} else {
		    showElement('emptySearchText');
		}
	}
	lock.release();
}

function selectOnChange(select, n, c, s ){
    setSearchKind(select.options[select.options.selectedIndex].value, n, c, s);
}
function setSearchKind(kind, cname, city, state)
{
	var searcher;
	if (!$('gResults')) return;
	switch (kind) {
		case 'web': {
			searcher = new GwebSearch();
			break;
		}
		case 'news': {
			searcher = new GnewsSearch();
			break;
		}
		case 'blog': {
			searcher = new GblogSearch();
			break;
		}
		/*
		case 'local':{
			searcher = new GlocalSearch();
			break;
		}
		*/
		case 'video': {
			searcher = new GvideoSearch();
			break;
		}
		default: return;
	}
	replaceChildNodes('gResults', SPAN(' '));
	searcher.setResultSetSize(GSearch.SMALL_RESULTSET);
	searcher.setSearchCompleteCallback(new Searcher(), Searcher.prototype.sc, [searcher]);
	searcher.execute('"' + cname + '" ' + city);
}

/*
** Insert a script node on load which will force the initial gsearch to populate
** the search box. Takes the initial load out of the page onload sequence, makes it
** asynchronous.
**
** It appends a script node to the end of the child list of the <body> node.
** The script that it loads actually runs the search.
** Dependencies:
**      The calling document has a body tag with id = "consumer"
*/
function writeGsearchScriptNode() {
    var body = $('consumer');
    if (!body) return;
    var sn = createDOM("script", {'type':'text/javascript', 
                                  'src':'/static/js/mcGsearch_action.js'});
    appendChildNodes(body, sn);
}

/* END from mcGsearch.js
******************/


/*
** AJAX search for inviteCombo.tmpl actions
**
*/

if (!mc) { var mc = {}; log('mc created before mc.invite'); }
if (!mc.invite) { mc.invite = function () {}; }
mc.invite.prototype = {
        url:null,
    	init:function (url, forvar) {
    	    this.url = url;
    		return this;
    	},
        inlineSearch: function (inviteWhat,inviteWhere, claimed, inviteArea, url)
        {
           whatval =$(inviteWhat).value;
           whereval = $(inviteWhere).value;
           var err;
           if (!whatval) {
               err = '\n a search term ';
               $(inviteWhat).style.backgroundColor = "#ffdddd";
               }
           if (!whereval) {
               msg = '\n a location containing city, state and/or ZIP';
               (err)?err += 'and ' + msg : err=msg;
               $(inviteWhere).style.backgroundColor = "#ffdddd";
        	   }
        
            if (err) {
        	   $(inviteArea).innerHTML = '\nPlease enter' + err;
        	   return false;
        	   }
        	
            var args = {'search':true,'inviteWhat':whatval,'inviteWhere':whereval, 'claimed':claimed};
            $(inviteArea).innerHTML = 'Loading...'; 
            var d = loadJSONDoc(url, args);
            d.addCallback(function (result) { 
                log('invitearea value',inviteArea);
                $(inviteArea).innerHTML = result["data"]; 
                $(inviteWhat).style.backgroundColor = "#ffffff";
                $(inviteWhere).style.backgroundColor = "#ffffff";
        	   });
        	d.addErrback(function (result) { log ('XMLHttpRequest Failed', result); } );
        	return false;
        }        
    };

if ((mc)&&(!mc.form)) { mc.form = function () {}; } 
mc.form.gatherInvites = function () {
    /* 
    ** gather invites from AJAX invite search boxes
    ** refer to snippets/invite/ajaxMoreMerchants.tmpl 
    ** grab all radio boxes and copy them into the FORM for submission
    */
    var set1 = getElementsByTagAndClassName('input','mcR');
    var set2 = getElementsByTagAndClassName('input','allR');
    var checks = [];
    for (var i=0;i<set1.length;i++) {
        if(set1[i].checked == true) {
            checks.push(set1[i].id);
        }
        }

    for (var i=0;i<set2.length;i++) {
        if(set2[i].checked == true) {
            checks.push(set2[i].id);
        }
        }
    //now copy all checked items -- hidden field and email address -- to the form
    var theform = $('moreinvites');
    theform.innerHTML = '';
    for (var i=0;i<checks.length;i++) 
    {
        var hiddenemail = '<input type="hidden" name="__NAME__" value="__VALUE__" />';

        //copy the INPUT type="radio" field
        var cradio = $(checks[i]);
        var fradio = hiddenemail.replace('__NAME__','company-'+i+'.checked');
        fradio = fradio.replace('__VALUE__', cradio.checked + '" checked="checked"');

        //copy the INPUT type="text" field
        var cemail = $( checks[i].replace('checked','email') );
        var ftext = hiddenemail.replace('__NAME__','company-'+i+'.email');
        ftext = ftext.replace('__VALUE__',cemail.value);

        //copy the INPUT type="hidden" field
        var cid = $( checks[i].replace('checked','id') );
        var fid = hiddenemail.replace('__NAME__','company-'+i+'.id');
        fid = fid.replace('__VALUE__',cid.value);

        theform.innerHTML += fradio + fid + ftext;
    }
    log('form stuff', $('moreinvites').innerHTML);
    return true;
    }

/* END from inviteCombo search
******************/

/* BEGIN from merchant updateable maps
******************/
if (!mc) { var mc = {}; logDebug('mc created before mc.mapset'); }
if (!mc.mapset) {  mc.mapset = function () {}; }
mc.mapset.prototype = {
    url:null,
    lat:null,
    lon:null,
    origlat:null,
    origlon:null,
    init:function (url, lat , lon, origlat, origlon) {
        //receives IDs to values 
        this.url = url;
        this.lat = lat;
        this.lon = lon;
        this.origlat = origlat;
        this.origlon = origlon;
		logDebug('mc.mapset instance initialized');
        return this;
    },
    saveMapLocation: function( ) {
		obj = this;
        var qry= queryString({lat:$(obj.lat).value,lon:$(obj.lon).value});
		$('origlat').value = $(obj.lat).value;
		$('origlon').value = $(obj.lon).value;
        var d = doXHR(obj.url, 
		{
            method:'POST',
			sendContent:qry,
            headers: {"Content-Type":"application/x-www-form-urlencoded"} 
        });
        d.addCallback(function (result) { 
				$('notify').innerHTML=unescape(result.responseText);
				appear('notify',{duration:0.3});
			});
        d.addErrback( function (result) { 
				$('notify').innerHTML=result.responseText; 
				logError('saveMapLocation callback failed'); 
			});
    },
    reset: function () {
        obj = this;
        orig = [$(obj.origlat).value,$(obj.origlon).value];
        log('reset clicked', orig);
    }
};
/* END merchant updateable maps
******************/



/*
**  Interactive Spell Checker code
*/

var gSpellCheckDone = false;
/*
**  show_hover_event 
**      populates the popup div with spelling correction suggestions,
**      and positions it "near" the preview field, which is an anchor somewhere.
**      The function depends on a div with id 'hover_div' defined in calling document
*/
function show_hover_event(e) {
    var a = e.target();
    popup_over(a);
}
function popup_over(a) {
    if (!a.id) return;
    var keys = a.id.split('-');
    // keys[1] is the preview field name
    // keys[2] is the index of the misspelling in the original string
    // keys[3] is the misspelled word
    var spanRE = new RegExp('span\\d+' + '-' + keys[1] + '-' + keys[2] + '-' + keys[3]);
    var hover_div = $('hover_div');
    hover_div.innerHTML = '';
    var repls = getElementsByTagAndClassName('span', 'replacementWord', a);
    var replacements = [];
    var text = a.childNodes[0].nodeValue;
    for (var j = 0; j < repls.length; j++) {
        var spanid = repls[j].id;
        if (spanid && spanid.match(spanRE)) {
            replacements.push(repls[j]);
        }
    }

    var len = replacements.length;
    var ul = UL();
    var anchor = null, li = null;
    for (var i = 0; i < len; i++) {
        var span = replacements[i];
        text = span.childNodes[0].nodeValue;
        anchor = A({'id':span.id.replace(/^span/,'a'), 'class':'wordReplaceAnchor', 'href':'javascript:void(0)'}, text);
        li = LI({'name':'foo'}, anchor);
        ul.appendChild(li);
    }
    hover_div.appendChild(ul);
    var pos = getElementPosition(a);
    var dims = getElementDimensions(a);
    pos.x += 3;
    pos.y += 5;
    // Connect up click handlers
    var anchors = getElementsByTagAndClassName('a', 'wordReplaceAnchor', hover_div);
    for (var i = 0; i < anchors.length; i++) {
        connect(anchors[i], 'onclick', highlightedWordClickHandler);
    }
    showElement('hover_div_container');
    // Wait a couple of seconds, then add a click handler to the document to close the hover div.
}

/*
**  Empty out and hide the popup
*/
function hide_hover_div() {
    $('hover_div').innerHTML = '';
    hideElement('hover_div_container')
}

/*
**  What to do when somebody clicks on a spelling suggestion
**
**  Each of the anchors has an id of the form:
**      aN-previewFieldId-index-replacementText
**      N is an integer, previewFieldId is the target anchor to replace,
**      index is the index of the misspelled word in the original input string,
**      replacementText shouldn't contain spaces...
*/

function highlightedWordClickHandler(evt) {
    var anchor = evt.target();
    var keys = anchor.id.split('-');
    var replacement = anchor.childNodes[0].nodeValue;
    replacement = replacement.replace(/^ */,'');
    replacement = replacement.replace(/ *$/,'');
    var previewField = keys[1];
    var field = fieldsFromPreview[previewField];
    var index = keys[2];
    var text = keys[3];
    var oldvalue = $(field).value;
    var pf = $(previewField);
    var targetAnchor = null;
    var spans = [];
    var found = false;
    var spid;
    
    // We've just got to find the anchor written in for this index by highlightWord,
    // replace it with a plain text node with the replacement text, and remove the
    // corresponding spans.
    var aid = 'anchor-' + previewField + '-' + index + '-' + text;
    targetAnchor = $(aid);
    if (!targetAnchor) return;
    swapDOM(targetAnchor, document.createTextNode(replacement));
    $(field).value = collapse_text(previewField);
    hide_hover_div();
}

function collapse_text(src) {
    var s = $(src);
    var nodes = s.childNodes;
    var child;
    var text = '';
    for (var i = 0; i < nodes.length; i++) {
        child = nodes[i];
        if (child.nodeName == "#text") {
            text += child.nodeValue;
        }
        if (child.nodeName == "A") {
            text += child.firstChild.nodeValue;
        }
    }
    return text;
}

/* map info windows
-- showMapInfoBlock called by marker (mcGmap.js)
-- result data populated by AJAX data returned (map.py)
*/

function DirectoryInfo(url,func) {
	this.url = url;
	this.targetId = 'mapInfoBlock';
	this.queryParams = undefined;
	this.afterCallback = undefined;
	if (!isUndefinedOrNull(func)) {
		this.func = func;
	}
}

DirectoryInfo.prototype.getInfo = function () {
	if (isUndefinedOrNull(this.queryParams)) {
		var d = loadJSONDoc(this.url);
	} else {
		var d = loadJSONDoc(this.url, this.queryParams);
	}
	//add the ajax object for access in AJAX callback
	d.dirInfo = this;
	$(this.targetId).innerHTML = '<div class="loading">Searching for businesses. Please wait.</div>';
    var cb = bind(function (result) { 
            if (isUndefinedOrNull(this.targetId)) 
            		this.targetId = 'mapInfoBlock';
            	$(this.targetId).innerHTML = result['data'];
            	try {
            		markers = result["gmap"];
            		if (!isUndefinedOrNull(d.dirInfo.func)) {
            			var evalStr='frames["gmframe"].' + d.dirInfo.func + '(markers);'
            			eval(evalStr);
            		} else {
            			frames['gmframe'].ajaxUpdateNearBy(markers);
            		}
            		if (!isUndefinedOrNull(d.dirInfo.afterCallback)) {
            		    d.dirInfo.afterCallback();
            		}
            	} catch (err) {
            		log('markers failed', err);
            	}
            }, this);
	d.addCallback(cb); //end d.callback
	return d;
}

DirectoryInfo.prototype.setFunc = function (funcName) {
    this.func = funcName;
}

/*select box navigator. 
* USAGE:
*  <select onchange="(this.id)">
*/
function selectGoTo(id) {
	window.location.href=$(id).value;
}

/* End map info windows
**************************/


/* Send to Friend
**************************/
function sendtofriend(actionUrl, formUrl, routeUrl, args) {
	this.actionUrl = actionUrl;
	this.formUrl = formUrl;
	this.routeUrl = routeUrl;
    this.replaceId = 'sendtofrienddiv';
    this.waitingId = 'sendToFriend';
	if (!isUndefinedOrNull(args)) {
	    this.replaceId = args['target'] || 'sendtofrienddiv';
	    this.waitingId = args['waiting'] || 'sendToFriend';
	    this.companyId = args['companyId'] || undefined;
        this.pageTitle = args['pageTitle'] || undefined;
        this.objectId = args['objectId'] || undefined;
        this.objectType = args['objectType'] || undefined;
	}
}

//AJAX retrieve the Send to friend form
sendtofriend.prototype.getForm = function () {
	var qry = queryString({url:this.routeUrl, companyId:this.companyId, pageTitle:this.pageTitle});
	var d = doXHR(this.formUrl, 
					{
			            method:'POST',
						sendContent:qry,
			            headers: {"Content-Type":"application/x-www-form-urlencoded"} 
			        });
	d.addCallback(this.handleResponse);
	d.addErrback(this.handleError);
}

//AJAX form submission
sendtofriend.prototype.sendForm = function () {
    var qryDict = {fromName: $('fromName').value,
							fromEmail: $('fromEmail').value,
							toEmail: $('toEmail').value,
							message: $('message').value,
							url: $('send_url').value,
							pageTitle:$('pageTitle').value,
							captchaGuess: $('captchaGuess').value,
							captchaHash: $('captchaHash').value,
							companyId:$('send_companyId').value};
    if ( !isUndefinedOrNull(this.objectType) && !isUndefinedOrNull(this.objectType) ) {
        qryDict['objectType'] = this.objectType;
        qryDict['objectId'] = this.objectId;
    }
	var qry = queryString( qryDict );
	var d = doXHR(this.actionUrl, {method:'POST',
						sendContent:qry,
						headers: {"Content-Type":"application/x-www-form-urlencoded"} 
					});
	$(this.waitingId).innerHTML = 'Please wait';
	d.addCallback(this.handleResponse);
	d.addErrback(this.handleError);
	return false;
}

sendtofriend.prototype.handleResponse = function (result) {
    if (isUndefinedOrNull(result.responseText)) {
        $('sendtofrienddiv').innerHTML = 'error ocurred';
    }
    $('sendtofrienddiv').innerHTML = result.responseText;
    //sendToFriend is display:none by default
    try {
        //display the form
        var ndim = getViewportDimensions();
        var npos = getViewportPosition();
        npos.x = ndim.w / 4; //put corner off the side.
        npos.y += 20;
        setElementPosition('sendToFriend', npos);
        Draggable('sendToFriend');
        showElement('sendToFriend');
    } catch (exc){
        $('sendtofrienddiv').innerHTML = result.responseText;
    }
}

sendtofriend.prototype.handleError = function (result) {
	$('sendtofrienddiv').innerHTML = result['data'];
}
/* End Send to Friend
**************************/

/* Newsletter subscribe
**************************/
function newsletterSubscribe () {
}

newsletterSubscribe.prototype.submitSubscription = function (form)
{
	var res = loadJSONDoc(form.action, { 'email':form['email'].value});
	res.addCallbacks(this.doReplaceForm,this.doReplaceErrorForm);
	return false;
}

newsletterSubscribe.prototype.doReplaceForm = function (result) {
    $('newsLetterSubscribe').innerHTML = result["data"];
}

newsletterSubscribe.prototype.doReplaceErrorForm = function () {
	window.location.reload();
}

/* End Newsletter subscribe
**************************/

/* use for onclick to mimic links. prevents robots from clicking to expensive pages
*****/
function jsHref (url) {
    window.location.href = url;
}


/* FORUM-
**************************/
var forum = {
    // thread
    initThread : function() {
    	if (isAdmin() || isModerator()) {
            this.showModerationControls('form','forumPostControl')				
    	} else {
    		// if customer toggle only the ones you've wrote...
    		var cid = getProfileCompany()
    		if (cid) {
    			this.showModerationControls('form', 'co-' + cid)
    		}	
    	}
    },
    // second-level topics...
    initTopic:function(klass) {
    	if (isAdmin() || isModerator()) {
            this.showModerationControls('tr', 'forumModerator')
        }
    },
    // main forum page listing all the forums (ie. top-level topics)...
    initTopics:function(klass) {
    	if (isAdmin() || isModerator()) {
            this.showModerationControls('tr', 'forumAdmin')
        }
    },    
    showModerationControls:function(tagname, klass) {
    	var els = getElementsByTagAndClassName(tagname, klass);
    	for (var i=0; i < els.length; i++ )  {
    		showElement(els[i]);
    	}
    }
}
/* -FORUM
**************************/

/* LOCAL CONSUMER EMAIL
**************************/
/* usage: 
    newEmail = new localConsumerEmail({'city':'Pacifica', 'state':'CA'})
*/
function localConsumerEmail(args) {
    if (args != null) {
        if (args.action_get_form) {this._action_get_form=args.action_get_form;}
        if (args.action_post_form) {this._action_post_form=args.action_post_form;}        
        this.set_city_state(args.city, args.state, args.zip);
    }

    return this;
}


localConsumerEmail.prototype = {
    _email:null,
    _city:null,
    _state:null,
    _zip:null,
    _action_get_form:null,
    _action_post_form:null,
    
    set_city_state:function(city,state,zip){
        this._city=city;
        this._state=state;
        this._zip=zip;
    },
    load_form:function(){
        var qs = queryString({city: this._city, state:this._state, zip:this._zip});
        
    	var d = doXHR(this._action_get_form, 
    	                {method:'POST',
    				     sendContent:qs,
    					 headers: {"Content-Type":"application/x-www-form-urlencoded"}
    					 });
    	d.addCallback(this.load_form_cb);
    	d.addErrback(this.load_form_error);        
    },
    load_form_cb:function(result){
        var el = $('local_consumer_email_signup');
        if (isUndefinedOrNull(result.responseText)) {
            el.innerHTML = "<p>We're sorry, an error ocurred trying to load the signup form.</p>";
        } else {  
            el.innerHTML = result.responseText
            localEmail.show_form();
        }
    },
    load_form_error:function(result){
        
    },
    
    show_form:function(){
        //display the form
        var ndim = getViewportDimensions();
        var npos = getViewportPosition();
        npos.x = (ndim.w / 2) - 300; //put corner off the side.
        npos.y += 50;
        var id = 'local_consumer_email_wrap'
        setElementPosition(id, npos);
        Draggable(id);
        showElement(id);
    },    
    
    
    signup:function(){
        var rec =  $('recipient').value;
        var zipcode_id = $('zipcode_id').value
        var captchaHash = $('captchaHash').value;
        var captchaGuess = $('captchaGuess').value;
        
        var qs = queryString({recipient:rec, zipcode_id:zipcode_id, captchaHash:captchaHash, captchaGuess:captchaGuess});
                
    	var d = doXHR(this._action_post_form, 
    	                {method:'POST',
    				     sendContent:qs,
    					 headers: {"Content-Type":"application/x-www-form-urlencoded"}
    					 });
    	d.addCallback(this.signup_cb);
    	d.addErrback(this.signup_error);
    },
    signup_cb:function(result){
        var el = $('local_consumer_email_signup');
        if (isUndefinedOrNull(result.responseText)) {
            el.innerHTML = "<p>We're sorry, an error ocurred trying to save the signup form.</p>";
        } else {   
            el.innerHTML = result.responseText        
        }
    },
    signup_error:function(result){
        var el = $('local_consumer_email_signup');
        el.innerHTML="<p>We're sorry, there was an error processing your request.</p>"        
    },

    end:function(){}
}


/* -CONSUMER EMAIL
**************************/


/* Neighborhood navigator
**************************/
function mcNeighborSearch (url) {
    if (url)
	    this.url = url;
	insertSiblingNodesAfter('qsearch',SPAN({id:'neighborsearch', title:'see neighborhoods for this city.'},IMG({src:'/static/imgs/buttons/arrowBox_neighborhoods.png', alt:'See neighborhoods in this city.'})));
	this.fired = false;
	this.ajax = null;
	return this;
}
mcNeighborSearch.prototype = {
	staticlist : function () {
	    //use this for static page DOM manip
	    //var mydiv = DIV({id:'neighborpopup'});
	    //mydiv.innerHTML = getElement('neighborlist').innerHTML;
	    //insertSiblingNodesAfter('neighborsearch',mydiv);
	    qpos = getElementPosition('neighborsearch');
        setElementPosition('neighborpopup',{x:qpos.x-100,y:qpos.y+30});
		appear('neighborpopup', {delay:0.1,duration:0.3});
		connect('nhoodclose','onclick', this.closelist);
	},
	getlist : function () {
	    //use this to get neighborhoods via ajax
		if (!this.fired) {
		this.ajax = loadJSONDoc(this.url);
		this.ajax.addCallback(bind(this.neighborhood_cb,this));
		this.fired = true;
		return;
		}
		appear('neighborpopup', {delay:0.3,duration:0.5});
	},
	neighborhood_cb : function (result) {
		var mydiv = DIV({id:'neighborpopup'});
		mydiv.innerHTML = result['data'];
		insertSiblingNodesAfter('neighborsearch', mydiv);
		appear(mydiv, {delay:0.2,duration:0.3});
		connect('nhoodclose','onclick', this.closelist);
	},
	closelist : function () {
	    fade('neighborpopup', {duration:0.3});
	}
}
/* end Neighborhood navigator
**************************/
