/* Use semicolons at the end of lines so this can be minified */

/* run "rake javascript:combine" to add this file to combined_min.js */ 

var COOKIE_DOMAIN = ".chow." + window.TLD;
var chow_logged_in = (document.cookie.indexOf('cs_sig') != -1) ? true : false;

document.observe("dom:loaded", function() {

// main nav event listener
  var main_nav = $$('a.menu_link_text');
	var sub_nav = $$('.nav_tier2');
	var nav_timeout;
	
	// move subnavs from footer to header
	sub_nav.each(function(div) {
		var parent = 'main_' + div.id;
		$(parent).insert(div);
	});
	
  main_nav.each(function(a) {
    a.observe('mouseover', function(e) {
			if (!e) var e = window.event;
			var relTarg = e.fromElement || e.relatedTarget;

			sub_id = a.id.split("_link")[0]; 
			if (relTarg.id != sub_id){
				nav_timeout = setTimeout("show_nav(sub_id)",200);
			} else {
				show_nav(sub_id);
			}
 
    });
    a.observe('mouseout', function(e) {
			if (nav_timeout) clearTimeout(nav_timeout);

      var sub_id = a.id.split("_link")[0];
	  		if ( sub_id.length != 0 && $(sub_id) ){
			 	$(sub_id).style.display = "none";
			}
    });
  });
	
	sub_nav.each(function(div) {
    div.observe('mouseover', function(e) {
      div.style.display = "block";
    });
    div.observe('mouseout', function(e) {
			div.style.display = "none";
    });
  });


	// initialize login and signup lightboxes
	chowLoginSignup.init();
	

// popup opener and closer
// assumes <a href="#id_of_popup" class="open_popup">text</a>
// assumes <a href="#id_of_popup" class="close_popup">text</a>
	var open_popup = $$('a.open_popup');
	var close_popup = $$('a.close_popup');

	open_popup.each(function(a) {
		a.observe('click', function(e) {
			e.stop();
			var popupId = this.href.split('#')[1]; 
			$(popupId).addClassName('active');

		});
	});
	
	close_popup.each(function(a) {
		a.observe('click', function(e) {
			e.stop();
			var popupId = this.href.split('#')[1]; 
			$(popupId).removeClassName('active');
		});
	});
	
		
	
	// restaurant rating on CH posts
	if($('restaurant_review_checkbox')) {
		($('restaurant_review_checkbox').checked) ? showRestaurantInputs(0) : '';
	}
	
	
	
	
  // tabby
  var tabs = $$('#tabby_list li');
  var tab_content = $$('.tabby_content');

  // show/hide tabs
  tabs.each(function(li) {
    li.observe('click', function(e) {
      e.stop();
      clearClasses(li);
      li.addClassName('selected');
      tab_content.each(function(div){div.removeClassName('active'); });

      var href = li.down('a').readAttribute('href').split('#')[1];
      $(href).addClassName('active');
    });
  });

  function clearClasses(el) {
    tabs.each(function(el){
      el.removeClassName('selected');  
    });
  }	

}); // dom:loaded

function show_nav(id){
	if ( id.length != 0 && $(id) )
	$(id).style.display="block";
}


