/*
	Googlyzer
	Contact: Bill Edgar (bill.edgar@oaktondata.com)
	http://www.oaktondata.com/googlyzer
	
	Copyright (c) 2011-2012, Oakton Data LLC
	All rights reserved.

	Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
	    
	    * Redistributions of source code must retain the above copyright
	      notice, this list of conditions and the following disclaimer.
	    * Redistributions in binary form must reproduce the above copyright
	      notice, this list of conditions and the following disclaimer in the
	      documentation and/or other materials provided with the distribution.
	    * Neither the name of the Oakton Data LLC nor the
	      names of its contributors may be used to endorse or promote products
	      derived from this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
	ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
	DISCLAIMED. IN NO EVENT SHALL Oakton Data LLC BE LIABLE FOR ANY
	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
	
	This is the Googlyzer options javscript file - googlyzer.options.js
	
*/

// initialize global variable for php options array
if ( typeof( phpOptionsArray ) === 'undefined' ) {
	// replace escaped characters in json string
	var js_json_str = phpOPTIONS.json_str.replace(/&quot;/g, '"');
	// load with php options array
	if ( googlyzer_FunctionExists( 'parseJSON', 'jQuery' ) ) {
		phpOptionsArray = jQuery.parseJSON( js_json_str );
	} else {
		googlyzer_BrowserIssueAlert( 'jQuery.parseJSON' );
	}
}

/**
 * googlyzer_BrowserIssueAlert
 * 
 * function to send browser support issue alert to UI
 * 
 * inputs:
 * 
 * missingFunction		name of missing function
 * 
 * outputs:
 * 
 * none
 * 
 */
function googlyzer_BrowserIssueAlert( missingFunction ) {
	alert( 'Browser compatibility issue: ' + missingFunction + ' does not exist.' );
} // end function googlyzer_BrowserIssueAlert

/**
 * googlyzer_CheckDate
 * 
 * function for validation of date input fields on options page
 * 
 * inputs:
 * 
 * 		none
 * 
 * outputs:
 * 
 * 		none
 * 
 */
function googlyzer_CheckDate() {
	// grab dates from html doc and specify date format
	var start = document.getElementById( 'standard_start' );
	var end = document.getElementById( 'standard_end' );
	// correct format is mm-dd-yyyy
	var dateFormat = /^\d{2}[\-]\d{2}[\-]\d{4}$/;
	
	// verify start date format
	if ( !dateFormat.test( start.value ) ) {
		alert( 'Invalid start date format detected, please try again.' );
		start.value = googlyzer_GetDesiredDate( { 'change':'decrease', 'amount':30, 'format':'text' } );
	// verify end date format
	} else if ( !dateFormat.test( end.value ) ) {
		alert( 'Invalid date format detected, please try again.' );
		end.value = googlyzer_GetDesiredDate( { 'change':'', 'amount':0, 'format':'text' } );
	// date is valid, perform detailed checks
	} else {
		// grab pieces of start input date for detailed checks
		var start_month = start.value.split("-")[0];
		var start_day = start.value.split("-")[1];
		var start_year = start.value.split("-")[2];
		var start_input = new Date( start_year, start_month-1, start_day );
		// grab pieces of end input date for detailed checks
		var end_month = end.value.split("-")[0];
		var end_day = end.value.split("-")[1];
		var end_year = end.value.split("-")[2];
		var end_input = new Date( end_year, end_month-1, end_day );
		// grab current date for comparison
		var today = new Date ();
		// check start date for invalid day, month, or year
		if ( ( start_input.getMonth()+1 != start_month ) || ( start_input.getDate() != start_day ) || ( start_input.getFullYear() != start_year ) ) {
			alert( "Invalid Day, Month, or Year detected in start date field.  Please try again." );
			start.value = googlyzer_GetDesiredDate( { 'change':'decrease', 'amount':31, 'format':'text' } );
		// check end date for invalid day, month, or year
		} else if ( ( end_input.getMonth()+1 != end_month ) || ( end_input.getDate() != end_day ) || ( end_input.getFullYear() != end_year ) ) {
			alert( "Invalid Day, Month, or Year detected in end date field.  Please try again." );
			end.value = googlyzer_GetDesiredDate( { 'change':'decrease', 'amount':1, 'format':'text' } );
		// passed, keep checking
		} else {
			// check to make sure year is not before 2005
			if ( end_input.getFullYear() < 2005 || start_input.getFullYear() < 2005 ) {
				alert( "Year cannot be set prior to 2005.  Please try again." );
			// passed, keep checking
			} else {
				// make sure start date is before end date
				if ( end_input < start_input ) {
					alert( "Start date must be before end date.  Please try again." );
					start.value = googlyzer_GetDesiredDate( { 'change':'decrease', 'amount':31, 'format':'text' } );
					end.value = googlyzer_GetDesiredDate( { 'change':'decrease', 'amount':1, 'format':'text' } );
				// make sure end date is no later than today
				} else if ( end_input > today ) {
					alert( "Cannot set end of date range beyond today's date.  Please try again." );
					start.value = googlyzer_GetDesiredDate( { 'change':'decrease', 'amount':31, 'format':'text' } );
					end.value = googlyzer_GetDesiredDate( { 'change':'decrease', 'amount':1, 'format':'text' } );
				}
				// passed all checks if reaches here
			}
		}
	}
} // end function googlyzer_CheckDate

