/**
 * Assess :: Main Ajax Object for Independent Assessment Form
 * @copyright  Abid Saigol
 */
var page = new function () {

/**
 * Property Instances
 */
	this.DOM = null;
	this.Event = null;
	this.nw = null;
	
	this.occSource = null;
	this.fosSource = null;

	this.AC_Job = null;
	this.AC_Work = null;
	this.AC_Edu = null;
	this.AC_Spouse = null;
	this.AC_SpEdu = null;
	
	this.tableMods = null;
	this.eduTables = null;
	this.workTables = null;
	this.famTables = null;
	
	this.helpTip = null;
	this.nocTip = null;
	this.deleteTip = null;
	
	this.tboxInput = null;

/**
 * Initialization Methods
 */
	this.init = function () {
		var self = page;
		self.DOM = YAHOO.util.Dom;
		self.Event = YAHOO.util.Event;
		self.nw = NetWorth;

		var citVal = ( self.DOM.inDocument('citizenship_value') ? self.DOM.get('citizenship_value').value : "XX" );
		var resVal = ( self.DOM.inDocument('residence_value') ? self.DOM.get('residence_value').value : "XX" );
		// populate select statements
		//self.setSelectByClass( 'selectCountry', 'assess3', _select.country, _label.list.selectCountry );
		self.setSelectByClass( 'selectNumChildren', 'assess3', _select.num_children, _label.list.slct );
		self.setSelectByClass( 'selectLang', 'assess3', _select.lang, _label.list.slct );
		self.setSelect( 'citizenship', _select.country, null, _label.list.selectCountry, citVal );
		self.setSelect( 'residence', _select.country, null, _label.list.selectCountry, resVal );
		if ( resVal == 'CA' ) self.DOM.get('liv_question').innerHTML = _label.help.livY;

		self.setSelect( 'liv_province', _select.destinations, null, null );
		self.setSelect( 'job_province', _select.provinces, null, null );
		self.setSelect( 'sp_degree_type', _select.edu_degrees, null, null );
		self.setSelect( 'sp_degree_duration', _select.edu_duration, null, null);
		self.setSelect( 'sp_occ_duration', _select.work_duration, null, null);
		self.setSelect( 'sp_french', _select.spouse_french, null, null);

		// hide blocks
		self.DOM.setStyle( self.DOM.getElementsByClassName( 'frmHelp', '', 'assess3' ), 'display', 'none' );
		self.DOM.setStyle( self.DOM.getElementsByClassName( 'frmHelp', '', 'assess3' ), 'visibility', 'visible' );
		self.DOM.setStyle( self.DOM.getElementsByClassName( 'frmHidden', '', 'assess3'), 'display', 'none' );
		self.DOM.setStyle( self.DOM.getElementsByClassName( 'spHidden', '', 'assess3' ), 'display', 'none' );
		self.DOM.setStyle( self.DOM.getElementsByClassName( 'occHelp', '', 'assess3' ), 'display', 'none' );
		self.DOM.setStyle( 'tpl-mods', 'display', 'none' );

		// form submission and validation events
		self.Event.addListener( 'email', 'change', self.checkEmailInput );
		self.Event.addListener( 'form1', 'submit', self.preventSubmit ); //deactivate the return key
		self.Event.addListener( 'submitForm', 'click', self.submitForm ); //submit on click only

		// toggle event listeners
		self.Event.addListener( 'mStatusM', 'click', self.showSpouse );
		self.Event.addListener( 'mStatusU', 'click', self.showSpouse );
		self.Event.addListener( 'childrenY', 'click', self.showChildren );
		self.Event.addListener( 'childrenN', 'click', self.showChildren );
		self.Event.addListener( 'edu_hasY', 'click', self.showEducation );
		self.Event.addListener( 'edu_hasN', 'click', self.showEducation );
		self.Event.addListener( 'sp_edu_hasY', 'click', self.showSpouseEducation );
		self.Event.addListener( 'sp_edu_hasN', 'click', self.showSpouseEducation );
		self.Event.addListener( 'wrk_hasY', 'click', self.showWork );
		self.Event.addListener( 'wrk_hasN', 'click', self.showWork );
		self.Event.addListener( 'job_incanadaY', 'click', self.showJob );
		self.Event.addListener( 'job_incanadaN', 'click', self.showJob );
		self.Event.addListener( 'fam_incanadaY', 'click', self.showFamily );
		self.Event.addListener( 'fam_incanadaN', 'click', self.showFamily );

		// general event listeners
		var helpButtons = self.DOM.getElementsByClassName( 'helpButton', 'img', 'assess3' );
		self.Event.addListener( helpButtons, 'click', self.showHelp );
		self.Event.addListener( 'residence', 'change', self.setResidence );
		self.Event.addListener( self.DOM.getElementsByClassName('edu_radio', '', 'assess3'), 'click', self.setSecondary );
		self.Event.addListener( 'add_degree', 'click', self.addEduTable );
		self.Event.addListener( 'add_work', 'click', self.addWorkTable );
		self.Event.addListener( 'add_fam', 'click', self.addFamTable );
		
		// set highlighting on focussed elements
		self.Event.addListener( document.getElementsByTagName('input'), 'focus', self.addOutline );
		self.Event.addListener( document.getElementsByTagName('input'), 'blur', self.remOutline );
		self.Event.addListener( document.getElementsByTagName('textarea'), 'focus', self.addOutline );
		self.Event.addListener( document.getElementsByTagName('textarea'), 'blur', self.remOutline );
		// remove listeners from the static autocomplete elements
		self.Event.removeListener( self.DOM.getElementsByClassName( 'ac_input', '', 'assess3' ), 'focus', self.addOutline );
		self.Event.removeListener( self.DOM.getElementsByClassName( 'ac_input', '', 'assess3' ), 'blur', self.remOutline );

		// auto-complete data sources and arrays
		self.initACSources();
		self.AC_Work = new Array();
		self.AC_Edu = new Array();

		// modules tables
		self.eduTables = new Array();
		self.workTables = new Array();
		self.famTables = new Array();

		// setup the module templates
		self.setSelectByClass( 'selectDegreeType', 'edu-tpl', _select.edu_degrees, null );
		self.setSelectByClass( 'selectDegreeDuration', 'edu-tpl', _select.edu_duration, null );
		self.setSelectByClass( 'selectDegreeLocation', 'edu-tpl', _select.country, _label.list.selectCountry );
		self.setSelectByClass( 'selectDegreeHowLongAgo', 'edu-tpl', _select.edu_howlongago, null );
		self.setSelectByClass( 'selectDegreeProv', 'edu-tpl', _select.provinces, null );
		self.setSelectByClass( 'selectDegreeVisa', 'edu-tpl', _select.edu_visaTypes, null );
		self.DOM.setStyle( self.DOM.getElementsByClassName( 'deg_locationinfo', 'tr', 'edu-tpl' ), 'display', 'none' );

		self.setSelectByClass( 'selectWorkDuration', 'work-tpl', _select.work_duration, null );
		self.setSelectByClass( 'selectWorkHowLongAgo', 'work-tpl', _select.work_howlongago, null );
		self.setSelectByClass( 'selectWorkLocation', 'work-tpl', _select.work_location, null );
		self.setSelectByClass( 'selectWorkType', 'work-tpl', _select.work_type, null );
		self.setSelectByClass( 'selectWorkProv', 'work-tpl', _select.provinces, null );
		//self.DOM.setStyle( 'wrk-occHelpTABINDEX', 'display', 'none' );
		self.DOM.setStyle( self.DOM.getElementsByClassName( 'wrk_provinfo', 'tr', 'work-tpl' ), 'display', 'none' );
		self.DOM.setStyle( self.DOM.getElementsByClassName( 'wrk_visainfo', 'tr', 'work-tpl' ), 'display', 'none' );

		self.setSelectByClass( 'selectFamRelation', 'fam-tpl', _select.fam_relations, null );
		self.setSelectByClass( 'selectFamStatus', 'fam-tpl', _select.fam_status, null );
		self.setSelectByClass( 'selectFamProv', 'fam-tpl', _select.provinces, null );
		self.setSelectByClass( 'selectFamSince', 'fam-tpl', _select.fam_since, null );
		// acquire the modules templates
		self.tableMods = new Array();
		self.tableMods['edu'] = self.DOM.get('edu-tpl').innerHTML;
		self.tableMods['work'] = self.DOM.get('work-tpl').innerHTML;
		self.tableMods['fam'] = self.DOM.get('fam-tpl').innerHTML;
		self.DOM.get('tpl-mods').innerHTML = '';

		// create tool tips
		self.helpTip = new YAHOO.widget.Tooltip( 'helpText', { context:helpButtons, text:_label.help.tip1 } );
		self.initToolTips();

		// initialize external objects
		self.nw.init();
		selector.init('independent');
		//*/
	}

	// update the tool tip setup
	this.initToolTips = function () {
		var self = page;
		var nocImgs = self.DOM.getElementsByClassName( 'noc-tip', 'img' );
		self.nocTip = new YAHOO.widget.Tooltip( 'NOCTip', { context:nocImgs } );
		var deleteButtons = self.DOM.getElementsByClassName( 'table_delete_image', 'img' );
		self.deleteTip = new YAHOO.widget.Tooltip( 'deleteText', { context:deleteButtons, text:_label.help.tipDelete } );
	}

	// create the auto-complete data sources
	this.initACSources = function () {
		var self = page;
		// generate the url
		var loc = window.location.href;
		var url = loc.substr(0, loc.lastIndexOf('/')) + '/index.php?';
		// create the occ source connection
		self.occSource = new YAHOO.util.XHRDataSource(url);
		self.occSource.connXhrMode = 'cancelStaleRequests';
		self.occSource.responseType = YAHOO.util.XHRDataSource.TYPE_JSON;
		self.occSource.responseSchema = {
			resultsList : 'response.data',
			fields : [
				{ key: 'title' },
				{ key: 'noc' }
			],
			metaFields : {
				totalRecords : 'response.rows'
			}
		};
		// create the fos source connection
		self.fosSource = new YAHOO.util.XHRDataSource(url);
		self.fosSource.connXhrMode = 'cancelStaleRequests';
		self.fosSource.responseType = YAHOO.util.XHRDataSource.TYPE_JSON;
		self.fosSource.responseSchema = {
			resultsList : 'response.data',
			fields : [
				{ key: 'field_of_study' }
			],
			metaFields : {
				totalRecords : 'response.rows'
			}
		};
	}
	
/**
 * General Helper Methods
 */
 	// to add and remove highlighting on focus
	this.addOutline = function ( el ) {
		var self = page;
		self.DOM.replaceClass( this, '', 'fcs' );
	}
	
	this.remOutline = function ( el ) {
		var self = page;
		self.DOM.removeClass( this, 'fcs' );
	}

	// populate select elements
	this.setSelect = function ( el, opts, app, hd, slctval ) {
		var self = page;
		
		if ( !self.DOM.inDocument(el) ) return;
		var e = self.DOM.get(el);
		if ( e.options ) {

			if ( app !== true ) {
				while ( e.options.length ) e.options[0] = null;
			}
			
			var o = new Option( (YAHOO.lang.isString(hd)?hd:_label.list.pleaseSelect), "XX", false, (slctval!=null?false:true) );
			e.options[0] = o;
			
			for ( var k in opts ) {
				var o = new Option( k, opts[k], false, (opts[k]==slctval?true:false) );
				e.options[e.options.length] = o;
			}
			
		}
		
	}
	
	this.setSelectByClass = function ( cls, docrt, opts, hd, slctval ) {
		var self = page;
		
		var el = self.DOM.getElementsByClassName( cls, 'select', docrt );
		if ( el.length ) {
			for ( var k in el ) self.setSelect( el[k], opts, false, hd, slctval );
		}
			
	}
	
	// set the value of an element matching a radio button
	this.setRadioValue = function ( el ) {
		var self = page;
		var src = this.name;
		var target = self.DOM.get(src+'_val');
		target.value = this.value;
	}

	// set visibility based upon button status
	this.showWithButton = function ( button, target ) {
		var self = page;
		self.DOM.setStyle( target, 'display', (button.checked ? '' : 'none') );
	}
	
	// removes all child nodes of a given node
	this.removeChildren = function ( node ) {
		var self = page;
		if ( self.DOM.inDocument( node ) ) {
			var children = self.DOM.getChildren(node);
			for ( var i=0; i < children.length; i++ ) {
				node.removeChild(children[i]);
			}
		}
	}
	
	this.disableAll = function ( block, tag ) {
		var self = page;
		block = self.DOM.get(block);
		var nodes = block.getElementsByTagName(tag);
		for ( var i=0; i < nodes.length; i++ ) {
			nodes[i].disabled = true;
		}
	}
	
	this.enableAll = function ( block, tag ) {
		var self = page;
		block = self.DOM.get(block);
		var nodes = block.getElementsByTagName(tag);
		for ( var i=0; i < nodes.length; i++ ) {
			nodes[i].disabled = false;
		}
	}
	
	this.in_array = function ( needle, haystack ) {
		for ( var key in haystack ) {
			if ( haystack[key] == needle ) return true;
		}
		return false;
	}
	
/**
 * Form Handlers
 */
	this.preventSubmit = function ( e ) {
		var self = page;
		self.Event.preventDefault(e);
		return false;
	}
	
	this.submitForm = function ( e ) {
		var self = page;
		// reset errors
		self.DOM.removeClass( self.DOM.getElementsByClassName('has_error', '', 'assess3'), 'has_error' );
		var hasError = false;
		// validate the form areas
		var areas = [ 'meta','profile', 'lang', 'edu', 'work'];//, 'networth', 'job', 'spouse', 'fam' ];
		for ( var k=0; k < areas.length; k++ ) {
			if ( self.validate(areas[k]) == false ) {
				if ( areas[k] != 'work' && areas[k] != 'edu' ) self.DOM.addClass( areas[k]+'_area', 'has_error' );
				hasError = true;
			}
		}
		//*/
		// form has errors, alert and return
		if ( hasError == true ) {
			window.scrollTo(0, 550);
			alert(_label.err.form);
			return false;
		}
		
		// remove any leftover modules
		if ( self.DOM.get('edu_hasN').checked ) self.removeChildren( self.DOM.get('edu_tables') );
		if ( self.DOM.get('wrk_hasN').checked ) self.removeChildren( self.DOM.get('work_tables') );
		if ( self.DOM.get('fam_incanadaN').checked ) self.removeChildren( self.DOM.get('fam_tables') );
		// submit after enabling and populating all form elements (required for back-end handling)
		var f = self.DOM.get('form1');
		for ( var i=0; i < f.elements.length; i++ ) {
			if ( f.elements[i].disabled && f.elements[i].disabled == true ) f.elements[i].disabled = false;
			if ( f.elements[i].options && f.elements[i].length == 0 ) {
				var o = new Option( _label.list.pleaseSelect, 'XX', false, true );
				f.elements[i].options[0] = o;
			}
		}
		f.submit();
	}
	
/**
 * Validation Handlers
 */
	this.validate = function ( area ) {
		var self = page;
		var isValid = true;
		// specific area checks
		switch ( area ) {
			case 'meta':
				self.DOM.get('phone').disabled = true;
				isValid = self.checkEmailInput() && isValid;
				isValid = self.allInputValid('meta_area') && isValid;
				//isValid = self.allSelectValid('meta_area') && isValid;
				self.DOM.get('phone').disabled = false;
				break;
			case 'profile':
				//if ( !self.DOM.get('childrenY').checked ) self.disableAll('children_info','select');
				//isValid = self.allSelectValid('profile_area') && isValid;
				isValid = self.allInputValid('profile_area') && isValid;
				isValid = self.allRadioValid('profile_area') && isValid;
				//self.enableAll('children_info','select');
				break;
			case 'networth':
				self.DOM.get('wth_currency').disabled = true;
				isValid = self.allSelectValid('networth_area') && isValid;
				self.DOM.get('wth_currency').disabled = false;
				break;
			case 'lang':
				isValid = self.validLanguage() && isValid;
				break;
			case 'edu':
				isValid = self.allRadioValid('edu_info') && isValid;
				if ( self.DOM.get('edu_hasY').checked ) {
					for ( var i in self.eduTables ) {
						if ( self.eduTables[i] != null && self.eduTables.length > (i+1) ) isValid = self.validEduBlock(i) && isValid;
					}
				}
				break;
			case 'work':
				isValid = self.allRadioValid('work_info') && isValid;
				if ( self.DOM.get('wrk_hasY').checked ) {
					for ( var i in self.workTables ) {
						if ( self.workTables[i] != null && self.workTables.length > (i+1) ) isValid = self.validWorkBlock(i) && isValid;
					}
				}
				break;
			case 'job':
				if ( self.DOM.get('job_incanadaY').checked ) {
					isValid = self.allInputValid('job_area') && isValid;
					isValid = self.allSelectValid('job_area') && isValid;
					isValid = self.allRadioValid('job_area') && isValid;
				}
				break;
			case 'spouse':
				if ( self.DOM.get('mStatusM').checked ) {
					if ( !self.DOM.get('sp_edu_hasY').checked ) {
						self.disableAll('sp_education_details','select');
						self.disableAll('sp_education_details','input');
					}
					isValid = self.allSelectValid('spouse_area') && isValid;
					isValid = self.allInputValid('spouse_area') && isValid;
					isValid = self.allRadioValid('spouse_area') && isValid;
					self.enableAll('sp_education_details','select');
					self.enableAll('sp_education_details','input');
				}
				break;
			case 'fam':
				if ( self.DOM.get('fam_incanadaY').checked ) {
					for ( var i in self.famTables ) {
						if ( self.famTables[i] != null ) isValid = self.validFamBlock(i) && isValid;
					}
				}
				break;
			// default check
			default:
		}
		return isValid;
	}

	this.checkEmailInput = function ( el ) {
		var self = page;
		var email = self.DOM.get('email');
		self.DOM.removeClass(self.DOM.getAncestorByTagName( email, 'tr' ), 'has_error');
		email.value = YAHOO.lang.trim(email.value);
		if ( !self.validEmail(email.value) ) {
			self.DOM.addClass(self.DOM.getAncestorByTagName( email, 'tr' ), 'has_error');
			return false;
		}
		return true;
	}
	
	this.validEmail = function ( str ) {
		var self = page;
		// establish parameters
		var emailValid = true;
		var at="@";
		var dot=".";
		var lat=str.indexOf(at);
		var lstr=str.length;
		// must be an @, but not in the first or last position
		if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr) emailValid = false;
		// must be a dot, but in the first or last position
		if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr) emailValid = false;
		// there cannot be more than one @
		if (str.indexOf(at,(lat+1))!=-1) emailValid = false;
		// dot cannot be right before or right after the @
		if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot) emailValid = false;
		// there must be a dot after the @ but not right after
		if (str.indexOf(dot,(lat+2))==-1) emailValid = false;
		// there can be no spaces in the email address
		if (str.indexOf(" ")!=-1) emailValid = false;
		// if valid return true else set error notice and return false
		return emailValid;
	}
	
	this.validLanguage = function () {
		var self = page;
		// init counters
		var score = new Array();
		score['en'] = 0;
		score['fr'] = 0;
		// loop through selectors and add one for the language if selection greater than zero
		var els = self.DOM.getElementsByClassName( 'selectLang', 'select', 'assess3' );
		for ( var i=0; i < els.length; i++ ) {
			if ( els[i].selectedIndex > 0 ) score[ els[i].name.substr(0,2) ]++;
		}
		// at least one language must have all four selections
		return ( score['en'] == 4 || score['fr'] == 4 ? true : false );
	}
	
	// checks all select statements and returns true if all have selections
	this.allSelectValid = function ( block ) {
		var self = page;
		var isValid = true;
		// check all select elements, except disabled or zero length elements
		var node = self.DOM.get(block);
		var elements = node.getElementsByTagName('select');
		for ( var k=0; k < elements.length; k++ ) {
			if ( elements[k].disabled == true || elements[k].length == 0 ) continue;
			if ( elements[k].selectedIndex == 0 ) {
				self.DOM.addClass( self.DOM.getAncestorByTagName(elements[k],'tr'), 'has_error' );
				isValid = false;
			}
		}
		return isValid;
	}
	
	// checks all text and textarea elements and returns true if all have length > 0
	this.allInputValid = function ( block ) {
		var self = page;
		var isValid = true;
		// check all input elements
		var node = self.DOM.get(block);
		var elements = node.getElementsByTagName('input');
		for ( var k=0; k < elements.length; k++ ) {
			if ( elements[k].disabled == true || elements[k].type == 'radio' || elements[k].type == 'hidden' ) continue;
			if ( elements[k].value.length == 0 ) {
				self.DOM.addClass( self.DOM.getAncestorByTagName(elements[k],'tr'), 'has_error' );
				isValid = false;
			}
		}
		return isValid;
	}
	
	// checks all radio button and returns true if all groups have 1 checked
	this.allRadioValid = function ( block ) {
		var self = page;
		var isValid = true;
		// first find all radio button group names
		var radios = new Array;
		var node = self.DOM.get(block);
		var elements = node.getElementsByTagName('input');
		for ( var k=0; k < elements.length; k++ ) {
			if ( elements[k].type != 'radio' ) continue;
			var n = elements[k].name;
			if ( !self.in_array(n, radios) ) radios.push(n);
		}
		// now check each group
		var form = self.DOM.get('form1');
		for ( var k=0; k < radios.length; k++ ) {
			var isChecked = false;
			var r = form.elements[radios[k]];
			for ( var x=0; x < r.length; x++ ) {
				if ( r[x].checked ) {
					isChecked = true;
				}
				lastr = r[x].id;
			}
			if ( !isChecked ) {
				self.DOM.addClass( self.DOM.getAncestorByTagName( lastr,'td'), 'has_error' );
				isValid = false;
			}
		}
		return isValid;
	}
	