var chowLoginSignup = {
	init: function() {
		// add listeners if not logged in
		if(!chow_logged_in){
			this.add_static_listeners();
			this.add_dynamic_listeners();
			this.new_location = ''; // redirects to new location on login success
		}
	},
	
	
	add_static_listeners: function() {
		
		// this set of listeners only needs to be called once since new elements won't be added to the page
		
		// find all instances of .show_login_box
		var show_login_box = YAHOO.util.Dom.getElementsByClassName('show_login_box');
		// open login lightbox
		YAHOO.util.Event.on(show_login_box, 'click', function(e) {
			YAHOO.util.Event.preventDefault(e);
			var classNames = this.className;
			
			// check if clicked element needs to call an external function after logging in
			if(classNames.indexOf('on_success') != -1) { // assumes element has a class in the form of on_success_someObject.someFunction
				chowLoginSignup.externalSuccess = classNames.split('on_success_')[1].split(' ')[0];
			}
			chowLoginSignup.open_login(YAHOO.util.Event.getPageY(e));
			chowLoginSignup.new_location = (this.href !== undefined) ? this.href : '';
		});
		
		// find all instances of .show_signup_box
		var show_signup_box = YAHOO.util.Dom.getElementsByClassName('show_signup_box');
		// open signup lightbox
		YAHOO.util.Event.on(show_signup_box, 'click', function(e) {
			YAHOO.util.Event.preventDefault(e);
			chowLoginSignup.open_signup(YAHOO.util.Event.getPageY(e));
		});
		
		
		// close lightbox when background is clicked
		var lightbox_bgs = YAHOO.util.Dom.getElementsByClassName('chow_lightbox_bg');
		
		YAHOO.util.Event.on(lightbox_bgs, 'click', function(e) {
			YAHOO.util.Dom.getAncestorByTagName(this, 'DIV').style.display='none';
			chowLoginSignup.clear_login_signup_errors('all');
		});
		
		
		// close lightbox when close btn is clicked
		// assumes <a class="close_lightbox" href="#chow_login">X</a> where href is id of lightbox
		var lightbox_close_btns = YAHOO.util.Dom.getElementsByClassName('close_lightbox');
		
		YAHOO.util.Event.on(lightbox_close_btns, 'click', function(e) {
			YAHOO.util.Event.preventDefault(e);
			$(this.href.split('#')[1]).style.display='none'; 
			
			// clear form and error messages
			chowLoginSignup.clear_login_signup_errors('all');
		});
			
		
		// toggle newsletter signup options
		YAHOO.util.Event.on('get_newsletters', 'click', function(e) {
			YAHOO.util.Event.preventDefault(e);
			if($('newsletter_options').style.display != 'block'){
				$('newsletter_options').style.display = 'block';
			} else {
				$('newsletter_options').style.display = 'none';
			}
		});
		
		
		// signup user_name: show confirmation or error on field blur
		YAHOO.util.Event.on('user_name', 'blur', function(e) {
			
			YAHOO.util.Connect.asyncRequest('POST', '/account/check_username?name=' + this.value, {
				success: function(e){	  
					if(e.responseText == 'username_ok'){
						$('username_ok').style.display = 'block';
						$('username_error').style.display = 'none';
					}
				},
				
				failure: function(e){	  
					if(e.responseText == 'username_in_use'){
						$('username_error').innerHTML = 'Already taken';
					}
					
					if(e.responseText == 'username_invalid_format'){
						$('username_error').innerHTML = 'Username must be between<br>3 and 20 characters';
					}
					$('username_error').style.display = 'block';
					$('username_ok').style.display = 'none';
					YAHOO.util.Dom.addClass('user_name', 'login_error');
				}
			}); // async
		});
							
		
		// signup user_email: show confirmation or error on field blur
		YAHOO.util.Event.on('user_email', 'blur', function(e) {
			YAHOO.util.Connect.asyncRequest('POST', '/account/check_email?email=' + this.value, {
				success: function(e){	  
					if(e.responseText == 'email_ok'){
						$('signup_email_ok').innerHTML = 'Email OK';
						$('signup_email_ok').style.display = 'block';
						$('signup_email_error').style.display = 'none';
					}
				},
				
				failure: function(e){
					if(e.responseText == 'email_invalid_format'){
						$('signup_email_error').innerHTML = 'Invalid email format';
					}
					
					if(e.responseText == 'email_in_use'){
						$('signup_email_error').innerHTML = 'Already registered.<br/><a href="/account/lost_password" onclick="chowLoginSignup.request_password(\'signup_form\'); return false" class="blue">Email password</a>';
					}
					$('signup_email_error').style.display = 'block';
					$('signup_email_ok').style.display = 'none';
					YAHOO.util.Dom.addClass('user_email', 'login_error');
				}
			}); // async
		});
		
		
		// Enter key listener
		YAHOO.util.Event.on(document, 'keydown',  function(e){			
			
			if( YAHOO.util.Event.getCharCode(e) == '13' && $('chow_login') && $('chow_login').style.display == 'block' ){
				YAHOO.util.Event.preventDefault(e);
				chowLoginSignup.submit_login_form();
			}
			
			if( YAHOO.util.Event.getCharCode(e) == '13' && $('chow_signup') && $('chow_signup').style.display == 'block' ){
				YAHOO.util.Event.preventDefault(e);
				chowLoginSignup.submit_signup_form();
			}
		});
				
		
		// submit login form
		YAHOO.util.Event.on('login_submit', 'click', function(e) {
			YAHOO.util.Event.preventDefault(e);
			chowLoginSignup.submit_login_form();
		});
		
		
		// submit sign up form
		YAHOO.util.Event.on('signup_submit_lightbox', 'click', function(e) {
			YAHOO.util.Event.preventDefault(e);
			chowLoginSignup.submit_signup_form(); 
		});			
		
	}, // end add_static_listeners
	
	add_dynamic_listeners: function() {
		// this set of listeners gets called when a new element is added to the page
		// (i.e. swapping password boxes with text boxes so error messages are readable)
		
		var field_names = ['login_name', 'login_password', 'user_name', 'user_password', 'user_password_confirmation', 'user_email' ]
		
		// clear sign up errors onfield focus
		YAHOO.util.Event.on(field_names, 'focus', function(e) {
			if(YAHOO.util.Dom.hasClass(this, 'login_error')) {
				chowLoginSignup.clear_login_signup_errors(this.id)
			}
		});
		
		
		// signup password: show confirmation or error on field blur
		YAHOO.util.Event.on('user_password', 'blur', function(e) {
			
			if(this.value.length < 3){
				$('password_error').style.display = 'block';
				$('password_ok').style.display = 'none';
				YAHOO.util.Dom.addClass('user_password', 'login_error');
			} else {
				$('password_ok').style.display = 'block';
				$('password_error').style.display = 'none';
			}

		});
		
		// signup confirm password: show error on field blur
		YAHOO.util.Event.on('user_password_confirmation', 'blur', function(e) {	
			// make sure both password fields match
			if( $('user_password_confirmation').value != $('user_password').value){
				$('confirm_password_error').style.display = 'block';
				YAHOO.util.Dom.addClass('user_password_confirmation', 'login_error');
			}

		});
		
	
	}, // end add_dynamic_listeners
	
	
	open_login: function(pageY){
		// pageY is optional. It's the y-coordinate of the click event.
		if(pageY !== undefined && pageY > 500){
			// move login box slightly above where the click was
			$('chow_login').style.top = (pageY - 400) + 'px';
			// also need to move the signup box in case they click 'join chow' in the login box
			$('chow_signup').style.top = (pageY - 400) + 'px';
		} else {
			$('chow_login').style.top = 0;
			$('chow_signup').style.top = 0;
		}
		
		
		var user_greetings = ["Let's get cooking!","Looking good today!","Let's stir it up!","Hope you're hungry!","Come and get it!","Hola, guapo!"]
		// choose a random greeting from the list
		$('login_header').innerHTML = user_greetings[Math.floor(Math.random()*user_greetings.length)];
		$('chow_login').style.display='block';
		$('login_name').focus();
	},
	
	open_signup: function(pageY){
		// pageY is optional. It's the y-coordinate of the click event.
		if(pageY !== undefined && pageY > 500){
			// move signup box slightly above where the click was
			$('chow_signup').style.top = (pageY - 400) + 'px';
		} else {
			$('chow_signup').style.top = 0;
		}
		
		$('chow_signup').style.display='block';
		$('user_name').focus();
	},
	
	clear_login_signup_errors: function(id){
	// clear login and sign up errors. called when a field gains focus or the lightbox is closed
		
		if (id == 'all'){
			var error_fields = YAHOO.util.Dom.getElementsByClassName('login_error');
			for(var i = 0; i < error_fields.length; i++) {
				YAHOO.util.Dom.removeClass(error_fields[i], 'login_error');
				error_fields[i].value = '';
			}
		
		} else {
			YAHOO.util.Dom.removeClass(id, 'login_error');
			$(id).value = '';
		}
		
		if(id == 'user_name' || id == 'all') {
			$('username_ok').style.display = 'none';
			$('username_error').style.display = 'none';
		}
		
		if(id == 'user_password' || id == 'all') {
			$('password_ok').style.display = 'none';
			$('password_error').style.display = 'none';
		}
		
		if(id == 'user_password_confirmation' || id == 'all') {
			$('confirm_password_error').style.display = 'none';
		}
		
		if(id == 'user_email' || id == 'all') {
			$('signup_email_ok').style.display = 'none';
			$('signup_email_error').style.display = 'none';
		}
		
		$('login_error').innerHTML = '';
	
		
		// set password fields back to password type
		if (id == 'user_password' || id == 'user_password_confirmation' || id == 'login_password' ){
			changeInputType($(id), 'password');
			chowLoginSignup.add_dynamic_listeners();
			$(id).focus();
		}

	},
	
	
	submit_login_form: function() {
		
		// check for blank fields
		if( $('login_name').value == ''){
			YAHOO.util.Dom.addClass('login_name', 'login_error');
			$('login_name').value = 'Username or Email is Required';
		}
		
		if( $('login_password').value == ''){
			YAHOO.util.Dom.addClass('login_password', 'login_error');
			
			$('login_password').value = 'Password is Required';
			
			// change to text field so text is readable
			changeInputType($('login_password'), 'text');
			chowLoginSignup.add_dynamic_listeners();
		}
		
		// submit form if front-end checks are ok
		if(!YAHOO.util.Dom.hasClass('login_password', 'login_error') && !YAHOO.util.Dom.hasClass('login_name', 'login_error') ){
			YAHOO.util.Connect.setForm('login_form');
			
			toggleSpinner('login_submit', 'hide');
			
			YAHOO.util.Connect.asyncRequest('POST', '/account/login', {
				success: function(e){	  				

					// don't redirect to login or sign up pages
					if(chowLoginSignup.new_location.indexOf('/account/combined') != -1 || 
						chowLoginSignup.new_location.indexOf('/account/login') != -1 || 
						chowLoginSignup.new_location.indexOf('/account/signup') != -1 || 
						chowLoginSignup.new_location == '') {
							chowLoginSignup.new_location = document.location;
					}
					// call external success function if it exists, otherwise refresh the page
					if(chowLoginSignup.externalSuccess){						
						chow_logged_in = true;						
						toggleSpinner('login_submit', 'show');
						$('chow_login').style.display = 'none';
						// remove listeners from login links
						YAHOO.util.Event.removeListener(YAHOO.util.Dom.getElementsByClassName('show_login_box'), "click");
						eval(chowLoginSignup.externalSuccess + '()');
					} else {
						document.location = chowLoginSignup.new_location;
					}
				},
				
				failure: function(e){
					toggleSpinner('login_submit', 'show');
					
					if(e.responseText.indexOf('invalid_username') != -1){
						$('login_error').innerHTML = 'User name / email not found'; 
					}
					
					if(e.responseText.indexOf('invalid_password') != -1){
						$('login_error').innerHTML = 'Invalid Password. Please try again'; 
					}
					
					if(e.responseText.indexOf('unknown_login_state') != -1){
						$('login_error').innerHTML = 'You need to verify your account with the email we sent you before you can log in. Contact <a href="mailto:moderators@chowhound.com" class="blue">moderators@chowhound.com</a> if you didn\'t recieve an email when you signed up'; 
					}
					
					$('login_error').style.display = 'block';
					
				}
			}); // async
			
			
		}
	
	}, // end submit_login_form
	
	
	submit_signup_form: function() {
		var signup_error = false;

		// check for blank fields
		if( $('user_name').value == ''){
			YAHOO.util.Dom.addClass('user_name', 'login_error');
			$('user_name').value = 'Username is Required';
			signup_error = true;
		}
		
		if( $('user_password').value == ''){
			YAHOO.util.Dom.addClass('user_password', 'login_error');
			// change to text field so text is readable
			changeInputType($('user_password'), 'text');
			$('user_password').value = 'Password is Required';
			chowLoginSignup.add_dynamic_listeners();
			signup_error = true;
		}
		
		if( $('user_password_confirmation').value == ''){
			YAHOO.util.Dom.addClass('user_password_confirmation', 'login_error');
			// change to text field so text is readable
			changeInputType($('user_password_confirmation'), 'text');
			$('user_password_confirmation').value = 'Password is Required';
			chowLoginSignup.add_dynamic_listeners();
			signup_error = true;
		}
		
		if( $('user_email').value == ''){
			YAHOO.util.Dom.addClass('user_email', 'login_error');
			$('user_email').value = 'Email is Required';
			signup_error = true;
		}
		
		// make sure both password fields match
		if( $('user_password_confirmation').value != $('user_password').value){
			YAHOO.util.Dom.addClass('user_password_confirmation', 'login_error');
			// change to text field so text is readable
			changeInputType($('user_password_confirmation'), 'text');			
			$('user_password_confirmation').value = 'Both Passwords Must Match';
			chowLoginSignup.add_dynamic_listeners();
			signup_error = true;
		}
		
		
		if(!signup_error){
			toggleSpinner('signup_submit_lightbox', 'hide');
			
			Timezone.set();
			YAHOO.util.Connect.setForm('signup_form');
			
			YAHOO.util.Connect.asyncRequest('POST', '/account/signup', {
				success: function(e){	  
					$('signup_header').innerHTML = 'Thanks for signing up!';
					$('signup_form').innerHTML = '<p class="ml10 mr10 f12">We just sent a <strong>verification email</strong> to your email address. You\'ll need to open it and click the link to finish the registration process. (If you don\'t receive it, check your spam folder! If you still haven\'t received it email <a href="mailto:moderators@chowhound.com" class="blue">moderators@chowhound.com</a>.)</p>';						
				},
				
				failure: function(e){
					toggleSpinner('signup_submit_lightbox', 'show');
					

					if(e.responseText == 'invalid_username'){
						$('login_error').innerHTML = 'Username / email not found.'; 
					}
					
					if(e.responseText == 'invalid_password'){
						$('login_error').innerHTML = 'Invalid Password. Please try again.'; 
					}
					
					$('login_error').style.display = 'block';
					
				}
			}); // async
		}
		
	}, // end submit_signup_form
	
	
	request_password: function(form_name){
		var email = '';
		
		if(form_name == 'login_form'){
			email = $('login_name').value;
			if(email == ''){
				$('login_name').value = 'Please enter your email address.'
				YAHOO.util.Dom.addClass('login_name', 'login_error');
				return;
			}
		} else {
		// signup_form
			email = $('user_email').value;
		}
		
		YAHOO.util.Connect.asyncRequest('GET', '/account/lost_password?email=' + email, {
			success: function(e){
				var msg = 'An email has been sent to ' +  email + ' with your password.';
				if(form_name == 'login_form'){
					$('login_error').innerHTML = msg;
				} else {
				// signup_form
					$('signup_email_ok').innerHTML = msg;
					$('signup_email_ok').style.display= 'block';
					$('signup_email_error').style.display= 'none';
				}

			},
			
			failure: function(e){
				if(e.responseText == 'email_not_found'){
					if(form_name == 'login_form'){
						$('login_error').innerHTML = 'Email not found. Please enter the email address you used to register.';
						YAHOO.util.Dom.addClass('login_name', 'login_error');

					} else {
						$('signup_email_error').innerHTML = 'We couldn\'t find that email address.';
					}
				}
						
			}
			
		}); // async
		
	}

} // end chowLoginSignup