/**
 * googlyzer_CheckFields
 * 
 * function for validation of input fields on options page
 * 
 * inputs:
 * 
 * 		none
 * 
 * outputs:
 * 
 * 		none
 * 
 */
function googlyzer_CheckFields() {
	// check to make sure we're on right page and tab first
	// get current URL
	var page = document.location.href;
	
	if ( !page.match( /tab=about|tab=composites|tab=ga_tracking|tab=linecharts|tab=piecharts|tab=tables/ ) ) {
		// grab field values for validation
		var date_range = document.getElementById( 'standard_date_range' );
		var start = document.getElementById( 'standard_start' );
		var end = document.getElementById( 'standard_end' );
		var today = document.getElementById( 'standard_today_enable' );
		var ga_auth_status = document.getElementById( 'ga_auth_status' );
		// get current date for comparison
		var d = new Date();
		var month, day;
		// check for selected option in date_range field
		var selected = date_range.options[date_range.selectedIndex].value;
		// if custom is not selected, date fields should be disabled
		if ( selected !== "Custom Range" ){
			today.disabled=false;
			start.value='';
			start.disabled=true;
			start.style.backgroundColor = "#cccccc";
			end.value='';
			end.disabled=true;
			end.style.backgroundColor = "#cccccc";
		// otherwise enable date fields and insert default values if needed
		} else {
			today.checked='';
			today.disabled=true;
			// set options for start date field
			start.disabled=false;
			start.style.backgroundColor = "";
			// set start date value if necessary
			if ( start.value == "" ) {
				start.value = googlyzer_GetDesiredDate( { 'change':'decrease', 'amount':31, 'format':'text' } );
			}
			// set options for end date field
			end.disabled=false;
			end.style.backgroundColor = "";
			// set end date value if necessary
			if ( end.value == "" ) {
				end.value = googlyzer_GetDesiredDate( { 'change':'decrease', 'amount':1, 'format':'text' } );
			}
		}
		// set fields on Google authentication form based on status
		if ( ga_auth_status.value === "Authenticated." ) {
			googlyzer_UpdateElements( { 'GoogleAuthButton':'Logout' } );
			googlyzer_ToggleElements( 'disable', new Array( 'ga_email', 'ga_password' ) );
		} else {
			googlyzer_UpdateElements( { 'GoogleAuthButton':'Login' } );
			googlyzer_ToggleElements( 'enable', new Array( 'ga_email', 'ga_password' ) );
		}
	// ga_tracking settings
	} else if ( page.match( /tab=ga_tracking/ ) ) {
		// nothing for the moment
	} else if ( page.match( /tab=composites/ ) ) {
		var dimension = document.getElementById( 'composite1_dimensions' );
		var sort_column = document.getElementById( 'composite1_sort_column' );
		// reset sort column based on dimension selection
		sort_column.value = dimension.options[dimension.selectedIndex].value;
	// line chart settings
	} else if ( page.match( /tab=linecharts/ ) ) {
		var field_set = new Array( 'linechart1', 'linechart2', 'linechart3', 'linechart4' );
		for ( field in field_set ) {
			// get fields by element id
			var history = document.getElementById( field_set[field] + '_history_enable' );
			var trend = document.getElementById( field_set[field] + '_trend_enable' );
			var dimension = document.getElementById( field_set[field] + '_dimensions' );
			var sort_column = document.getElementById( field_set[field] + '_sort_column' );
			// disable or enable trend based on history selection
			if ( history.checked == true ) {
				trend.disabled=false;
			} else {
				trend.checked='';
				trend.disabled=true;
			}
			// reset sort column based on dimension selection
			// check for selected option in date_range field
			sort_column.value = dimension.options[dimension.selectedIndex].value;
		}
	} else if ( page.match( /tab=piecharts/ ) ) {
		var field_set = new Array( 'piechart1', 'piechart2' );
		for ( field in field_set ) {
			var chart_selection = document.getElementById( field_set[field] + '_chart_selection' );
			var max_results = document.getElementById( field_set[field] + '_max_results' );
			// reset sort column based on metric selection
			if ( chart_selection.options[chart_selection.selectedIndex].value == 'browser' ) {
				max_results.value = 4;
			} else {
				max_results.value = 1000;
			}
		}
	// table settings
	} else if ( page.match( /tab=tables/ ) ) {
		var field_set = new Array( 'table1', 'table2' );
		for ( field in field_set ) {
			var metric = document.getElementById( field_set[field] + '_metrics' );
			var sort_column = document.getElementById( field_set[field] + '_sort_column' );
			// reset sort column based on metric selection
			sort_column.value = metric.options[metric.selectedIndex].value;
		}
	}
} // end function googlyzer_CheckFields