/**
 * Event Handler Methods
 */
	this.showHelp = function ( el ) {
		var self = page;
		var target = self.DOM.get('help-'+this.id);
		// toggle the help button and container
		if ( this.src.indexOf('.off.') == -1 ) {
			this.src = this.src.replace('.on.','.off.');
			self.DOM.setStyle( target, 'display', 'none');
		} else {
			this.src = this.src.replace('.off.','.on.');
			self.DOM.setStyle( target, 'display', '' );
		}
	}
	
	this.showSpouse = function ( el ) {
		var self = page;
		self.showWithButton( self.DOM.get('mStatusM'), self.DOM.getElementsByClassName('spHidden', '', 'assess3') );
		self.AC_Spouse = ( self.DOM.get('mStatusM').checked ? self.newOccAC( 'ac-sp-occupation', 'ac-sp-container' ) : null );
	}
	
    this.showChildren = function ( el ) {
        var self = page;
		var button = self.DOM.get('childrenY');
		self.showWithButton( button, self.DOM.get('children_info') );
		if ( button.checked ) self.DOM.get('children12').focus();
    }
	
	this.showEducation = function ( el ) {
		var self = page;
		var button = self.DOM.get('edu_hasY');
		var button2 = self.DOM.get('edu_secondaryY');
		self.DOM.get('education_level').value = ( button.checked ? 'post-secondary' : ( button2.checked ? 'secondary' : 'none' ) );
		self.showWithButton( button, self.DOM.get('education_details') );
		if ( button.checked && self.eduTables.length == 0 ) self.addEduTable();
	}
	
	this.showSpouseEducation = function ( el ) {
		var self = page;
		var button = self.DOM.get('sp_edu_hasY');
		var button2 = self.DOM.get('sp_edu_secondaryY');
		self.DOM.get('sp_education_level').value = ( button.checked ? 'post-secondary' : ( button2.checked ? 'secondary' : 'none' ) );
		self.showWithButton( button, self.DOM.get('sp_education_details') );
		self.AC_SpEdu = ( button.checked ? self.newFosAC( 'ac-spdeg-fos', 'ac-spfos-cont' ) : null );
		if ( button.checked ) self.DOM.get('sp_degree_type').focus();
	}
	
	this.showWork = function ( el ) {
		var self = page;
		var button = self.DOM.get('wrk_hasY');
		self.showWithButton( button, self.DOM.get('work_details') );
		if ( button.checked && self.workTables.length == 0 ) self.addWorkTable();
	}
	
	this.showJob = function ( el ) {
		var self = page;
		var button = self.DOM.get('job_incanadaY');
		self.showWithButton( button, self.DOM.get('job_details') );
		self.AC_Job = ( button.checked ? self.newOccAC( 'ac-job-occupation', 'ac-job-container' ) : null );
		if ( button.checked ) self.DOM.get('ac-job-occupation').focus();
	}
	
	this.showFamily = function ( el ) {
		var self = page;
		var button = self.DOM.get('fam_incanadaY');
		self.showWithButton( button, self.DOM.get('fam_details') );
		if ( button.checked && self.famTables.length == 0 ) self.addFamTable();
	}
	
	this.setResidence = function ( el ) {
		var self = page;
		var res = this.options[this.selectedIndex].value;
		self.DOM.get('liv_question').innerHTML = ( res == 'CA' ? _label.help.livY : _label.help.livN );
	}

	this.setSecondary = function ( el ) {
		var self = page,
			target = self.DOM.get( (this.id.indexOf('sp_') == -1 ? '' : 'sp_') + 'education_level' );
		if ( target.value != 'post-secondary' ) target.value = ( this.id.indexOf('Y') == -1 ? 'none' : 'secondary' );
	}