var chowLoginSignupReady = true;

function toggleSpinner(id, visibility){
	
	if( visibility == 'hide') {
		// show spinner
		$(id).style.display = 'none';
		$(id + '_spinner').style.display = 'block'
	} else {
		// hide spinner
		$(id).style.display = 'block';
		$(id + '_spinner').style.display = 'none'
	}

}


// IE can't change input types dynamically, hence this function
// Other browsers have no problem with someInput.type = 'text'
function changeInputType(oldObject, oType) {
	var newObject = document.createElement('input');
	newObject.type = oType;
	if(oldObject.size) newObject.size = oldObject.size;
	if(oldObject.value) newObject.value = oldObject.value;
	if(oldObject.name) newObject.name = oldObject.name;
	if(oldObject.id) newObject.id = oldObject.id;
	if(oldObject.className) newObject.className = oldObject.className;
	oldObject.parentNode.replaceChild(newObject,oldObject);	
	return newObject;
}


/* carousel */
var chow_carousel = {
	init: function() {
		this.carousel_buttons = YAHOO.util.Dom.getElementsByClassName('chow_carousel_button');
		this.totalSlides = this.carousel_buttons.length;
		this.loadImages();
		this.activeIndex = ''; // integer that keeps track of the current slide
		this.addListeners();
		this.timeoutID = ''; // holds a reference to the current timeout process so it can be cleared
		this.startTimer();	
	},
	
	loadImages: function(){
		// set the src attribute of the slides
		var imgs = YAHOO.util.Dom.getElementsByClassName('carousel_slide_img');
		for(var i = 0; i < this.totalSlides; i++) {
			// the active slide already has it's src set. no need to set it again
			if(!YAHOO.util.Dom.hasClass($('carousel_slide_' + i), 'active')){
				imgs[i].src = $('slide_src_' + i).value;
			}
		}
		
	},
	
	startTimer: function(){
		this.timeoutID = setTimeout("chow_carousel.show_slide()", 3000)
	},
	
	addListeners: function(){
		// the starting slide is random so we need to find the active button
		for (var i = 0; i < this.totalSlides; i++){
			if(YAHOO.util.Dom.hasClass(this.carousel_buttons[i], 'active')) {
				this.activeIndex = i;
				break;		
			}
		}
		
		
		// hover over dots
		YAHOO.util.Event.on(this.carousel_buttons, 'mouseover', function(e){
			clearTimeout(chow_carousel.timeoutID);
			chow_carousel.show_slide(this.href.split('#')[1]);
			clearTimeout(chow_carousel.timeoutID);
		});
		
		// restart timer on mouseout
		YAHOO.util.Event.on(this.carousel_buttons, 'mouseout', function(e){
			chow_carousel.startTimer();
		});
		
		YAHOO.util.Event.on(this.carousel_buttons, 'click', function(e){
			YAHOO.util.Event.preventDefault(e);
		});		
	},
	
	show_slide: function(id){
		var oldID = 'carousel_slide_' + this.activeIndex;
		
		if (oldID != id){
			// remove hightlight from active button
			YAHOO.util.Dom.removeClass('chow_carousel_button_' + this.activeIndex, 'active');
		}
			
		if(id === undefined){
			this.activeIndex++;
			if(this.activeIndex >= this.totalSlides) {
				this.activeIndex = 0;
			}
			id = 'carousel_slide_' + this.activeIndex;
		} else {
			this.activeIndex = id.split('carousel_slide_')[1];
		}
		
		if (oldID != id){ // if() keeps slides from going black onmouseout and staying that way
			// fade out current slide
			new Effect.Fade( oldID, { duration: .5, from: 1, to: 0, transition: Effect.Transitions.linear, afterFinish: function() { $(oldID).removeClassName('active') } } );
			// show selected slide
			new Effect.Appear( id, { duration: .5, from: 0, to: 1, transition: Effect.Transitions.linear, beforeStart: function() { $(id).addClassName('active'); } } );
			
			// highlight button
			YAHOO.util.Dom.addClass('chow_carousel_button_' + this.activeIndex, 'active');
			
			this.startTimer();
		}
	}

} // end carousel




var Timezone = { 
  set: function() { 
    var d = new Date(); 
    createCookie("timezone", -d.getTimezoneOffset() * 60, 1000);
  } 
}

//

var Proteus = {
  update_counter: function() {
    var c = readCookie("proteus_counter");
    var n = c ? (parseInt(c) + 1) : 0;
    createCookie("proteus_counter", n);
    return n;
  }
}

//

// TODO add to elements as a method
function removeChildren(parent) {
  while (parent.firstChild) {
    parent.removeChild(parent.firstChild);
  }
}

// Designed for non-terminating tag pairs, like p, div, etc.
function elem(name, contents) { // , options) {
  // XXX if we don't $() it IE will silently die
  var e = $(document.createElement(name));
  
  if (contents) {
    if (typeof(contents) == 'string') {
      // e.appendChild(document.createTextNode(contents))
      // XXX need to refactor how Places search results are populated before using proper dom building
      e.update(contents);
    } else {
      e.appendChild(contents);
    }
  }
  
  // if (options) options.each(function(k,v) { e[k] = v })
  
  return e;
}

// XXX prototype has a facility for this, i think..
function getElementsByClass(searchClass, node, tag) {
  var classElements = [];
  
  if (!node) node = document;
  if (!tag)  tag  = '*';
  
  var els = node.getElementsByTagName(tag);
  var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
  
  for (i = 0, j = 0; i < els.length; i++) {
    if (pattern.test(els[i].className)) {
      classElements[j] = els[i];
      j++;
    }
  }
  
  return classElements;
}

// XXX don't need this.. should refactor it out and use Event.observe instead
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}

// Used for counting characters in email redbox
function textCounter(elementId, counterId, maxlimit) {
    var field = $(elementId);
    if (field.value.length > maxlimit) {
        // if too long...trim it!
        field.value = field.value.substring(0, maxlimit);
    } else {
        // otherwise, update 'characters left' counter
        var tag = $(counterId);
        tag.firstChild.data = maxlimit - field.value.length;
    }
}

String.prototype.blank = function() { return this == '' || this == null }

/*
  Google Maps API helper functions
*/

function centerAndZoom(map, bounds) {
  var sw = bounds.getSouthWest();
  var ne = bounds.getNorthEast();
  var center = new GLatLng(
    (sw.lat() + ne.lat()) / 2,
    (sw.lng() + ne.lng()) / 2
  );
  map.setCenter(center, map.getBoundsZoomLevel(bounds));
}

/*
  Google AJAX Search - http://code.google.com/apis/ajaxsearch/documentation/reference.html
*/
var glocal_ctl, glocal_searcher;

function GoogleSearchCtl() {
  this.results = $('places_search_results');
  
  glocal_searcher = new GlocalSearch(); 
  glocal_searcher.setNoHtmlGeneration();
  glocal_searcher.setCenterPoint('94105'); // San Francisco
  // glocal_searcher.setAddressLookupMode(GlocalSearch.ADDRESS_LOOKUP_DISABLED)
  glocal_searcher.setSearchCompleteCallback(this, GoogleSearchCtl.prototype.searchComplete, [glocal_searcher]);
}

GoogleSearchCtl.prototype.formSubmit = function() {  
  if (Restaurant.validate_search()) {
    $('spinner').show();
    glocal_searcher.execute($F('name') + ' in ' + $F('location'));
  } else {
    $('spinner').hide();
  }
}

// This callback is fired after a Searcher completes its execute() call.
GoogleSearchCtl.prototype.searchComplete = function(searcher) {
  removeChildren(this.results);
  
  var post = 'name=' + escape($F('name')) + '&location=' + escape($F('location'));

  if ($F('board_id')) post += '&board_id=' + escape($F('board_id'));
  
  var params = {
    postBody: post,
    onComplete: function(t) { glocal_ctl.populateResults(eval(t.responseText), searcher.results) }
  }
  
  new Ajax.Request('/restaurants/search', params);
  
  $('restaurant_name').value     = $F('name');
  $('restaurant_location').value = $F('location');
  $('restaurant_board_id').value = $F('board_id');
}