/**
 * googlyzer_FormReset
 * 
 * function to reset options form fields
 * 
 * inputs:
 * 
 * 		none
 * 
 * outputs:
 * 
 * 		none
 * 
 */
function googlyzer_FormReset( myForm ) {
	// call form reset and run input field validation checks
	if ( myForm !== 'google_authentication_form' ) {
		document.getElementById( myForm ).reset();
		googlyzer_CheckFields();
		googlyzer_LoadTableID();
	} else {
		googlyzer_ShowHideElements( false, new Array( 'captcha_notification','captcha_instructions','captcha_img','captcha_response','captcha_description' ) );
		googlyzer_UpdateElements( { 'ga_auth_status':'', 'ga_email':'', 'ga_password':'' } );
	}
} // end function googlyzer_FormReset

/**
 * googlyzer_FunctionExists
 * 
 * function to verify existence of js or jQuery function
 * 
 * inputs:
 * 
 * functionName		name of function to be checked
 * type				either js or jQuery
 * 
 * outputs:
 * 
 * 0 if false (does not exist), otherwise true (exists)
 * 
 */
function googlyzer_FunctionExists( functionName, type ) {
	switch ( type ) {
		case 'jQuery':
			// jQuery function exists test
			if ( functionName in jQuery ) {
				return true;
			} else {
				return false;
			}
			break;
		case 'js':
			// javascript function exists test
			break;
	}
} // end function googlyzer_FunctionExists

/*
 * googlyzer_GetDesiredDate
 * 
 * function to return a desired date range in different string formats
 * 
 * inputs:
 * 
 * date		date input string formatted as yyyy-mm-dd
 * change	desired operation (increase or decrease)
 * amount	numeric amount of desired change in days (for example 30)
 * format	desired output format (text, obj, or ga_uri)
 * 
 * outputs:
 * 
 * text 	returns 'mm-dd-yyyy'
 * obj 		returns a javascript date object
 * ga_uri 	returns 'yyyy-mm-dd' (used for formulating Google Analytics feed requests)
 * 
 */