/**
 * Occupation Auto-Complete Methods
 */
	this.newOccAC = function ( inputEl, containerEl ) {
		var self = page;
		var Obj = new YAHOO.widget.AutoComplete(inputEl, containerEl, self.occSource);
		Obj.generateRequest = function(sQuery){ return "lang="+LANGUAGE+"&module=ajax&action=gettitles&occ="+sQuery; };
		Obj.minQueryLength = 2;
		Obj.maxResultsDisplayed = 100;
		Obj.useIFrame = true;
		Obj.textboxKeyEvent.subscribe(self.setKeypress);
		Obj.itemSelectEvent.subscribe(self.occSelectHandler);
		Obj.textboxFocusEvent.subscribe(self.showOccHelp);
		Obj.textboxBlurEvent.subscribe(self.hideOccHelp);
		return Obj;
	}

	this.setKeypress = function ( sType, aArgs ) {
		var self = page;
		self.tboxInput = true;
		self.DOM.setStyle( 'occTip', 'visibility', 'visible' );
	}

	this.occSelectHandler = function (sType, aArgs) {
		var self = page;
		// first get input element id
		var oObj = aArgs[0];
		var oEl = oObj.getInputEl();
		var inID = oEl.id.replace('ac-', '');
		// now set noc value using input element id
		var oX = aArgs[2];
		self.DOM.get('noc-'+inID).value = oX[1];
		self.DOM.get('tip-'+inID).title = "NOC: "+oX[1];
		// reset the keypress monitor
		self.tboxInput = false;
		self.DOM.setStyle( 'occTip', 'visibility', 'hidden' );
		oEl.focus();
	}

	this.showOccHelp = function ( sType, aArgs ) {
		var self = page;
		// first get input element id
		var oObj = aArgs[0];
		var oEl = oObj.getInputEl();
		self.DOM.addClass( oEl, 'fcs' );
		//
		self.DOM.setXY( 'occTip', [ self.DOM.getX(oEl), self.DOM.getY(oEl)+23 ] );
		self.DOM.setStyle( 'occTip', 'visibility', 'visible' );
		//
		var table = self.DOM.getAncestorByClassName( oEl, 'mod-table' );
		self.DOM.setStyle( self.DOM.getElementsByClassName( 'occHelp', '', table ), 'display', '' );
		// reset the keypress monitor
		self.tboxInput = false;
	}
	
	this.hideOccHelp = function ( sType, aArgs ) {
		var self = page;
		// first get input element id
		var oObj = aArgs[0];
		var oEl = oObj.getInputEl();
		self.DOM.removeClass( oEl, 'fcs' );
		//
		self.DOM.setStyle( 'occTip', 'visibility', 'hidden' );
		self.DOM.setXY( 'occTip', [ 0, 0 ] );
		//
		var table = self.DOM.getAncestorByClassName( oEl, 'mod-table' );
		self.DOM.setStyle( self.DOM.getElementsByClassName( 'occHelp', '', table ), 'display', 'none' );
		// clear noc containers if keypress monitor true
		if ( self.tboxInput ) {
			var inID = oEl.id.replace('ac-', '');
			self.DOM.get('noc-'+inID).value = '';
			self.DOM.get('tip-'+inID).title = 'Empty';
		}
	}
	