// This fires during searchComplete to show the results to the user.
// Results container is currently hardcoded to #places_search_results for all instances of the SearchControl.
// 
// XXX needs refactoring
GoogleSearchCtl.prototype.populateResults = function(chow_places, google_places) {
  
  $('spinner').hide();
  
  this.results.style.display = 'block';
  
  var chow_div = Restaurant.search_results_container('CHOW Places');
  this.results.appendChild(chow_div);
  
  // Chow  
  if (chow_places.length > 0) {    
    chow_places.each(function(cp, i){
      var div =  elem('div', cp.name + '<br>' + cp.location);
      div.addClassName('chow');
      div.addClassName('result');
      div.onclick = function() { Restaurant.select(escape(cp.name), escape(cp.location), escape(cp.phone)) }
    
      chow_div.appendChild(div);
    })
  } else {
    chow_div.appendChild(
      elem('p', 'Sorry, no CHOW Places found for that region.')
    )
  }
  
  // Google
  if (google_places.length > 0) {    
    var google_div = Restaurant.search_results_container('Other results by name and location');
    this.results.appendChild(google_div);
    
    // XXX has to be a for loop to use +continue+
    for (var j = 0; j < google_places.length; j++) {
      var gp = google_places[j];
      
      if (gp.phoneNumbers == null) {
        continue; // ignore junk
      }
      
      // skip google results that we think we already have in our db
      var dup = false;
      chow_places.each(function(cp){ dup = Restaurant.check_for_dup(cp, gp) })
      
      if (dup) {
        continue;
        
      } else {
        var number = '';
        
        if (gp.phoneNumbers.length > 0) {
          gp.phoneNumbers.each(function(n) {
            // label certain valid types accordingly: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_class_GlocalResult
            if (n.type == 'fax' || n.type == 'mobile' || n.type == 'data') {
              number += n.type + ':&nbsp;';
            }
            number += n.number + '\n';
          })
        }
        
        var div = elem('div', gp.titleNoFormatting + '<br />' + gp.streetAddress + ', ' + gp.city + ', ' + gp.region);
        div.addClassName('result');
      /* prevaluate the parameters to avoid closing over gp, which preserves only its last value */
        div.onclick = new Function(
          "Restaurant.select(\"" + 
            escape(gp.titleNoFormatting) + "\",\"" + 
            escape(gp.streetAddress) + " " + escape(gp.city) + " " + escape(gp.region) + "\",\"" +
            escape(number) +
          "\")"
        )
        
        google_div.appendChild(div);    
      }
    }
  }
  
 /* var none_found = elem('p',
    'Not in list? <input type="button" onclick="$(\'places_add\').show(); $(\'places_search_results\').hide(); $(\'places_search_instructions\').hide()" value="Add a Place" />'
  )*/
  var none_found = ('p'," ");
  this.results.appendChild(none_found);
}


/*
  The Boards: Topics and posts
*/
var Topic = {
  current : null,
  currentType : null,
  mapJsLoaded : false,
  
  switcher : function() {
    var node = $('comments');
    var posts = getElementsByClass('post', node);
    
    if($('switcher').innerHTML == 'Expand All') {
      for (var i = 0; i < posts.length; i++) {
        var id = posts[i].id.replace('highlight-', '');
        Element.removeClassName(posts[i], 'post_collapsed');
        $('truncated-content-' + id).hide();
        $('post-content-' + id).show();
      }
      
      $('switcher').innerHTML = 'Only Show New Posts';
    
    } else {
      for (var i = 0; i < posts.length; i++) {
        if (!posts[i].className.match(/new_post/)) {
          var id = posts[i].id.replace('highlight-', '');
          Element.addClassName(posts[i], 'post_collapsed');
          $('truncated-content-' + id).show();
          $('post-content-' + id).hide();
        }
      }
      
      $('switcher').innerHTML = 'Expand All';
    }
  },
  
  changeResponseArea : function(new_id, topic_id, level) {
    if (this.current != null && (this.current != new_id || this.current_type != 'comment')) {
      $('comment-' + this.current).hide();
    }
    
    if ((this.current != new_id) || (this.current_type != 'comment')) {
      $('comment-' + new_id).innerHTML = '<div style="text-align:center;"><img src="/images/spinner.gif" /></div>'
      new Ajax.Updater($('comment-' + new_id), '/posts/reply', { postBody:'parent_id=' + new_id + '&topic_id=' + topic_id + '&level=' + level, evalScripts:true})
    }

    this.finishChange(new_id, 'comment');

  },
  
  changeFeedbackArea : function(new_id) {   
    if (this.current != null && (this.current != new_id || this.current_type != 'feedbk')) {
      $('comment-' + this.current).hide();
    }
    
    if ((this.current != new_id) || this.current_type != 'feedbk') {
      $('comment-' + new_id).innerHTML = '<div style="text-align:center;"><img src="/images/spinner.gif" /></div>';
      new Ajax.Updater($('comment-' + new_id), '/posts/feedback_panel/' + new_id);
    }
    
    this.finishChange(new_id, 'feedbk');
  },
  
  changeModArea : function(new_id) {
    if (this.current != null && (this.current != new_id || this.current_type != 'mod')) {
      $('comment-' + this.current).hide();
    }
    
    if ((this.current != new_id) || (this.current_type != 'mod')) {
      $('comment-' + new_id).innerHTML = '<div style="text-align:center"><img src="/images/spinner.gif" /></div>';
      new Ajax.Updater($('comment-' + new_id), '/posts/mod_panel/' + new_id);
    }
        
    this.finishChange(new_id, 'mod');
  },

   changeContriArea : function(new_id) {
    if (this.current != null && (this.current != new_id || this.current_type != 'contri')) {
      $('comment-' + this.current).hide();
    }

    if ((this.current != new_id) || (this.current_type != 'contri')) {
      $('comment-' + new_id).innerHTML = '<div style="text-align:center"><img src="/images/spinner.gif" /></div>';
      new Ajax.Updater($('comment-' + new_id), '/posts/contri_panel/' + new_id);
    }
        
    this.finishChange(new_id, 'contri');
  },
 
  finishChange : function(new_id, type) {

    // new Effect.toggle(location.getElementById('comment-' + new_id), 'blind', {duration: .3, fps: 50});
    $('comment-' + new_id).toggle();
        
    // Blow out previous response area
    if (this.current != null && this.current != new_id) {
      $('comment-' + this.current).update('');
    }
    
    this.current = new_id;
    this.current_type = type;
  },
  
  changeSelection : function(selected_value, new_title, input, new_board) {
    if (selected_value == 'POST_SPLIT' || selected_value == 'POST_SPLIT_REPLIES') {
      var title = prompt('Please enter in a topic title for the new thread:');
      if (title != null || title != '') {
        $(input).value = title;
        $(new_title).show();
        $(new_board).show();
      }
    } else if(selected_value == 'TOPIC_MOVE') {
      if (new_title != '') {
        $(new_title).hide();
      }     
      $(new_board).show();
    } else {
      $(new_title).hide();
      $(new_board).hide();
    }
  },
  
  loadMapJs: function(){
  // Load google map api when manage links button is clicked. The add a place geocoder needs this.
  // The map loads the js so if the map is already on the page, don't load the js again
	  if( $('placesmentioned_map') || Topic.mapJsLoaded ){
		Topic.mapJsLoaded = true;
		return;
	  } else {
		  Topic.mapJsLoaded = true;
		  // having a callback function removes document.write from the api script
		  var mapAPI = new Element('script', { type: 'text/javascript', src: 'http://maps.google.com/maps/api/js?sensor=false&callback=Topic.loadMapJs' });
		  $$('head')[0].appendChild(mapAPI);
	  }
	  
  },
  
  
  toggleDropdown : function() {
    $('dropdown').toggle();
    if ($('options_toggle').className == 'toggle_button') {
      $('options_toggle').className = 'toggle_button_toggled';
    } else {
      $('options_toggle').className = 'toggle_button';
    }
  }

} // end Topic