function googlyzer_GetDesiredDate( args ) {
	// set current date based on input
	if ( typeof args['date'] !== 'undefined' ) {
		var date_array = args['date'].split('-');
		var year = date_array[0];
		var month = date_array[1]-1;
		var day = date_array[2];
		// alert('date input = ' + args['date'] + 'year = ' + year + ' month = ' + month + ' day = ' + day );
		var d=new Date( year, month, day );
	} else {
		// set up variables for date operations
		var d=new Date(), month, day;
	}
	// switch based on requested operation and set d
	switch ( args['change'] ) {
		case 'increase':
			d.setDate( d.getDate()+args['amount'] );
			break;
		case 'decrease':
			d.setDate( d.getDate()-args['amount'] );
			break;
	}
	// don't forget to add one, month starts at 0, catch months < 10 for formatting
	if ( d.getMonth()+1 < 10 ) {
		month = "0" + ( d.getMonth() + 1 );
	// otherwise just get the month value and add 1
	} else {
		month = d.getMonth() + 1;
	}
	// if day is less than 10, add 0 to front
	if ( d.getDate() < 10 ) {
		day = "0" + d.getDate();
	// otherwise just get the day
	} else {
		day = d.getDate();
	}
	// set return value based on requested format
	switch ( args['format'] ) {
		case 'text':
			return month + "-" + day + "-" + d.getFullYear();
			break;
		case 'obj':
			return new Date( d.getFullYear(), d.getMonth(), d.getDate() );
			break;
		case 'ga_uri':
			return d.getFullYear() + "-" + month + "-" + day;
			break;
	}	
} // end function googlyzer_GetDesiredDate

function googlyzer_LoadTableID() {
	// check to make sure we're on right page and tab first
	// get current URL
	var page = document.location.href;
	if ( !page.match( /tab=about|tab=composites|tab=ga_tracking|tab=linecharts|tab=piecharts|tab=tables/ ) ) {
		// grab the website page element and selected index
		var select = document.getElementById('standard_website');
		var index = select.selectedIndex;		
		var ga_tableid = document.getElementById('standard_ga_tableid');
		// check to make sure index is valid
		if ( typeof index !== 'undefined' && index >= 0 ) {
			// set the table id based on current website selection
			ga_tableid.value = select.options[index].value;
		}
	}
}

/**
 * googlyzer_RestoreDefaults
 * 
 * function to restore default values to Googlyzer options page
 * 
 * inputs:
 * 
 * 		none
 * 
 * outputs:
 * 
 * 		none
 * 
 */