/**
 * Field of Study Auto-Complete Generic Method
 */
	this.newFosAC = function ( inputEl, containerEl ) {
		var self = page;
		var Obj = new YAHOO.widget.AutoComplete(inputEl, containerEl, self.fosSource);
		Obj.generateRequest = function(sQuery){ return "lang="+LANGUAGE+"&module=ajax&action=getfos&fos="+sQuery; };
		Obj.minQueryLength = 2;
		Obj.maxResultsDisplayed = 100;
		Obj.useIFrame = true;
		return Obj;
	}


/**
 * Education Table Methods
 */
	this.addEduTable = function () {
		var self = page;
		var tabIndex = self.eduTables.length;
		// check previous table
		if ( tabIndex > 0 && !self.validEduBlock(tabIndex-1) ) {
			alert(_label.err.ind3);
			self.eduTables[(tabIndex-1)].element.getElementsByTagName('select')[0].focus();
			return false;
		}
		// activate new table module
		var tab = new YAHOO.widget.Module('edu-t'+tabIndex);
		var modStr = self.tableMods['edu'].replace(/TABINDEX/g,tabIndex);
		tab.setBody( modStr );
		tab.render(self.DOM.get('edu_tables'));
		tab.show();
		self.eduTables[tabIndex] = tab;
		self.AC_Edu[tabIndex] = self.newFosAC( 'ac-deg-fos'+tabIndex, 'ac-fos-cont'+tabIndex );
		self.Event.addListener( self.DOM.getElementsByClassName( 'selectDegreeType', 'select', tab.id ), 'change', self.handleEvalDegreeType, tab.id );
		self.Event.addListener( self.DOM.getElementsByClassName( 'selectDegreeLocation', 'select', tab.id ), 'change', self.handleEduLocation, tab.id );
		self.Event.addListener( self.DOM.getElementsByClassName( 'selectDegreeHowLongAgo', 'select', tab.id ), 'change', self.handleEduHowLongAgo, tab.id );
		self.Event.addListener( self.DOM.get('edu-img'+tabIndex), 'click', self.deleteEduTable );
		self.initToolTips();
		// set container title
		self.DOM.get('edu_title'+tabIndex).innerHTML = ( tabIndex == 0 ? _label.help.edu1 : _label.help.edu2 );
		// set focus
		tab.element.getElementsByTagName('select')[0].focus();
	}

	this.validEduBlock = function ( i ) {
		var self = page;
		var test = true;
		while ( self.eduTables[i] == null ) i--;
		self.DOM.removeClass( self.DOM.getElementsByClassName('has_error', '', 'edu-t'+i), 'has_error' );
		//var test = self.allSelectValid('edu-t'+i);
		//var test = self.allInputValid('edu-t'+i) && test;
		var els = [ 'deg_type', 'deg_dur' ];
		for ( var k in els ) {
			if ( self.DOM.get(els[k]+i).selectedIndex == 0 ) {
				test = false;
				self.DOM.addClass( self.DOM.getAncestorByTagName(els[k]+i,'tr'), 'has_error' );
			}
		}
		if ( !test ) self.DOM.addClass( self.DOM.getElementsByClassName('mod-table', '', 'edu-t'+i), 'has_error' );
		return test;
	}
	
	this.handleEvalDegreeType = function ( el ) {
		var self = page;
		// remove notice
		self.DOM.removeClass( self.DOM.get('education_details'), 'has_notice' );
		// evaluate 
		var group = self.DOM.getElementsByClassName('selectDegreeType', 'select', 'edu_tables');
		var hasBach = false;
		var hasPost = false;
		for ( var i in group ) {
			var type = group[i].options[group[i].selectedIndex].value;
			switch (type) {
				case 'bachelors':
					hasBach = true;
					break;
				case 'masters':
				case 'phd':
					hasPost = true;
					break;
				default:
			}
		}
		if ( hasPost && !hasBach ) self.DOM.addClass( self.DOM.get('education_details'), 'has_notice');
	}

	this.handleEduHowLongAgo = function ( el, obj ) {
		var self = page;
		var tabIndex = this.id.substr(7);
		if ( this.selectedIndex == 1 ) {
			self.DOM.get('deg_compN_'+tabIndex).checked = true;
			self.DOM.get('deg_comp'+tabIndex+'_val').value = 'No';
		}
	}
	
	this.handleEduLocation = function ( el, obj ) {
		var self = page;
		var elP = self.DOM.getElementsByClassName( 'selectDegreeProv', 'select', obj );
		var elV = self.DOM.getElementsByClassName( 'selectDegreeVisa', 'select', obj );
		var infoRow = self.DOM.getElementsByClassName( 'deg_locationinfo', 'tr', obj );
		if ( this.options[this.selectedIndex].value == 'CA' ) {
			self.DOM.setStyle( infoRow, 'display', '' );
			elV[0].disabled = false;
			elP[0].disabled = false;
			elP[0].focus();
		} else {
			self.DOM.setStyle( infoRow, 'display', 'none' );
			elP[0].disabled = true;
			elV[0].disabled = true;
		}
	}
	
	this.deleteEduTable = function ( el ) {
		var self = page;
		var tabIndex = this.id.replace('edu-img','');
		var child = self.DOM.get('edu-t'+tabIndex);
		var parent = self.DOM.get('edu_tables');
		parent.removeChild(child);
		self.eduTables[tabIndex] = null;
		// now reset tables if all null
		var allNull = true;
		for ( var x=0; x < self.eduTables.length; x++ ) {
			if ( self.eduTables[x] != null ) allNull = false;
		}
		if ( allNull ) {
			self.eduTables = new Array;
			self.DOM.get('edu_hasN').checked = 'checked';
			self.showEducation();
		}
		self.initToolTips();
	}
	