var Post = {

  advancedToggle : function(id, which) {

    var button = $(which + '_button_' + id);
    var form   = $(which + '_form_' + id);
    
    if (button.className.match(/button_active/)) {
      button.removeClassName('button_active');
      form.style.display = 'none';
    } else {
      button.addClassName('button_active');
      form.style.display = 'block';
    }
    
    // if ($('name')) $('name').focus()
  },
  
  editMode : function(id) {
    $('post_content_' + id + '_in_place_editor').hide();
    if ($('post_' + id + '_places')) {
      $('post_' + id + '_places').hide();
    }
    if($('post_' + id + '_reviewed_restaurant')){
      $('post_' + id + '_reviewed_restaurant').hide();
    }

    editors[id].enterEditMode('click');

    for (var index = 0; index < 4; index++) {
      try {
        $('inplace_photo_edit_' + id + '_index_' + index).show();
      } catch(e) {}
    }
  },
  
  setupEditing : function(id, rows) {
    var hideCallback = function() {
      for (var index = 0; index < 4; index++) {
        try {
          $('inplace_photo_edit_' + id + '_index_' + index).hide();
        } catch(e) {}
      }
    }
    var showPlacesList = function(){
      if ($('post_' + id + '_places')) {
        $('post_' + id + '_places').show();
      }
      if($('post_' + id + '_reviewed_restaurant')){
        $('post_' + id + '_reviewed_restaurant').show();
      }

    }
    var insertRatingAndPlaceModule = function(ipe, ipeForm){
      var divTag = document.createElement("div");
      ipeForm.insertBefore(divTag,ipeForm.firstChild);
      new Ajax.Request('/posts/rating_module?id='+id, {
        method: 'get',
        onSuccess: function(transport) {
          divTag.innerHTML = transport.responseText;
					// call restaurant rating and AC functions if restaurant id is set
					if ($('restaurant_id_edit_post_' + id) && $('restaurant_id_edit_post_' + id).value != '' ) {
						$('restaurant_review_checkbox_edit_post_' + id).checked = 'true';
						var checkBoxValue = $('restaurant_review_checkbox_edit_post_' + id).value;
						var ACBoardId = $('restaurant_board_edit_post_' + id).value;
						restaurant_rating('rating_edit_post_' + id);
						setRestaurantName('restaurant_id_edit_post_' + id,'restaurant_edit_post_' + id); 
						restaurant_auto_complete('restaurant_edit_post_' + id,'rest_autoCompleteContainer_edit_post_' + id, ACBoardId, 'restaurant_id_edit_post_' + id);
						showRestaurantInputs('rest_rating_module_edit_post_' + id, 'restaurant_name_edit_post_' + id, 'restaurant_review_checkbox_edit_post_' + id, checkBoxValue);
					}
       }
     });

     var placesUlTag =  document.createElement("div");
     ipeForm.insertBefore(placesUlTag, ipeForm.lastChild);
     new Ajax.Request('/posts/edit_linked_restaurant_module?id='+id, {
        method: 'get',
        onSuccess: function(transport) {
          placesUlTag.innerHTML = transport.responseText;
       }
     });
    
    }

    editors[id] = new Ajax.InPlaceEditor('post_content_' + id + '_in_place_editor', '/posts/set_post_content/' + id, {handleFormSubmission:true, clickToEditText: null, loadTextURL:'/posts/get_post_content/' + id, okText: 'Save', rows:rows, hideCallback: hideCallback, onFormCustomization: insertRatingAndPlaceModule,onLeaveEditMode: showPlacesList, htmlResponse:false,  onFailure: function(transport) {
		  alert('Something\'s gone wrong. Please try again.');	
       }})
    editors[id].dispose();
  },
  
  visibilityToggle : function(id) {
    el = $('post-content-' + id);
    if (el.style.display != 'none') {
      el.hide();
      Element.removeClassName('highlight-' + id, 'post_collapsed');
      $('truncated-content-' + id).show();
    } else {
      el.show();
      Element.removeClassName('highlight-' + id, 'post_collapsed');
      $('truncated-content-' + id).hide();
    }
  },
  
  repliedTo : function(id) {
    var highlight_id = 'highlight-' + id;
    var post = $('post-content-' + id);
    
    if (!post.visible()) {
      post.show();
      Element.removeClassName(highlight_id, 'post_collapsed');
      $('truncated-content-' + id).hide();
    }
    
    new Effect.Highlight(highlight_id, {duration: 5});
    new Effect.ScrollTo(highlight_id, {offset: -200});
  }
} // end Post