function googlyzer_RestoreDefaults() {
	// get current URL
	var doc = document.location.href;
	// grab tab name from URL
	if ( doc.match( /tab=composites/ ) ) {
		tab = 'composites';
	} else if ( doc.match( /tab=linecharts/ ) ) {
		tab = 'linecharts';
	} else if ( doc.match( /tab=piecharts/ ) ) {
		tab = 'piecharts';
	} else if ( doc.match( /tab=tables/ ) ) {
		tab = 'tables';
	} else if ( doc.match( /tab=ga_tracking/ ) ) {
		tab = 'ga_tracking';
	} else {
		tab = 'general';
	}
	// switch statement for different tabs
	switch ( tab ) {
		case 'composites' :
			// loop for each section on tab
			for ( var item in phpOptionsArray['googlyzer-composites']['defaults'] ) {
				// catch general options (for now)
				if ( !item.match( /general/ ) ) {
					// loop for each field in section
					for ( var field in phpOptionsArray['googlyzer-composites']['defaults'][item] ) { 
						var f = document.getElementById( item + '_' + field );
						if ( f == null ) {
							alert('could not find ' + item + '_' + field );
						}
						if ( f.type == 'text' && field.match( /color/ ) ) {
							googlyzer_UpdateBackground( item + '_' + field, phpOptionsArray['googlyzer-composites']['defaults'][item][field] );
						}
						f.value = phpOptionsArray['googlyzer-composites']['defaults'][item][field];
						if ( f.type === 'checkbox' && phpOptionsArray['googlyzer-composites']['defaults'][item][field] === 'enabled' ) {
							f.checked = 'checked';
						}
					}
				}
			}
			break;
		case 'general' :
			excludedFields = new Array( 'ga_auth_token', 'ga_beginning', 'ga_login', 'ga_password', 'ga_tableid', 'website' );
			// loop for each section on on tab
			for ( var item in phpOptionsArray['googlyzer-options']['defaults'] ) {
				// loopt for each field in section
				for ( var field in phpOptionsArray['googlyzer-options']['defaults'][item] ) { 
					if ( jQuery.inArray( field, excludedFields ) == -1 ) {
						var f = document.getElementById( item + '_' + field );
						f.value = phpOptionsArray['googlyzer-options']['defaults'][item][field];
						if ( f.type === 'checkbox' && phpOptionsArray['googlyzer-options']['defaults'][item][field] === 'enabled' ) {
							f.checked = 'checked';
						}
					}
				}
			}
			break;
		case 'ga_tracking' :
			// loop for each section on on tab
			for ( var item in phpOptionsArray['googlyzer-ga_tracking']['defaults'] ) {
				// loopt for each field in section
				for ( var field in phpOptionsArray['googlyzer-ga_tracking']['defaults'][item] ) { 
					var f = document.getElementById( item + '_' + field );
					f.value = phpOptionsArray['googlyzer-ga_tracking']['defaults'][item][field];
					if ( f.type === 'checkbox' && phpOptionsArray['googlyzer-ga_tracking']['defaults'][item][field] === 'enabled' ) {
						f.checked = 'checked';
					} else if ( f.type === 'checkbox' ) {
						f.checked = '';
					}
				}
			}
			break;
		case 'linecharts' :
			// loop for each section on tab
			for ( var item in phpOptionsArray['googlyzer-linecharts']['defaults'] ) {
				// catch general options (for now)
				if ( !item.match( /general/ ) ) {
					// loop for each field in section
					for ( var field in phpOptionsArray['googlyzer-linecharts']['defaults'][item] ) { 
						var f = document.getElementById( item + '_' + field );
						if ( f == null ) {
							alert('could not find ' + item + '_' + field );
						}
						if ( f.type == 'text' && field.match( /color/ ) ) {
							googlyzer_UpdateBackground( item + '_' + field, phpOptionsArray['googlyzer-linecharts']['defaults'][item][field] );
						}
						f.value = phpOptionsArray['googlyzer-linecharts']['defaults'][item][field];
						if ( f.type === 'checkbox' && phpOptionsArray['googlyzer-linecharts']['defaults'][item][field] === 'enabled' ) {
							f.checked = 'checked';
						}
					}
				}
			}
			break;
		case 'piecharts' :
			// loop for each section on tab
			for ( var item in phpOptionsArray['googlyzer-piecharts']['defaults'] ) {
				// catch general options (for now)
				if ( !item.match( /general/ ) ) {
					// loop for each field in section
					for ( var field in phpOptionsArray['googlyzer-piecharts']['defaults'][item] ) { 
						var f = document.getElementById( item + '_' + field );
						if ( f == null ) {
							alert( 'could not find ' + item + '_' + field );
						}
						if ( f.type == 'text' && field.match( /color/ ) ) {
							googlyzer_UpdateBackground( item + '_' + field, phpOptionsArray['googlyzer-piecharts']['defaults'][item][field] );
						}
						f.value = phpOptionsArray['googlyzer-piecharts']['defaults'][item][field];
						if ( f.type === 'checkbox' && phpOptionsArray['googlyzer-piecharts']['defaults'][item][field] === 'enabled' ) {
							f.checked = 'checked';
						}
					}
				}
			}
			break;
		case 'tables' :
			// loop for each section on tab
			for ( var item in phpOptionsArray['googlyzer-tables']['defaults'] ) {
				// catch general options (for now)
				if ( !item.match( /general/ ) ) {
					// loop for each field in section
					for ( var field in phpOptionsArray['googlyzer-tables']['defaults'][item] ) { 
						var f = document.getElementById( item + '_' + field );
						f.value = phpOptionsArray['googlyzer-tables']['defaults'][item][field];
						if ( f.type === 'checkbox' && phpOptionsArray['googlyzer-tables']['defaults'][item][field] === 'enabled' ) {
							f.checked = 'checked';
						}
					}
				}
			}
			break;
		default : // assume general if no tab indicated
			// loop for each section on on tab
			for ( var item in phpOptionsArray['googlyzer-options']['defaults'] ) {
				// loopt for each field in section
				for ( var field in phpOptionsArray['googlyzer-options']['defaults'][item] ) { 
					var f = document.getElementById( item + '_' + field );
					f.value = phpOptionsArray['googlyzer-options']['defaults'][item][field];
					if ( f.type === 'checkbox' && phpOptionsArray['googlyzer-options']['defaults'][item][field] === 'enabled' ) {
						f.checked = 'checked';
					}
				}
			}
			break;
	} // end switch for tabs
	// call function to validate fields
	googlyzer_CheckFields();
	googlyzer_LoadTableID();
} // end function googlyzer_RestoreDefaults

