/*
	Site:		PBX Prompts
	File:		Main Site Behaviors
	Author:		Eric Shepherd (except where noted)
	Date:		August 2007 - January 2008
	Copyright:	2007-2008 Sayers Media Group, LLC. All Rights Reserved
*/


/*************************************
           jQuery Plugins
*************************************/


/**
 * <p>Clears any form on which it's run.</p>
 *
 * @return jQuery
 * @author Eric Shepherd
 * @example
 * 		$('#my-form').clearForm();
 **/
jQuery.fn.clearForm = function() {
	return this.each(function() {
		var type = this.type;
		var tag = this.tagName.toLowerCase();
		if (tag == 'form') {
			return $(':input', this).clearForm();
		}
		if (type == 'text' || type == 'password' || tag == 'textarea') {
			this.value = '';
		} else if (type == 'checkbox' || type == 'radio') {
			this.checked = false;
		} else if (tag == 'select') {
			this.selectedIndex = -1;
		}
	});
};


/**
 * <p>jquery color animations. Use with $().animate({ js css property: str value }, int duration)</p>
 *
 * @return		jQuery
 * @author		John Resig (http://plugins.jquery.com/project/color)
 * @copyright	2007 John Resig, released under the MIT and GPL licenses.
 * @example
 * 		$('#element').animate({ backgroundColor: '#343434' }, 1000);
 **/
(function(jQuery){

			// We override the animation for all of these color styles
	jQuery.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){
		jQuery.fx.step[attr] = function(fx){
			if ( fx.state === 0 ) {
				fx.start = getColor( fx.elem, attr );
				fx.end = getRGB( fx.end );
			}

			fx.elem.style[attr] = "rgb(" + [
				Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
				Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
				Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
			].join(",") + ")";
		}
	});

	// Color Conversion functions from highlightFade
	// By Blair Mitchelmore
	// http://jquery.offput.ca/highlightFade/

	// Parse strings looking for color tuples [255,255,255]
	// [gotta love those seven return statements...]
	function getRGB(color) {
		var result;
				// Check if we're already dealing with an array of colors
		if (color && color.constructor == Array && color.length == 3) {
			return color;
		}
				// SAFARI HACK: Test to see if the color returned rgba(0,0,0,0) rather than "transparent" if an element is transparent
		if (result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) {
			//return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];
			return [255,255,255]; // we'll start with white by default
		}
				// END SAFARI HACK
				// Look for rgb(num,num,num)
		if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) {
			return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];
		}
				// Look for rgb(num%,num%,num%)
		if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) {
			return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
		}
				// Look for #a0b1c2
		if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) {
			return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
		}
				// Look for #fff
		if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) {
			return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
		}
				// Otherwise, we're most likely dealing with a named color
		return colors[jQuery.trim(color).toLowerCase()];
	}
	
			// rewritten by EBS to eliminate the assignment operator in the while statement
	function getColor(elem, attr) {
		var color;
		while(elem) {
			color = jQuery.curCSS(elem, attr);
			if (color !== '' && color != 'transparent' || jQuery.nodeName(elem, 'body')) {
				break;
			}
			attr = 'backgroundColor';
			elem = elem.parentNode;
		}
		return getRGB(color);
	}

	// Some named colors to work with
	// From Interface by Stefan Petre
	// http://interface.eyecon.ro/

	var colors = {
		aqua:[0,255,255], azure:[240,255,255], beige:[245,245,220],	black:[0,0,0], blue:[0,0,255], brown:[165,42,42], cyan:[0,255,255],
		darkblue:[0,0,139], darkcyan:[0,139,139], darkgrey:[169,169,169], darkgreen:[0,100,0], darkkhaki:[189,183,107], darkmagenta:[139,0,139],
		darkolivegreen:[85,107,47], darkorange:[255,140,0], darkorchid:[153,50,204], darkred:[139,0,0], darksalmon:[233,150,122], darkviolet:[148,0,211],
		fuchsia:[255,0,255], gold:[255,215,0], green:[0,128,0], indigo:[75,0,130], khaki:[240,230,140], lightblue:[173,216,230], lightcyan:[224,255,255],
		lightgreen:[144,238,144], lightgrey:[211,211,211], lightpink:[255,182,193], lightyellow:[255,255,224], lime:[0,255,0], magenta:[255,0,255],
		maroon:[128,0,0], navy:[0,0,128], olive:[128,128,0], orange:[255,165,0], pink:[255,192,203], purple:[128,0,128], violet:[128,0,128],
		red:[255,0,0], silver:[192,192,192], white:[255,255,255], yellow:[255,255,0]
	};

})(jQuery);