/*
  Places
*/
var Restaurant = {
  // Are we adding a place from outside a thread or not? True if so, false if not i.e. in a topic.
  new_path: function() {
    return window.location.href.match(/places\/new#?$/);
  },
  
  validate_search: function(name, location) {
    if (!name) name = $F('name');
    if (!location) location = $F('location');
    
    if (name.blank()) {
      alert('Name is required!');
      $('name').focus();
      return false;
    } else if (location.blank()) {
      alert('Location is required!');
      $('location').focus();
      return false;
    }
    return true;
  },
  
  select : function(name, location, phone) {    
    var params = { postBody: 'restaurant[name]=' + name + '&restaurant[location]=' + location + '&restaurant[phone]=' + phone + '&restaurant[board_id]=' + $F('board_id') };
    new Ajax.Request('/restaurants/create', params);


    // Just redirect to edit the new place if coming from the detached form
    if (Restaurant.new_path()) return;
    
    glocal_ctl.results.hide();
    $('places_search_instructions').hide();
    $('places_add').hide();
    
    $('confirmation_name').update(unescape(name));
    $('places_search_confirmation').style.display = 'block';
    
    $('places_list').show();   
    
    // $('name').value = ''
    // $('location').value = ''
    
    $('restaurant_name').value = '';
    $('restaurant_location').value = '';
  },
  
  another : function() {
    $('places_search_confirmation').hide();
    $('places_search_results').hide();
    $('places_add').hide();
    
    $('places_search_instructions').show();
  },
  
  cancel_another: function() {
    $('places_add').hide();
    
    $('places_search_instructions').show();   
  },
  
  remove : function(place_id) {
    //var place  = $(place_id);
    //var places = $('places');
    //place.parentNode.removeChild(place);
    //if (places) $('fake_places').update(places.innerHTML);
	$(place_id).remove();
	Restaurant.addRemoveClass();
  },
  
  search_results_container: function(heading) {
    return elem('div', elem('p', heading).addClassName('topic_header_underline'));
  },
  
  check_for_dup: function(chow_place, google_place) {
    return google_place.titleNoFormatting == chow_place.name &&
    google_place.streetAddress == chow_place.street &&
    google_place.city == chow_place.city
  },
  
  add_restaurant: function(link) {
    if($('restaurant-list')){
		$('restaurant-list').insert(link,'bottom');
	} else {
		$('fake_places').insert(link,'bottom');
	}
  },
  
  addRemoveClass: function(){
		
	// remove class 'first' from all li tags in the manage links list and then add the class to the first li tag
	if($('restaurant-list')){
		var restaurant_list_li =  $$('#restaurant-list li');
		restaurant_list_li.each(function(li){
			li.removeClassName('first');							 							 
		});
		
		if(restaurant_list_li.length > 0){
			restaurant_list_li[0].addClassName('first');
		}
		
	}  
	  
  },
  
  addRestaurantLink: function(){
	  	  

    // continue if there's an id value and if that value is not already in the ids field
	if($("restaurant_link_id").value != '' && $("restaurant_link_ids").value.match($("restaurant_link_id").value) == null ){
		
  		var link = '<li id=\"restaurant_' + $("restaurant_link_id").value + '\">' + '<a href="#" class="remove" ' +
			'onclick="Restaurant.remove(\'restaurant_'+ $("restaurant_link_id").value + '\');' +
			'Restaurant.removeRestaurantLinkId(\''+ $("restaurant_link_id").value + '\'); return false">Remove</a>' + 
		    '<a href="/restaurants/'+ $("restaurant_link_id").value + '" class=\"r_name\" target=\"_blank\">' + 
			$("restaurant_link_name").value + '</a> - <span class=\"r_address\">' + 
			$("restaurant_link_address").value + '</span>';
        
		if($('manage_links_instructions')) $('manage_links_instructions').style.display='block';
        
		if($('restaurant-list')) $('restaurant-list').style.display='block';
  	    
		Restaurant.add_restaurant(link);
		
		Restaurant.addRemoveClass();
	
        
		$("restaurant_link_ids").value += $("restaurant_link_id").value + ',';
	  }
	},

	removeRestaurantLinkId: function(id){
		$("restaurant_link_ids").value = $("restaurant_link_ids").value.replace(id + ',', '');
	}
   
 
} // end Restaurant

function voteCountAdjust() {
  var field = $('contest_entries_overview');
  var strongs = field.getElementsByTagName('strong');
  var voteWidths = new Array();
  for(var i=0; i<strongs.length; i++) {
    if(strongs[i].getAttribute('class') == 'vote_count') {
      var mom = strongs[i].parentNode;
      var newH = mom.offsetHeight;
      strongs[i].style.height = newH + 3 + "px";
      voteWidths[i] = strongs[i].offsetWidth;     
    }
  }
  voteWidths.sort(function(a,b){return (b - a)})
  for(var j=0; j<strongs.length; j++) {
    if(strongs[j].getAttribute('class') == 'vote_count') {
      if(strongs[j].offsetWidth < voteWidths[0]) {
        strongs[j].style.width = voteWidths[0] + "px";
      }
    }
  }
}

function voteCountAdjustIE() {
  var field = $('contest_entries_overview');
  var strongs = field.getElementsByTagName('strong');
  var voteWidths = new Array();
  for(var i=0; i<strongs.length; i++) {
    if(strongs[i].className == 'vote_count') {
      var mom = strongs[i].parentNode;
      var newH = mom.offsetHeight;
      strongs[i].style.height = newH + 3 + "px";
      voteWidths[i] = strongs[i].offsetWidth;     
    }
  }
  voteWidths.sort(function(a,b){return (b - a)})
  for(var j=0; j<strongs.length; j++) {
    if(strongs[j].className == 'vote_count') {
      if(strongs[j].offsetWidth < voteWidths[0]) {
        strongs[j].style.width = voteWidths[0] + "px";
      }
    }
  }
}

function showMenu(menu, tog) {
  if(tog == 1) {
    $('menu_' + menu).style.display = "block";
    $('menu_' + menu + '_link').style.backgroundImage="url(/images/nav-bg-active.gif)";
    $('menu_' + menu + '_link').style.backgroundRepeat = "repeat-x";
    $('menu_' + menu + '_link').style.color = "#fff";
    $('menu_' + menu + '_link').style.textDecoration = "none";
  }else{
    $('menu_' + menu).style.display = "none";
    $('menu_' + menu + '_link').style.backgroundImage = "url(/images/nav-bg.gif)";
    $('menu_' + menu + '_link').style.backgroundRepeat = "repeat-x";
    $('menu_' + menu + '_link').style.backgroundColor = "#d7d7d7";
    $('menu_' + menu + '_link').style.color = "#bd0e13";
    $('menu_' + menu + '_link').style.height="22px";
    $('menu_' + menu + '_link').style.textDecoration = "none";
  }
}

function showActionMenu(menu, tog) {
  if(tog == 1) {
    $('menu_' + menu).style.display = "block";
  }else{
    $('menu_' + menu).style.display = "none";
  }
}


/* restaurant rating on topic pages */
function restaurant_rating(rating_field){
var rating_modules = YAHOO.util.Dom.getElementsByClassName('rating_module');

for (var i = 0; i < rating_modules.length; i++) {
  var ul = rating_modules[i];
  var li = YAHOO.util.Dom.getChildren(rating_modules[i]);
  for (var j = 0; j < li.length; j++) {
    YAHOO.util.Event.on(li[j], 'click', function(e){
      YAHOO.util.Event.preventDefault(e);
      for(x=1; x <=5; x++){
        YAHOO.util.Dom.removeClass(ul, 'stars' +x );
      }
      YAHOO.util.Dom.addClass(ul, this.className);
      var rating_value = this.className.split('stars')[1];
      YAHOO.util.Dom.get(rating_field).value = rating_value;
    });
  }

}


}
/* restaurant auto complete for boards, link to place, and places lists */
function restaurant_auto_complete(rest_input_field, AC_field, restaurant_board_id, restaurant_id_field, restaurant_name_field, restaurant_address_field){
	// rest_input_field is the id of the input that the user types the restaurant name into
	// AC_field is the id of the autocomplete container
	// restaurant_board_id is the board id
	// restaurant_id_field is the id of the input field that will hold the restaurant id once it's returned
	
	// the next two are optional and are used on 'link to a place' in topics
	// restaurant_name_field is the id of the input field that will hold the restaurant name once it's returned
	// restaurant_address_field is the id of the input field that will hold the restaurant address once it's returned
	
	
	if(restaurant_board_id == null && $('new_board_id') && $('new_board_id').value != 0) { // places list
		restaurant_board_id = $('new_board_id').value;	 
	} else if (restaurant_board_id == null) {
		restaurant_board_id = "";
	}
	
	var oDS = new YAHOO.util.XHRDataSource('/xhr/restaurant/autocomplete?board_ids=' + restaurant_board_id);

	// Set the responseType
	oDS.responseType = YAHOO.util.XHRDataSource.TYPE_JSON;
	oDS.responseSchema = {
	  resultsList : "response.docs",
	  fields : ["restaurant_name", "id", "address", "city", "country_state"]
	};
	
	
	// Instantiate the AutoComplete
	var oAC = new YAHOO.widget.AutoComplete(rest_input_field, AC_field, oDS);
	
	oAC.forceSelection = true;
	oAC.useIFrame = true;
	
	oAC.generateRequest = function(sQuery) {
	  return "&prefix=" + sQuery ;	  
	};
	
	// flatten results into an array
	oAC.resultTypeList = true;
	
	oAC.formatResult = function(oResultData, sQuery, sResultMatch) {
		var acAdress = (oResultData[2] != null) ? oResultData[2] : '';
		var acCity = (oResultData[3] != null) ? oResultData[3] : '';
		return '<span class="fr">' + acAdress + ', ' + acCity + '</span><span class="bold">' + oResultData[0] + '</span>';
	};
	
	oAC.itemSelectEvent.subscribe(function(oSelf, elItem , oData) {
	
		
		$(restaurant_id_field).value = elItem[2][1];
		
		// add name and address to input field unless we're in the manage links module
		if(rest_input_field == "link_to_restaurant_field") {
			$(rest_input_field).value = "";
		} else {
			$(rest_input_field).value = elItem[2][0] + ' - ' + elItem[2][2] + ' ' + elItem[2][3] + ', ' + elItem[2][4];
		}
		
		// the next two are used for link to a place
		if (restaurant_name_field !=''){

			$(restaurant_name_field).value = elItem[2][0];
		}
		if (restaurant_address_field !=''){
			$(restaurant_address_field).value = elItem[2][2] + ' ' + elItem[2][3] + ', ' + elItem[2][4];
		}
		
	
		
		// write html
		Restaurant.addRestaurantLink();
		
	});
	

  return {
      oDS: oDS,
      oAC: oAC
  };
}

function showRestaurantInputs(rest_rating_module, restaurant_name, restaurant_review_checkbox, checkbox_value) {

		if(checkbox_value == "0") {
				//show
				$(rest_rating_module).style.display ='block';
				$(restaurant_name).style.display ='block';
				$(restaurant_review_checkbox).value ='1';

		} else {
				//hide
				$(rest_rating_module).style.display ='none';
				$(restaurant_name).style.display ='none';
				$(restaurant_review_checkbox).value ='0';
		}

}

// write restaurant name to page if user is editing a previous post
function setRestaurantName(id_field, nameField){
	var idValue = $(id_field).value;
	if(idValue=="") return;
	var sUrl = '/xhr/restaurant/get?id='+ idValue;	
	
	var restNameSuccess = function(o){
		if(o.responseText !== undefined){
			var restaurantResult = eval('(' + o.responseText + ')');
			//var restaurantResult = JSON.parse(o.responseText); // doesn't work in IE6
			$(nameField).value= restaurantResult.response.docs[0].restaurant_name;	
		}
	};
	
	var restNameFailure = function(o){
		if(o.responseText !== undefined){
			$(nameField).value= "Couldn't find Restaurant name";
		}
	};
	
	var callback =
	{
		success:restNameSuccess,
		failure:restNameFailure
	};

	var request = YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);

}


// autocomplete for sidebar and topics search bar
// takes the id of the input field and the autocomplete container
function chowAutoSuggest(input_id, AC_id) {
	
	var oDS = new YAHOO.util.XHRDataSource('/xhr/tags/autocomplete');

	// Set the responseType
	oDS.responseType = YAHOO.util.XHRDataSource.TYPE_JSON;
	oDS.responseSchema = { 
		 resultsList : "response.docs", 
		 fields : ["tag_name"]
	};

	// Instantiate the AutoComplete
	var oAC = new YAHOO.widget.AutoComplete(input_id, AC_id, oDS);
	oAC.generateRequest = function(sQuery) { 
		return "?prefix=" + sQuery ; 
	};
	
	oAC.autoHighlight = false;
	oAC.allowBrowserAutocomplete = false;
	oAC.animVert = false;
	oAC.useIFrame = true;
	
	// submit sidebar search form when a selection is made
	oAC.itemSelectEvent.subscribe(function(oSelf, elItem , oData) {
		if(input_id == "sidebar_entry" ) $('side-search').submit();
	});
	
    // populate input field when item is moused over
	oAC.itemMouseOverEvent.subscribe(function(oSelf , elItem) {
		$(input_id).value = elItem[1].innerHTML;
	});
	
	// populate input field when item is arrowed to
	oAC.itemArrowToEvent.subscribe(function(oSelf , elItem) {
		$(input_id).value = elItem[1].innerHTML;
	});

	return {
			oDS: oDS,
			oAC: oAC
	};
}

var goRecipePrint = {

	printNow : function() {	
		this.isCtrl = false;
		this.isP = false;
		/*if ($( "printID" )) {
			$( "printID" ).onclick = this.doPopup;
		}*/
		document.onkeydown = this.KeyDownCheck;
		document.onkeyup = this.KeyUpCheck; 			  
	},
	
	KeyUpCheck : function(e) {		
		var KeyID = (window.event) ? event.keyCode : e.keyCode;	 		 
		switch(KeyID){

	 		case 17:
	 		this.isCtrl = false;
	 		break;
		  
	 		case 224:
	 		this.isCtrl = false;
	 		break;
	  
	 		case 91://for safari
	 		this.isCtrl = false;
	 		break;	 
		}
	},  
	
	KeyDownCheck : function(e){
		var KeyID = (window.event) ? event.keyCode : e.keyCode;
		switch(KeyID){

			case 17:
			this.isCtrl = true;			
			break;
			  
			case 224:
			this.isCtrl = true;
			break;
		  
			case 91://for safari
			this.isCtrl = true;
			break;	 
		}
	  
		if (this.isCtrl && KeyID == 80){	
			var theURL = document.location.href; 
			recipeNumber = theURL.substring(theURL.length-5, theURL.length);
			printURL = "/print/recipe/" + recipeNumber;
			if (document.all){ window.parent; }//for IE6 because it losses focus
			document.location = printURL; 
			return false;  		  	  
		}		
	}
		
	/*doPopup : function() {
		var theURL = document.location.href; 
		recipeNumber = theURL.substring(theURL.length-5, theURL.length);
		printURL = "/print/recipe/" + recipeNumber;
		document.location = printURL;
		return false;
	}*/
}// end goRecipePrint object