/**
 * Work History Table Methods
 */
	this.addWorkTable = function () {
		var self = page;
		var tabIndex = self.workTables.length;
		// check prev work
		if ( tabIndex > 0 && !self.validWorkBlock(tabIndex-1) ) {
			alert(_label.err.ind4);
			self.DOM.get('ac-work-occ'+(tabIndex-1)).focus();
			return false;
		}
		// create table module
		var tab = new YAHOO.widget.Module('work-t'+tabIndex);
		var modStr = self.tableMods['work'].replace(/TABINDEX/g,tabIndex);
		tab.setBody( modStr );
		tab.render(self.DOM.get('work_tables'));
		tab.show();
		self.workTables[tabIndex] = tab;
		self.AC_Work[tabIndex] = self.newOccAC( 'ac-work-occ'+tabIndex, 'ac-work-cont'+tabIndex );
		// set job title
		self.DOM.get('wrk_title'+tabIndex).innerHTML = ( tabIndex == 0 ? _label.help.wrk1 : _label.help.wrk2 );
		// set event listeners
		self.Event.addListener( self.DOM.getElementsByClassName( 'typeRadio', 'input', 'work-t'+tabIndex ), 'click', self.setRadioValue );
		self.Event.addListener( self.DOM.get('wrk_how'+tabIndex ), 'change', self.handleWorkHowLongAgo );
		self.Event.addListener( self.DOM.get('wrk_location'+tabIndex), 'change', self.handleWorkLocation, tab.id );
		self.Event.addListener( self.DOM.get('wrk-img'+tabIndex), 'click', self.deleteWorkTable );
		self.initToolTips();
		// set focus
		self.DOM.get('ac-work-occ'+tabIndex).focus();
	}

	this.validWorkBlock = function ( i ) {
		var self = page;
		var test = true;
		while ( self.workTables[i] == null ) i--;
		self.DOM.removeClass( self.DOM.getElementsByClassName('has_error', '', 'work-t'+i), 'has_error' );
		//
		var el = self.DOM.get('ac-work-occ'+i);
		if ( el.value.length == 0 ) {
			test = false;
			self.DOM.addClass( self.DOM.getAncestorByTagName(el,'tr'), 'has_error' );
		}
		//
		var el = self.DOM.get('wrk_duration'+i);
		if ( el.selectedIndex == 0 ) {
			test = false;
			self.DOM.addClass( self.DOM.getAncestorByTagName(el,'tr'), 'has_error' );
		}
		//
		if ( !test ) self.DOM.addClass( self.DOM.getElementsByClassName('mod-table', '', 'work-t'+i), 'has_error' );
		return test;
	}
	
	this.handleWorkHowLongAgo = function ( el ) {
		var self = page;
		var tab_id = this.id.substr(7);
		var v = 'No';
		if ( this.selectedIndex == 0 ) v = '';
		if ( this.selectedIndex == 1 ) v = 'Yes';
		self.DOM.get('wrk_curr' + tab_id + '_val').value = v;
	}

	this.handleWorkLocation = function ( el, obj ) {
		var self = page;
		var elP = self.DOM.getElementsByClassName( 'selectWorkProv', 'select', obj );
		var elV = self.DOM.getElementsByClassName( 'selectWorkVisaType', 'select', obj );
		var provRow = self.DOM.getElementsByClassName( 'wrk_provinfo', 'tr', obj );
		var visaRow = self.DOM.getElementsByClassName( 'wrk_visainfo', 'tr', obj );
		if ( this.options[this.selectedIndex].value == 'canada' ) {
			self.DOM.setStyle( provRow, 'display', '' );
			self.DOM.setStyle( visaRow, 'display', '' );
			self.setSelect( elV[0], _select.work_caVisaTypes, false, null );
			elV[0].disabled = false;
			elP[0].disabled = false;
			elP[0].focus();
		} else if ( this.options[this.selectedIndex].value == 'usa' ) {
			self.DOM.setStyle( provRow, 'display', 'none' );
			self.DOM.setStyle( visaRow, 'display', '' );
			self.setSelect( elV[0], _select.work_usVisaTypes, false, null );
			elV[0].disabled = false;
			elP[0].selectedIndex = 0;
			elP[0].disabled = true;
			elV[0].focus();
		} else {
			self.DOM.setStyle( provRow, 'display', 'none' );
			self.DOM.setStyle( visaRow, 'display', 'none' );
			elP[0].selectedIndex = 0;
			elP[0].disabled = true;
			while ( elV[0].options.length ) elV[0].options[0] = null;
			elV[0].disabled = true;
		}
	}
	
	this.deleteWorkTable = function ( el ) {
		var self = page;
		var tabIndex = this.id.replace('wrk-img','');
		var child = self.DOM.get('work-t'+tabIndex);
		var parent = self.DOM.get('work_tables');
		parent.removeChild(child);
		self.workTables[tabIndex] = null;
		// now reset tables if all null
		var allNull = true;
		for ( var x=0; x < self.workTables.length; x++ ) {
			if ( self.workTables[x] != null ) allNull = false;
		}
		if ( allNull ) {
			self.workTables = new Array;
			self.DOM.get('wrk_hasN').checked = 'checked';
			self.showWork();
		}
		self.initToolTips();
	}
	