/*
 * googlzyer_SetSelectedIndex
 * 
 * function to update dropdown selection based on desired value
 * 
 * inputs:
 * 
 * field		dropdown field element
 * value		desired value
 * 
 * outputs:
 * 
 * 		none
 */
function googlzyer_SetSelectedIndex( field, value ) {
	for ( var i=0; i<field.options.length; i++ ) {
		if ( field.options[i].value = value ) {
			field.option[i].selected = true;
			return;
		}
	}
} // end function googlyzer_SetSelectedIndex

/**
 * googlyzer_ShowHideElements
 * 
 * function for display of list of html elements by id
 * 
 * inputs:
 * 
 * 		display			true=show, false=hide
 * 		myArray			standard array of html element id's
 * 
 * outputs:
 * 
 * 		none
 * 
 */
function googlyzer_ShowHideElements( display, myArray ) {
	var setting = ( display ) ? "block" : "none";
	// loop for each element in list
	for ( var key in myArray ) {
		// grab element by id
		var e = document.getElementById( myArray[key] );
		// if element exists
		if ( typeof e !== 'undefined' ) {
			// enable display
			e.style.display = setting;
		}
	}
}

/**
 * googlyzer_ToggleElements
 * 
 * updates html element values based on id
 * 
 * inputs:
 * 
 * 		myArray			standard array of html element id's to be disabled/enabled
 * 
 * outputs:
 * 
 * 		none
 * 
 */
function googlyzer_ToggleElements( change, myArray ) {
	// loop for each element in list
	for ( var key in myArray ) {
		// grab element by id
		var e = document.getElementById( myArray[key] );
		// if element exists
		if ( typeof e !== 'undefined' ) {
			if ( change === 'enable' ) {
				e.disabled = false;
			} else {
				e.disabled = true;
			}
		}
	}
}

/*
 * googlyzer_UpdateBackground
 * 
 * function to update background color of textfields on Googlyzer options page
 * 
 * inputs:
 * 
 * element_id		id of document textfield element to be updated
 * 
 * outputs:
 * 
 * 		none
 * 
 */
function googlyzer_UpdateBackground( element_id, color ) {
	var element = document.getElementById( element_id );
	element.style.backgroundColor = color;
} // end function googlyzer_UpdateBackground

/**
 * googlyzer_UpdateElements
 * 
 * updates html element values based on id
 * 
 * inputs:
 * 
 * 		myArray			associative array of html element id's (keys) and new values
 * 
 * outputs:
 * 
 * 		none
 * 
 */
function googlyzer_UpdateElements( myArray ) {
	// loop for each element in list
	for ( var key in myArray ) {
		// grab element by id
		var e = document.getElementById( key );
		// if element exists
		if ( typeof e !== 'undefined' ) {
			// if it's a checkbox
			if ( key.match( /enable/ ) ) {
				// update checkbox
				e.checked = myArray[key];
			// otherwise it's a standard input field
			} else {
				// update value
				e.value = myArray[key];
			}
		}
	}
}