// Manage Links in Post - Auto-linking restaurants

function sendPostContent(restaurant_link_id, restaurant_link_name, restaurant_link_address, restaurant_link_ids, open_manage_links, restaurant_list, manage_links){
	var board_id = $('board_id').value;
	var postContent = document.topic.elements['post_content'].value;
		
	
	// append title field to postContent if it exists
	if($('topic_title')) postContent += ' ' + $('topic_title').value;
	
	// if coming from a restaurant page and creating a new post, get restaurnat id from url and append it to xhr call
	if(document.location.toString().match('restaurant_id')){
		postContent += '&restaurantID=' + document.location.toString().split('restaurant_id=')[1].split('&')[0];
	}
	
	
	autoLinkRestaurantsUrl = '/xhr/linkPost?boardID=' + board_id;
	
	
	if($('open_manage_links')) $('open_manage_links').value = 1;
		
	YAHOO.util.Connect.asyncRequest('POST', autoLinkRestaurantsUrl, {
		
		success: function(e) {
			
			var restaurantResultsObj = YAHOO.lang.JSON.parse(e.responseText);
			
			// if results exist, carry on, otherwise exit
			if (restaurantResultsObj.restaurantsInfoResult) {
				var O = restaurantResultsObj.restaurantsInfoResult;
				if($('manage_links_instructions')) $('manage_links_instructions').style.display = 'block';
				if($('restaurant-list')) $('restaurant-list').style.display = 'block';
			} else { return }
				
				
			for (i=0; i < O.length; i++) {
				  
					$(restaurant_link_id).value = O[i].id;
					

					// the next two are used for link to a place
					if (restaurant_link_name !=''){
						$(restaurant_link_name).value = O[i].name;
					}
					if (restaurant_link_address !=''){
						$(restaurant_link_address).value = O[i].address.address[0] + ' ' + O[i].address.city + ', ' +  O[i].address.state;
					}
					Restaurant.addRestaurantLink();
														
			} // end for loop																	
			
			
		} // end success
	}, 'postContent=' + encodeURIComponent(postContent)); //end ajax request
	
} // end Auto-linking restaurants

// Don't submit form when enter key is pressed
function disableEnterKey(e,inputFieldId) {
     var key=e.keyCode || e.which; // IE / firefox     
     return (key != 13);
     if ($(inputFieldId)) {
	    $(inputFieldId).value = '';
	   }  
} // end disableEnter Key


// js for photo uploads
var uploadPhoto = {
	
	//filebrowsers: 1,
	
	init: function(){
        //register events
        uploadPhoto.addNewFileBrowser();
		uploadPhoto.removePhoto();
	},	
	
	addNewFileBrowser: function(id){
		var file_upload_inputs = (id) ? id : YAHOO.util.Dom.getElementsByClassName('fileuploadinput');
		
		//detect change event on file selector
		YAHOO.util.Event.addListener( file_upload_inputs, 'change', function(){
			var number = this.id.split('photo')[1];
			
			$('remove_photo' + number).style.display = 'block';
			
			if( this.value != '' ){
				//add filename to input
				$('add-photo-filetext-' + number).value = this.value;
			}

		});

	},
	
	removePhoto: function(){
		var remove_photo_links = YAHOO.util.Dom.getElementsByClassName('remove_photo_link');
		YAHOO.util.Event.addListener( remove_photo_links, 'click', function(e){
			YAHOO.util.Event.preventDefault(e);
			var number = this.rel.split('photo')[1];         // assumes rel='photo' plus a number
			
			// clear file input
			// IE doesn't support this $(this.rel).value = '';
			// so you have to add a new file input in place of the old one
			$('photo' + number + '_wrapper').innerHTML = '<input type="file" name="photo' + number + '" id="photo' + number + '" class="fileuploadinput">'
			
			
			// clear fake file input
			$('add-photo-filetext-' + number).value = '';
			this.style.display = 'none';
			
			// add listener to the new file input
			uploadPhoto.addNewFileBrowser('photo' + number);
		});
		
	}
	
} // uploadPhoto


/* add new restaurant */
var addplace = {
	
	init: function(){

		YAHOO.util.Event.addListener('add_place_form','submit',function(e){
			
			// change submit button to spinner
			$('addplacesubmit').innerHTML = '<img src="/images/spinner_lg.gif" id="addplace_spinner" />';
			
			//error cleanup			
			addplace.removeError();
			
			//stop form submit
			YAHOO.util.Event.preventDefault(e);
			
			//clear existing hidden inputs
			var el = YAHOO.util.Dom.getElementsByClassName('addplacehiddeninput','input');
			for(var i=0;i<el.length;i++){
				el[i].value = '';
			}
			
			//get form inputs
			var el = YAHOO.util.Dom.getElementsByClassName('addplaceinput', 'input');

			//geocode on name/address fields
			var geo = new google.maps.Geocoder();
			geo.geocode( { address: el[1].value }, function(results, status){
			                  
				//possible status responses from request
				if(status === "OK" && results.length > 0){
					//only use the first result
					
					//increment if required field is matched
					var addresscomponents = [];
					
					//get lat & long
					if(results[0].geometry.location.lat() !== '' && results[0].geometry.location.lng() !== ''){
						addresscomponents.push({tid:'addplacelat', val:results[0].geometry.location.lat()});
						addresscomponents.push({tid:'addplacelong', val:results[0].geometry.location.lng()});
					}				
					
					//get address
					if(results[0].formatted_address !== '')
						addresscomponents.push({tid:'addplaceaddress', val: results[0].formatted_address.split(',',1)[0] });

					var e = results[0].address_components;
					for(var i=0;i<e.length;i++){
					
					    for(var d=0;d<e[i].types.length;d++){
					        //city
					        if(e[i].types[d] === 'locality'){
					        	addresscomponents.push({tid:'addplacecity', val:e[i].short_name});
					        }
					        //states are returned as "administrative_area_level_1" but can be different in non-US countries.
					        //we ignore this parameter if it is different than level_1 and get country/city only
					        if(e[i].types[d] === 'administrative_area_level_1'){
					        	addresscomponents.push({tid:'addplacestate', val:e[i].short_name});
					        }
					        //country
					        if(e[i].types[d] === 'country'){
					        	addresscomponents.push({tid:'addplacecountry', val:e[i].short_name});							
					        }
					        //postal code
					        if(e[i].types[d] === 'postal_code'){
					        	addresscomponents.push({tid:'addplacezipcode', val:e[i].short_name});
					        }
					    }
					        
					}
					
					//check if required hidden inputs are all filled from geocoder
					if( addresscomponents.length !== 7 ){
						addplace.showError('The address fields needs to include address, city and state. Try to be more precise or check the spelling.');
						return false;
					}

					//check if restaurant name has been filled in
					if(el[0].value === ''){
						addplace.showError('The restaurant\'s name is required.');
						el[0].focus();
						return false;
					}
					
					//add geocode info to form
					for(var i=0; i<addresscomponents.length; i++){
						$( addresscomponents[i].tid ).value = addresscomponents[i].val;
					}


					//set formatted address into input
					el[1].value = results[0].formatted_address;
					


					//submit form to api
					//set post params
					YAHOO.util.Connect.setForm('add_place_form'); 
					
					//submit form
					YAHOO.util.Connect.asyncRequest('POST', '/xhr/restaurant/add.json', {
					    //if successful
					    success: function(e){
							// change spinner back to submit button
							$('addplacesubmit').innerHTML = '<input type="submit" class="addplacesubmit" value="Add Restaurant or Bar"/>';
					
							var r = YAHOO.lang.JSON.parse(e.responseText);
					    document.getElementsByTagName('input').disabled='true';
					    $('addplaceerror').innerHTML = '<div id="add_place_error" style="background-color:#fff;color:#333">Your restaurant or bar is being added. You will be redirected to another page momentarily. Thank you for your patience.</div>';
					
					    //close popup
					    $('add_place_popup').style.display = "none";
					
					    if($('manage_links_instructions')) $('manage_links_instructions').style.display = 'block';
				      if($('restaurant-list')) $('restaurant-list').style.display = 'block';
					
					    //add restaurant link to page
					    $('restaurant_link_id').value = r.id;
					    
					    // the next two are used for link to a place  
					    $('restaurant_link_name').value = r.restaurant_name;
					    $('restaurant_link_address').value = r.address + ' ' +r.city + ', ' +  r.country_state;
					  
					    Restaurant.addRestaurantLink();
 
              //redirect to edit page
					    window.open('/restaurants/'+r.id+'/?format=edit', 'Edit Restaurant'); 
					
   
					    },
					    
					    failure: function(e){
					        
					        //handle possible error states from xhr api
					        e.status === 400 ? function(){
					            //remove error message if present, and send callback/msg if response should be shown
					            addplace.showError( e.responseText );
					        }():
					        e.status === 404 ? function(){
					            //show message if url couldn't be found.
					            addplace.showError('Looks like that doesn\'t exist.');
					        }():
					        e.status === 500 ? function(){
					            //show message that something wrong happened on the server
					            addplace.showError('Sorry, but there might be something wrong on our end. Try it again, and we\'ll fix it if it\'s broken.');
					        }():function(){
					            //show message for other errors not handled here.
					            addplace.showError('We\'re having some app problems right now. Please try again in a bit.');
					        }();
					        
					    }
					    
					}, '');
					
			
			     }
			     //geocoder errors
			     if(status === "ZERO_RESULTS"){ addplace.showError('The address you entered wasn\'t found. Try an alternate search or spelling'); }
			     if(status === "OVER_QUERY_LIMIT"){ addplace.showError('Too many requests. Please wait and try again.'); }
			     if(status === "REQUEST_DENIED"){ addplace.showError('Request deined.'); }
			     if(status === "INVALID_REQUEST"){ addplace.showError('The address field needs to include Address, City and State'); }
			     
			 });

		});		

	},
	
	showError: function(msg){
		// change spinner back to submit button
		$('addplacesubmit').innerHTML = '<input type="submit" class="addplacesubmit" value="Add Restaurant or Bar"/>';
		
		//remove error message if present
		addplace.removeError();
		$('addplaceerror').innerHTML = '<div id="add_place_error">'+ msg.replace(/&lt;/g,'<').replace(/&gt;/g, '>').replace(/&quot;/g, '"') +'</div>';
	},
	removeError: function(){
		//check if error was previously displayed and remove if so
		$('addplaceerror').innerHTML = '';
	},
	addDuplicate: function(){
		//submit form to api
		//set post params
		YAHOO.util.Connect.setForm('add_place_form'); 
		
		//submit form
		YAHOO.util.Connect.asyncRequest('POST', '/xhr/restaurant/add.json?ignoreDuplicate=true', {
		    //if successful
		    success: function(e){
		
				var r = YAHOO.lang.JSON.parse(e.responseText);
		
		        //redirect to edit page
		        window.location = '/restaurants/'+r.id+'/?format=edit';
		        
		    },
		    
		    failure: function(e){
		        
		        //handle possible error states from xhr api
		        e.status === 400 ? function(){
		            //remove error message if present, and send callback/msg if response should be shown
		            addplace.showError( e.responseText);
		        }():
		        e.status === 404 ? function(){
		            //show message if url couldn't be found.
		            addplace.showError('Looks like that doesn\'t exist.');
		        }():
		        e.status === 500 ? function(){
		            //show message that something wrong happened on the server
		            addplace.showError('Sorry, but there might be something wrong on our end. Try it again, and we\'ll fix it if its broken.');
		        }():function(){
		            //show message for other errors not handled here.
		            addplace.showError('We\'re having some app problems right now. Please try again in a bit.');
		        }();
		        
		    }
		    
		}, '');
	}	
}