/**
 * Relative Table Methods
 */
	this.addFamTable = function () {
		var self = page;
		var tabIndex = self.famTables.length;
		// check previous table
		if ( tabIndex > 0 && !self.validFamBlock(tabIndex-1) ) {
			alert(_label.err.ind5);
			self.famTables[(tabIndex-1)].element.getElementsByTagName('select')[0].focus();
			return false;
		}
		// create table module
		var tab = new YAHOO.widget.Module('fam-t'+tabIndex);
		var modStr = self.tableMods['fam'].replace(/TABINDEX/g,tabIndex);
		tab.setBody( modStr );
		tab.render(self.DOM.get('fam_tables'));
		tab.show();
		self.famTables[tabIndex] = tab;
		// Add delete listener
		self.Event.addListener( self.DOM.get('fam-img'+tabIndex), 'click', self.deleteFamTable );
		self.initToolTips();
		// Hide the spouse string
		var btn = self.DOM.get('mStatusM');
		if ( !btn.checked ) self.DOM.setStyle( self.DOM.getElementsByClassName( 'spHidden', '', tab.id ), 'display', 'none' );
		// set focus
		tab.element.getElementsByTagName('select')[0].focus();
	}

	this.validFamBlock = function ( i ) {
		var self = page;
		var test = true;
		while ( self.famTables[i] == null ) i--;
		self.DOM.removeClass( self.DOM.getElementsByClassName('has_error', '', 'fam-t'+i), 'has_error' );
		var els = [ 'fam_relation', 'fam_status' ];
		for ( var k in els ) {
			if ( self.DOM.get(els[k]+i).selectedIndex == 0 ) {
				test = false;
				self.DOM.addClass( self.DOM.getAncestorByTagName(els[k]+i,'tr'), 'has_error' );
			}
		}
		if ( !test ) self.DOM.addClass( self.DOM.getElementsByClassName('mod-table', '', 'fam-t'+i), 'has_error' );
		return test;
	}
	
	this.deleteFamTable = function ( el ) {
		var self = page;
		var tabIndex = this.id.replace('fam-img','');
		var child = self.DOM.get('fam-t'+tabIndex);
		var parent = self.DOM.get('fam_tables');
		parent.removeChild(child);
		self.famTables[tabIndex] = null;
		// now reset tables if all null
		var allNull = true;
		for ( var x=0; x < self.famTables.length; x++ ) {
			if ( self.famTables[x] != null ) allNull = false;
		}
		if ( allNull ) {
			self.famTables = new Array;
			self.DOM.get('fam_incanadaN').checked = 'checked';
			self.showFamily();
		}
		self.initToolTips();
	}
	
}

// initialize the ajax page when DOM is ready
YAHOO.util.Event.onDOMReady(page.init);