/*************************************
     Create the object and init
*************************************/

var SMG = window.SMG || {};

SMG.pbxprompts = function() {

	/* private */
	
	var pageName						= '';
	var manualPromptWordLimit			= 20;
	var manualPromptAdditionalCharge	= 0.8;
	var highlightColor					= '#fffdd4';
	

	/**
	 * <p>Gets the body id, defaulting to 'generic' if none present, and sets the pageName.
	 * Triggers page-specific behavior.</p>
	 *
	 * @return void
	 * @author Eric Shepherd
	 **/
	function init() {
		
				// assigns page name and runs page-specific behavior
		var body = document.getElementsByTagName('body')[0];
		pageName = (body.id !== null) ? body.id : 'unknown-page';
		buildPageBehaviors();

				// initializes live help - comment out for now
		//liveHelpInit();
	}
	
	
	/**
	 * <p>Centralizes stuff that is needed for every thickbox callback - 
	 * if we have a login form, run BuildLoginBehaviors. If the user 
	 * did not click a login link and we still have a thickbox, we must
	 * be targeting a thickbox, so set the targetsmodal value to true.</p>
	 *
	 * @return void
	 * @author Eric Shepherd
	 **/
	function commonThickboxCallback() {
		
				// Check for login form
		if (document.getElementById('form-login')) {
			if (!(tb_clickTarget.match(/login.html/))) {
				$('#login-targetsmodal').val('true');
			}
			buildLoginBehaviors();
			
				// Check for reset password form
		} else if (document.getElementById('form-reset-password')) {
			buildResetPasswordBehaviors();
		}
	}

	
/*************************************
          Live Help Setup
*************************************/

	/**
	 * <p>Sets up the extra class to apply to the live help container 
	 * to specify if we are online or offline.</p>
	 *
	 * @return		void
	 * @author		Matt Puchlerz
	 * @modified	Eric Shepherd - inserted interval checks so that we can avoid the slowness that is Volusion
	 **/
	function liveHelpInit() {
		
				// sets up the script insertion
		var liveHelp = document.getElementById('live-help');
		var volusionDiv = $('#VolusionLiveChat');
		var scriptTag = $('<script type="text/javascript" src="https://livechat.volusion.com/script.aspx?id=79144"></script>');
		volusionDiv.after(scriptTag);
		var count = 0;
		
				// sets an interval check for the live help div
		var isThereAnImage = setInterval(function() {
			count++;
			try {
				if (count > 10) { // we'll give up if it takes longer than 3 seconds for Volusion to respond
					clearInterval(isThereAnImage);
				}
				var liveHelpImg = liveHelp.getElementsByTagName('img')[0];
				if (liveHelpImg) {
					liveHelp.className += (liveHelpImg.src.match(/online/gi)) ? ' online' : ' offline';					
					clearInterval(isThereAnImage);
				}
			} catch (e) {}	
		}, 300);
	}

/*************************************
  Specific functionality for pages
*************************************/

	/**
	 * <p>Creates a string with pipe-delimited name/value 
	 * pairs for each form item in the elements collection.
	 * It's not technically a query string currently.</p>
	 *
	 * @param  elements			the dictionary to convert to string
	 * @return 					string containing name|value pairs separated by an ampersand
	 * @author Eric Shepherd
	 **/
	function buildFormQueryString(elements) {
		var queryString = '';
		for (var i=0; i<elements.length; i++) {
			queryString += elements[i].name + '|' + elements[i].value + '&';
		}
		return queryString;
	}


	/**
	 * <p>On Choose Set Attributes page, hides submits, prepares click 
	 * events, makes ajax call for next form. Also recurses on itself
	 * to add events to new ajax response.</p>
	 *
	 * @return void
	 * @author Eric Shepherd
	 **/
	function prepareSelectorForms() {
		
				// hides the submit buttons on the forms
		$('form.choose-attributes input:submit').hide();
		
				// adds the click event, removes existing events so we don't double them
		$('form.choose-attributes input:radio').unbind('click').click(function() {
			var thisReference = $(this);
			var currentForm = thisReference.parents('form');
			
					// deletes all forms after this one
			$(currentForm).nextAll().remove();
			
					// gets the input values for submission
			var postData = currentForm.find(':input').serialize();
			
					// makes the request
			var xhr = $.ajax({
				type 		: 'POST',
				url 		: 'ajax_choose_set_attributes.php',
				data 		: postData,
				dataType 	: 'html',
				success 	: function(msg) {
							// appends new form (or paragraph)
					msg = $.trim(msg); // jquery blows up if there are too many whitespaces or newlines in the response
					var newContent = $(msg);
					$('#inner-content-main').append(newContent);
					if (newContent.is('form')) {
						newContent.animate({ backgroundColor: highlightColor }, 300).animate({ backgroundColor: 'white' }, 1000);
					}
							// updates sidebar
					updatePromptDetails();
                            // inits modal links
					$('li.talent-audio a').unbind('click');
                    tb_init('form.choose-attributes a.thickbox');
				},
				complete : prepareSelectorForms
			});
		});
	}


	/**
	 * <p>Converts the example table to the real table on the upload page.</p>
	 *
	 * @return void
	 * @author Eric Shepherd
	 **/
	function stripExampleTable() {
		var existing = $('#example-container');
		var contents = existing.contents();
		
				// replaces old table with its inner contents
		existing.replaceWith(contents);
		
				// modifies table to remove example stuff
		$('h3.example').remove();
		$('#manual-entry-table').removeAttr('class').attr('summary', 'Current Prompt Set');
		$('#manual-entry-table tbody').empty();
	}


	/**
	 * <p>Currently sets the tooltip for notes, because Edit and 
	 * Delete are taken care of with thickbox class in HTML.</p>
	 *
	 * @return void
	 * @author Eric Shepherd
	 **/
	function setManualPromptEvents() {
				 // only run on items with title, because tooltips removes title attribute.
		$('#manual-entry-table').find('.manual-entry-actions-note[@title]').Tooltip();
		$('#form-manual-entry').find('input[@title], textarea[@title], label[@title]').Tooltip();
	}


/****************************************
 Custom prompts detail updater functions
****************************************/

	/**
	 * <p>A representation of the json details object associated.
	 * with the corresponding id of the html element which
	 * contains its data.</p>
	 */
	var promptDetails = {
		'count' 		: '#details-cost-number',
		'cost' 			: '#details-cost-cost',
		'language' 		: '#details-meta-language',
		'talent' 		: '#details-meta-talent',
		'platform' 		: '#details-meta-platform',
		'recordingFee' 	: '#details-totals-recording',
		'longPromptFee'	: '#details-totals-long-prompts',
		'subtotal' 		: '#details-totals-subtotal',
		'tax' 			: '#details-totals-tax',
		'total' 		: '#details-totals-total'
	};
	

	/**
	 * <p>Performs the get request and updates the prompt 
	 * detail sidebar with the json result.</p>
	 *
	 * @return void
	 * @author Eric Shepherd
	 **/
	function updatePromptDetails() {
		var result = $.getJSON('ajax_prompts_details.php', function(json) {
			
					// cycles through each item in the promptDetails object, compares to json
			for (var key in promptDetails) {
				
						// tests variable because we need empty string rather than undefined for html
				var jsonTest = json[key] || '&nbsp;';
				if (jsonTest != $(promptDetails[key]).html()) {
					var el = $(promptDetails[key]);
					el.hide().html(jsonTest).fadeIn('slow');
				}
			}

				// try to get rid of the click event for the a's if they exist
			try {
				$('a#submit-add-to-cart').attr('href', '#').removeClass('thickbox #modal').unbind('click').get(0).onclick = function(){ return false; };
				$('a#save-set').attr('href', '#').removeClass('thickbox #modal').unbind('click').get(0).onclick = function(){ return false; };
			} catch(e) {}
			
					// indicates visually whether there are prompts to move forward with or not
			if (json.canContinue === true) {
				$('a#submit-add-to-cart').attr('href', 'login.html?redirect=custom_prompts_tool%3Fstep%3Dconfirm%26add_to_cart_x').addClass('thickbox #modal');
				$('a#save-set').attr('href', 'login.html?redirect=custom_prompts_tool%3Fstep%3Dconfirm%26save_for_later_x').addClass('thickbox #modal');
				tb_init('a#submit-add-to-cart, a#save-set');
				$('#details-cost, #details-totals').removeClass('inactive');
				$('#details-submit input, #details-submit a').fadeTo('slow', '1.0').css('cursor', 'pointer').attr('disabled', '');
			} else {
				$('#details-cost, #details-totals').addClass('inactive');
				$('#details-submit input, #details-submit a').fadeTo('slow', '0.5').css('cursor', 'default').attr('disabled', 'disabled');
			}
		});
	}


/****************************************
            Login behaviors
****************************************/

	/**
	 * <p>Sets up the behaviors for the login modal window.</p>
	 *
	 * @return void
	 * @author Eric Shepherd
	 **/
	function buildLoginBehaviors() {
		
		try {
			var postData = '';
		
					// Focuses on the email input
			$('#email-address').focus();
							
// TODO: why the hell does this get called 4 times!?		
			var showSignup = function() {
				$('#forgot-password').hide();
				var confirmNode = $('label[for=password-confirmation]').parents('li');
				$('label[for=password]').text('Choose Password:').parents('li').insertBefore(confirmNode);
				$('#submit-login').attr('src', function() { this.src = this.src.replace(/signin/g, 'createaccount'); return this.src; } );
				$('#form-login-new').show();
			};
		
			var hideSignup = function() {
				$('#form-login-new').hide();
				var forgotNode = $('#forgot-password').parents('li');
				$('label[for=password]').text('Password:').parents('li').insertBefore(forgotNode);
				$('#submit-login').attr('src', function() { this.src = this.src.replace(/createaccount/g, 'signin'); return this.src; } );
				$('#forgot-password').show();
						// clears the hidden fields so we don't send bad information in the request
				$('#password-confirmation, #first-name, #last-name').clearForm();
			};
		
			hideSignup();
		
			$('#customer-existing').focus(hideSignup).click(hideSignup);
			$('#customer-new').focus(showSignup).click(showSignup);
		
					// sets the jsrequest hidden input to true
			$('#login-jsrequest').attr('value', 'true');
			
					// sets the submit event function
			$('#form-login').submit(function() {
				postData = $(this).find('input').serialize();

				var xhr = $.ajax({
					type 		: 'POST',
					url 		: $(this).attr('action'),
					data 		: postData,
					dataType 	: 'json',
					success 	: function(msg) {
						if (msg.uri) {
							window.location = msg.uri;
						} else if (msg.errors) {
									// builds the error collection from the provided json
							var errors = SMG.Json.convertToErrors(msg.errors);
									// clears existing error list and add new one
							$('ul.error').remove();
							var errorList = buildErrorList(errors);
							$('#form-login').prepend(errorList);
							toggleFieldErrorClasses(errors);
						} else if (msg.html) { // we get this if we're going to a modal and need to insert into the DOM
							$('#TB_ajaxContent').html(jQuery("<div/>").append(msg.html.replace(/<script(.|\s)*?\/script>/g, "")).find('#modal'));
						}
					},
					complete : function() {
					}
				});
				return false;
			});
		} catch(e) {
			console.log('SMG.pbxprompts.buildLoginBehaviors: Error. Are you sure this is being called on a login form?');
		}
	}
	
	
	/**
	 * <p>Builds an unordered list of errors given an SMG json error object.</p>
	 *
	 * @return			An unordered list of errors
	 * @param	errors	An SMG json error object
	 * @author 			Eric Shepherd
	 **/
	function buildErrorList(errors) {
		
				// creates a new list element
		var list = document.createElement('ul');
		list.className = 'error';
		
				// cycles through the errors, writes a list item for each of them
		for (var i=0; i<errors.length; i++) {
			for (var j=0; j<errors[i].getErrorMessages().length; j++) {
				var item = document.createElement('li');
				var text = document.createTextNode(errors[i].getErrorMessages()[j]);
				item.appendChild(text);
				list.appendChild(item);
			}
		}
		return list;
	}
	
	
	/**
	 * <p>Adds or removes error classes from all fields passed in a collection of SMG FormErrors.</p>
	 *
	 * @return			void
	 * @param	errors	A collection of SMG FormErrors
	 * @param	opts	An associative array of options indicating the behavior of the method
	 * @author			Eric Shepherd
	 **/
	function toggleFieldErrorClasses(errors, opts) {
		
				// options
		opts = opts || {};
		var options = {
			'add' : opts.add || true
		};
				// cycles through errors, writes error classes or removes them from dom elements
		for (var i=0; i<errors.length; i++) {
					// we know that the name field will always be form name[field name], we just don't know the form name
			var fieldDictionaryName = '[' + errors[i].getFieldName() + ']';
					// finds th element matching the bracketed field name
			var el = $('input[name*="' + fieldDictionaryName + '"]');
			if (el) {
				if (options.add) {
					el.addClass('error');
					$(el).focus(function() { $(this).removeClass('error'); });
				} else {
					el.removeClass('error');
				}
			}
		}
	}


/****************************************
       Reset Password Behaviors
****************************************/

	/**
	 * <p>Sets up the behaviors for the login modal window.</p>
	 *
	 * @return void
	 * @author Matt Puchlerz
	 **/
	function buildResetPasswordBehaviors() {
		try {

					// Focuses on the email input
			$('#email-address').focus();

					// sets the submit event function
			$('#form-reset-password').submit(function() {
				$.ajax({
					type 		: 'POST',
					url 		: $(this).attr('action'),
					data 		: $(this).find('input').serialize(),
					dataType 	: 'html',
					success 	: function(msg) {
						$('#TB_ajaxContent').html(jQuery("<div/>").append(msg.replace(/<script(.|\s)*?\/script>/g, "")).find('#modal'));
						buildResetPasswordBehaviors();
						tb_init('#modal a.thickbox');
					}
				});
				return false;
			});
			
		} catch(e) {
			console.log('SMG.pbxprompts.buildResetPasswordBehaviors: Error. Are you sure this is being called on a reset password form?');
		}
	}


/******************************************************
Main switch statement to handle page-specific branching
******************************************************/

	/**
	 * <p>Switches on page name property, runs page-specific
	 * scripts for effects and page behaviors.</p>
	 *
	 * @return void
	 * @author Eric Shepherd
	 **/
	function buildPageBehaviors() {
		
		switch (pageName) {
			
			case 'login-page' :
				buildLoginBehaviors();
				break;

			case 'upload-page' : 
			
						// toggles the help section
				var helpToggle = $('#headline-help');
				var itemToShow = $('#more-help-inner');
				if (helpToggle && itemToShow) {
					var isToggled = true;
					itemToShow.hide();
					helpToggle.bind('click', function(e) {
						if (isToggled === false) {
							itemToShow.slideUp('slow');
							isToggled = true;
						} else {
							itemToShow.slideDown('slow');
							isToggled = false;
						}
					});
				}
				
						// toggles the "advanced" option for prompt path
				if ($('#modal #prompt-path-container').length === 0) {
    				var pathContainer = $('#prompt-path-container');
    				var advancedMarkup = $('<span id="advanced-toggle" href="#">Advanced</span>');
				
    				pathContainer.hide();
    				$('#form-manual-entry fieldset').append(advancedMarkup);

    				advancedMarkup.toggle(
    				    function(){
        					pathContainer.show('normal');
        					$('#advanced-toggle').text('Simple');
        					return false;
        				},
        				function() {
        					pathContainer.hide('normal');
        					$('#advanced-toggle').text('Advanced');
        					return false;
        				}
        			);
    			}

						// validates the length of the prompt text
				var textarea = $('#prompt-text');
				var hasWarning = false;
				
						// processes the keypress - currently run every time a key is hit - we could use an interval also
				textarea.keypress(function(e) {
					var copy = textarea.attr('value') || '';
					var spaces = copy.match(/\s+/g) || '';
					var words = spaces.length + 1;
					if (words > manualPromptWordLimit) {
						if (hasWarning === false) {
							textarea.addClass('warning');
							$('label[for=prompt-text]').append('<em class="warning">Your prompt is longer than ' + manualPromptWordLimit + ' words. An additional charge of $<span>' + ((manualPromptAdditionalCharge * (words - 20)).toFixed(2)) + '</span> will apply to this prompt.</em>');
							hasWarning = true;
						} else {
							$('label[for=prompt-text] em span').html((manualPromptAdditionalCharge * (words - 20)).toFixed(2));
						}
					} else {
						textarea.removeClass('warning');
						$('label[for=prompt-text] em').remove();
						hasWarning = false;
					}
				});
				
						// defines the fragment id string
				var fragmentId = window.location.toString().match(/#\w*/);
				fragmentId = fragmentId ? fragmentId.toString() : '';

// TODO: Refactor this - it's damn ugly
// TODO: No, really. REFACTOR THIS SHIT CODE!

						// disables the submits
				$('#submit-upload').attr('disabled', 'disabled').css('cursor', 'default');

						// headlines to insert toggles into
				var manualHeadline = $('#upload-manual-box h3');
				var bulkHeadline = $('#upload-bulk-box h3');
				
						// boxes to toggle
				var manualBox = $('#upload-manual-box-inner');
				var bulkBox = $('#upload-bulk-box-inner');
				
						// text
				var minText = 'minimize';
				var maxText = 'maximize';
				
						// is box closed or open
				var bulkToggled = false;
				var manualToggled = false;
				
						// sets text and open state based on fragment id
				switch (fragmentId) {
					case '#manual' : 
						manualHeadline.append('<span>' + minText + '</span>');
						bulkHeadline.append('<span>' + maxText + '</span>');
						bulkToggled = true;
						bulkBox.hide();
						break;
					case '#bulk' :
						manualHeadline.append('<span>' + maxText + '</span>');
						bulkHeadline.append('<span>' + minText + '</span>');
						manualToggled = true;
						manualBox.hide();
						break;
				}
						// bulk box toggle events
				var bulkToggle = $('#upload-bulk-box h3');
				bulkToggle.bind('click', function(e) {
					if (bulkToggled === true) {
						bulkBox.slideDown('slow');
						bulkToggled = false;
						bulkToggle.find('span').text(minText);
						manualBox.slideUp('slow');
						manualToggled = true;
						manualToggle.find('span').text(maxText);
					} else {
						bulkBox.slideUp('slow');
						bulkToggled = true;
						bulkToggle.find('span').text(maxText);
						manualBox.slideDown('slow');
						manualToggled = false;
						manualToggle.find('span').text(minText);
					}
				});
						// manual box toggle events
				var manualToggle = $('#upload-manual-box h3');
				manualToggle.bind('click', function(e) {
					if (manualToggled === true) {
						manualBox.slideDown('slow');
						manualToggled = false;
						manualToggle.find('span').text(minText);
						bulkBox.slideUp('slow');
						bulkToggled = true;
						bulkToggle.find('span').text(maxText);
					} else {
						manualBox.slideUp('slow');
						manualToggled = true;
						manualToggle.find('span').text(maxText);
						bulkBox.slideDown('slow');
						bulkToggled = false;
						bulkToggle.find('span').text(minText);
					}
				});

						// sets up manual prompt action events
				setManualPromptEvents();
				
						// sets up submit button event for manual prompts				
				var manualSubmit = $('#submit-add-prompt');
				
						// calls ajax on click
				manualSubmit.click(function() {
					var currentForm = $('#form-manual-entry');
					var postData = currentForm.find(':input').serialize();
					var xhr = $.ajax({
						type 		: 'POST',
						url 		: 'ajax_add_prompts_to_set.php',
						data 		: postData,
						dataType 	: 'json',
						success 	: function(msg) {
									// runs function first time to get rid of example table
							if (document.getElementById('example-container')) {
								stripExampleTable();
							}
									// if not successful
							if (msg.success === false) {
										// if error already, remove
								if (document.getElementById('errors-container')) {
									$('#errors-container').remove();
								}
										// inserts errors
								$('#manual-entry-table').before(msg.html);
								for (var e in msg.errors) {
									$('#prompt-' + e).addClass('error').focus(function() {
										$(this).removeClass('error'); 
									});
								}
									// if successful
							} else if (msg.success === true) {
										// if errors present, removes all traces of them
								if (document.getElementById('errors-container')) {
									$('#errors-container').remove();
								}
								$('em.error').remove();
								$('em.warning').remove();
								$('.error').removeClass('error');
								$('.warning').removeClass('warning');
										// appends table row
								var newRow = $(msg.html);
								$('#manual-entry-table tbody').prepend(newRow);
								newRow.animate({ backgroundColor: highlightColor }, 300).animate({ backgroundColor: 'white' }, 1000);
										// updates details and clears form for next entry, initializes thickbox
										// TODO: might be good to create an object out of the recently entered item, 
										// so we can address it directly rather than clearing and re-initing everything
								updatePromptDetails();
								currentForm.clearForm();
								$('a.thickbox').unbind('click');
								tb_init('a.thickbox');
								$('#prompt-text').focus();
							} else {
								// TODO: what else is possible?
							}
						},
						complete : function() {
									// adds new prompt events, resets old events
							setManualPromptEvents();
						}
					});
					return false;
				});
				
						// sets up bulk upload submit event
				var bulkSubmit = $('#submit-upload');
				bulkSubmit.fadeTo(1, 0.5);
				$('#upload-file').change(function() {
					bulkSubmit.fadeTo('slow', 1.0).removeAttr('disabled').css('cursor', 'pointer');
				});
				
				break;

			case 'prompt-sets-page' :	
			
						// hides the submit button
				$('#form-find-prompts input:submit').hide();
				
						// adds click events to all checkboxes
				$('input:checkbox').click(function() {
					var ajaxData = '';
					var checkedElements = $('input:checked');
							// sets string of 'all' if we don't have anything checked. No checks == all checks
					ajaxData = buildFormQueryString(checkedElements) === '' ? 'all' : buildFormQueryString(checkedElements);
							// creates alert message
					var alertMessage = $('<p id="alert"><img src="includes/templates/template_pbxprompts/images/ajax-loader6.gif" alt="Loading" /></p>');
							// loads prompt browser, callback with sorting and pagination
					$('body').append(alertMessage);
					$('#find-prompts-container').fadeOut('fast').load('ajax_prompts_browser.php', {is_checked:ajaxData}, function() {
						tb_init('#find-prompts a.thickbox');
						fdTableSort.init();
                        tablePaginater.init();
						$(alertMessage).remove();
						$(this).fadeIn('fast');
						var label = $('<p class="pageLabel">Page: </p>');
						$('ul.tablePaginater').before(label);
						styleRows();
					});
				});
						// function to style rows and assign click trigger event
				var styleRows = function() {
							// sets row hover
					$('#find-prompts td').hover(
						function() {
							$(this).parent('tr').find('td').addClass('hover');
						},
						function() {
							$(this).parent('tr').find('td').removeClass('hover');
						}
					);
				};
				styleRows();

						// Inserts the page label
				var hasPaginationLoaded = setInterval(function() {
					if (document.getElementById('paginateList-find-prompts-clone')) {
						$('#find-prompts-container').trigger('click');
						var label = $('<p class="pageLabel">Page: </p>');
						$('ul.tablePaginater').before(label);
						clearInterval(hasPaginationLoaded);
					}
				}, 300);
						
				break;
				
			case 'pricing-page' :
				$('#set-pricing td').hover(
					function() {
						$(this).parent('tr').find('td').addClass('hover');
					},
					function() {
						$(this).parent('tr').find('td').removeClass('hover');
					}
				);
				break;

			case 'choose-attributes-page' :
				prepareSelectorForms(); // this is a separate function because it self-calls on complete of ajax
				break;
				
			case 'account-page' :
			
						// disables form fields and adds disabled class
				$('#form-account input:text, #form-account input:password, #form-account select').addClass('disabled');//.attr('disabled', 'disabled');
				
						// disables the submit button, then clones to each fieldset
				var submitButton = $('#form-account input:image');
				$(submitButton).addClass('save-changes').addClass('disabled').hide();//.attr('disabled', 'disabled');
				$('#form-account fieldset').append(submitButton.clone());
				
						// generates the edit links
				var editLink = $('<p class="edit"><a href="#">Edit</a></p>');
				$('#form-account fieldset').append(editLink);
				
						// sets the edit button event
				$('#form-account p.edit').click(function(){
					$(this).parent('fieldset').find('input:image').fadeIn('slow').removeClass('disabled');
					$(this).parent('fieldset').find('input:text, input:password, select').removeClass('disabled');//.attr('disabled', '');
					$(this).hide();
					return false;
				});
				
						// sets the focus event
				$('#form-account input:text, #form-account input:password, select').focus(function(){
					$(this).parents('fieldset').find('input:image').fadeIn('slow').removeClass('disabled');
					$(this).parents('fieldset').find('input:text, input:password, select').removeClass('disabled');
					$(this).parents('fieldset').find('p.edit').hide();
				});
				
						// hides the real submit button
				$(submitButton).hide();
				break;
				
			case 'prompt-set-manager-page' :
				$('.action-delete a').click(function() {
					window.tb_callback = function() {
								// calls common functions in case this generates a login
						SMG.pbxprompts.CommonThickboxCallback();

						var submitButton = $('#form-prompt-set-delete-submit');
								// grays out delete button
						submitButton.attr('disabled', 'disabled').addClass('disabled');
								// sets up event for checkbox
						$('#form-prompt-set-delete-confirm').change(function() {
							if ($(this).attr('checked')) {
								submitButton.attr('disabled', '').fadeTo('slow', 1).removeClass('disabled');
							} else {
								submitButton.attr('disabled', 'disabled').fadeTo('slow', 0.5).addClass('disabled');
							}
						});
								// returns this function to it's generic state. damn this is ugly.
								// TODO: figure out why Matt killed this and if it's necessary to reset the callback function somehow
						// window.tb_callback = function() {
						// 	return false;
						// }
						return false;
					};
					return false;
				});
				break;
				
			case 'history-page' :
				$('.order-history-detail a').click(function() {
					window.tb_callback = function() {
								// runs common callback functions in case this generates a login
						SMG.pbxprompts.CommonThickboxCallback();
						
						var el = document.getElementById('print');
						SMG.PageHelpers.addPrintLink.init(el, { linkText : 'Print this invoice' });
					};
				});
				break;
				
			case 'checkout-payment-page' :
			
						// first, shows the section which should be active and hides the rest
				$('.tab-content').hide();
				var id = $('#form-checkout-payment input:checked').attr('id');
				$('.' + id).show();
				
						// builds the new unordered list
				var ul = $('<ul id="payment-method-list"></ul>');
				$('h3.tab').each(function() {
					var liString = '<li id="li-' + $(this).attr('id') + '">' + $(this).html() + '</li>';
					var li = $(liString);
					ul.append(li);
				});
				
						// replaces the current headlines
				$('h3.payment-method-name').remove();
				$('#checkout-payment legend').after(ul);
				$('#' + id).attr('checked', 'checked');
				
						// sets up the click events to swap the payment method boxes
				$('#payment-method-list label').click(function(e) {
					$('.tab-content').hide();
					var attribute = this.getAttribute('for') ? this.getAttribute('for') : this.htmlFor; // frickin IE
					var correspondingDiv = $('.' + attribute);
					correspondingDiv.show();
				});
				
						// duplicates submit functionality at top of page
				var formEl = $('#form-checkout-payment');
				var newLink = $('<a id="form-checkout-submit-clone" href="#">Continue</a>');
				newLink.click(function() {
							// UGLY HACK! This calls a function hard-coded into the checkout_payment page, courtesy of Zen Cart!
					if (check_form()) {
						formEl.submit();
					}
					return false;
				});
				$('#inner-content-main').prepend(newLink);
				break;
				
			case 'checkout-confirmation-page' :
			
						// duplicates submit functionality at top of page, the next two vars are already defined in this file
				formEl = $('#form-place-order');
				newLink = $('<a id="form-place-order-submit-clone" href="#">Place Order</a>');
				newLink.click(function() {
					formEl.submit();
					return false;
				});
				$('#inner-content-main p.alert').append(newLink);
				break;
				
			case 'checkout-success-page' :
				var el = document.getElementById('print');
				SMG.PageHelpers.addPrintLink.init(el, { linkText : 'Print this invoice' });
				break;

			default : 
				break;
		}
	}

	return {
		
		/* public accessors */

		Init						: init,
		PageName					: pageName,
		BuildLoginBehaviors			: buildLoginBehaviors,
		BuildResetPasswordBehaviors	: buildResetPasswordBehaviors,
		CommonThickboxCallback		: commonThickboxCallback

	};

}();

		// runs the init when the dom is ready
if (typeof $ == 'function') {
	$(document).ready(function() {
		SMG.pbxprompts.Init();
	});
}