// end add a place

 /* comments.js */

var chowcomments = {
		init:function(){
			
			//add focus events for form fields
			YAHOO.util.Event.addListener('comments_text','focus',function(){
				//set default text value
				if( this.defaultValue === ''){ this.defaultValue = this.value; }
			
				//clear value
				if( this.value === this.defaultValue ){ $(this.id).value = ''; }
			});
	
			//add blur events for form fields
			YAHOO.util.Event.addListener('comments_text','blur',function(){
				if( this.value === '' ){ $(this.id).value = this.defaultValue; }
			});			
	
	
			//##FORM SUBMISSION
			//add event listeners for form
			//override form submission event
			YAHOO.util.Event.addListener('chow-addComment', 'submit', function(e){ 																													
				//stop form from submitting
				YAHOO.util.Event.preventDefault(e);
				
				if (chow_logged_in) {
					chowcomments.submitComment();
				}
			});
		
			chowcomments.registerDelete();
			
		},


        buildComment:function() {
            //comment object
            var comment = {};
            
            
            //get comment
            var commenttext = $('comments_text').value;
                if( commenttext.toLowerCase() != 'comment' && commenttext != '' ){
                    comment.comment = commenttext;
                }
            return comment;

            //get rid
            var rid = $('rid').value;

            //get content type
            var rtype = $('rtype').value;

        },

        loginToChow:function() {
            var comment = chowcomments.buildComment();
            var qs = '?text='+encodeURIComponent(comment.comment);
            $('return_to').value = $('return_to').value+qs;
        },
       

        submitComment:function() {
			if ( $('comments_text').value == 'Comment' || $('comments_text').value === undefined ) {
				chowcomments.showError('Please enter some text before submitting your comment.');
				return;
			}
			// change submit button to spinner
			$('submit_btn_holder').innerHTML = '<img src="http://www.chow.com/images/spinner-small-orange-bg-transparent.gif" />';
            var comment = chowcomments.buildComment();
                
                //submit form to api
				//set post params
				YAHOO.util.Connect.setForm('chow-addComment');
					
				//submit form 
                YAHOO.util.Connect.asyncRequest('POST', '/xhr/comments', {

                    //if successful
                    success: function(e){
	
                    	chowcomments.donecommentPost(e, comment);
                    },
                    
                    failure: function(e){
                        $('submit_btn_holder').innerHTML = '<input type="submit" class="submit_btn show_login_box" id="submit_comment" value="">';
						
						//handle possible error states from xhr api
                        e.status === 400 ? function(){
                            //remove error message if present, and send callback/msg if response should be shown
                            chowcomments.showError( e.responseText );
                        }():
                        e.status === 404 ? function(){
                            //need a better message here
                            //show message if url couldn't be found.
                            chowcomments.showError('Looks like that doesn\'t exist.');
                        }():
                        e.status === 500 ? function(){
                            //show message that something wrong happened on the server
                            chowcomments.showError('Sorry, but there might be something wrong on our end. Try it again, and we\'ll fix it if its broken.');
                        }():function(){
                            //show message for other errors not handled here.
                            chowcomments.showError('We\'re having some app problems right now. Please try again in a bit.');
                        }();
                        
                    }
                    
                });


            
		},
		
        
	
        donecommentPost:function(e, comment){
	
			chowcomments.removeError();
			
			//reload page
			if(window.location.toString().indexOf('?comment=new') == -1 ){
				window.location = window.location + '?comment=new#comments_container';
			} else {
				window.location.reload(true);
			}
 
        },

        //##comment DELETE BUTTONS	
		registerDelete:function(sm){
		
			//if el is undefined, get all delete buttons on page
			if(sm === undefined){
				var sm = YAHOO.util.Dom.getElementsByClassName('comment-delete-btn');
			}
			
			//setup listeners for delete buttons
			YAHOO.util.Event.addListener(sm,'click',function(e){
			
				//comment object
				var comment = {};
				
				//set storyID
				//comment.storyID = 0; //set rating
			
				YAHOO.util.Connect.asyncRequest('POST', '/xhr/comment/delete.json', {
					//if successful
					success: function(e){
						
						//removes error if previously shown
						chowcomments.removeError();
						
						//remove comment from DOM
						//var r = $('comment'+comment.storyID);
						//r.parentNode.removeChild(r);
						
						//update comment count
						chowcomments.updatecommentCount();
						
					},
				
					failure: function(e){
						//handle possible error states from xhr api
						e.status === 400 ? function(){
							//remove error message if present, and send callback/msg if response should be shown
							chowcomments.showError( e.responseText );
						}():
						e.status === 404 ? function(){
							//need a better message here
							//show message if url couldn't be found.
							chowcomments.showError('Looks like that doesn\'t exist.');
						}():
						e.status === 500 ? function(){
							//show message that something wrong happened on the server
							chowcomments.showError('Sorry, but there might be something wrong on our end. Try it again, and we\'ll fix it if its broken.');
						}():function(){
							//show message for other errors not handled here.
							chowcomments.showError('We\'re having some app problems right now. Please try again in a bit.');
						}();
						
					}
				
				}/*,'storyID='+comment.storyID*/);
						
			});
			
		},
		
		showError: function(msg){
			//remove error message if present
			chowcomments.removeError();
			
			// create new error node and insert
			var div = document.createElement('div');
			div.id = 'chow-commentError';
			div.innerHTML = msg;
			$('chow-addComment').parentNode.insertBefore(div, $('chow-addComment') );
			// Insert submit button in case initial state had login link and login success called this success function
			$('submit_btn_holder').innerHTML = '<input type="submit" class="submit_btn show_login_box" id="submit_comment" value="">';
		},
		removeError: function(){
			//check if error was previously displayed and remove if so
			var rm = $('chow-commentError');
			if(rm !== null){
				rm.parentNode.removeChild(rm);
			}	
			
		}
		
	}