function checkInputForDiscConstraints() {
    return checkInputForDiscConstraints([-1,-1,-1,-1]);
}

/**
 * Check input given prior input.
 * Prior input is an array including previous config index, plan value index within that config, month & year within that index
 */
function checkInputForDiscConstraints(previousConfigVals) {
	//prove that the external vars are available in here.
	if (null == previousConfigVals || previousConfigVals === undefined) {
		//set to default
		previousConfigVals = [-1,-1,-1,-1];
	}
	var coverLevelCode = $('#coverLevelCode').val();
	//alert('coverLevelCode is ' + coverLevelCode);
	/**
	 * Actual configurations are in function getDiscPlanEffDatesArray below.
	 * disc config example:  If plan coverLevelCode is 45 or 47, and eff month is 3 ('Mar') in year 2010,
	 * then:
	 *  1) Set the effecive day to 22, and the effective month to 4 ('Apr')
	 *  2) remove 1st, 8th and 15th as possible eff dates and entire month of 3 ('Mar')
	 *  Thus 22nd of April becomes the earliest possible effective date for this plan at the given rate.
	 *
	 *  Changing the month brings back all the removed choices again -
	 *  However, once re-inserted, picking one of the previously removed dates defaults the user to the next value
	 *  for that field.
	 *  If moving from start to end month or vice versa a different set of days/months/years may be removed as part 
	 *  of the same event.
	 *  Set the start month and end month, days may be removed in either or both of these.
	 *  No days should be removed in any months between the start month and end month.
	 *  Set the start year and end year.
	 *  There is a forEl property, that says for the element given, where the value = val to check, apply the removals listed.
	 *  Use 0 to match any value in the valToCheck field
	 *
	 * 	var discConfig1 = { 
		                plan: ['45','47'], mon: startMon, year: startYearVal, endMon: endMon, endYear: endYearVal,
                        defaultVal: [{forEl: 'effectiveMonth', valToCheck: startMon, elName: 'effectiveDay', valToSet: 22},
							         {forEl: 'effectiveMonth', valToCheck: endMon, elName: 'effectiveDay', valToSet: 1}], 
				        elsToRemove: [{forEl: 'effectiveMonth', valToCheck: startMon, 
							           elName: 'effectiveDay', valsToRemove:[{val: 1, txt: '1'},
                                                                             {val: 8, txt: '8'},
                                                                             {val: 15, txt: '15'}]},
							          {forEl: 'effectiveMonth', valToCheck: endMon, 
							           elName: 'effectiveDay', valsToRemove:[{val: 8, txt: '8'},
                                                                             {val: 15, txt: '15'},
                                                                             {val: 22, txt: '22'}]},
				                      {forEl: 'effectiveYear', valToCheck: 0,
							           elName: 'effectiveMonth', valsToRemove:[{val: 1, txt: 'Jan'},
                                                                             {val: 2, txt: 'Feb'},
                                                                             {val: 6, txt: 'Jun'},
                                                                             {val: 7, txt: 'Jul'},
                                                                             {val: 8, txt: 'Aug'},
                                                                             {val: 9, txt: 'Sep'},
                                                                             {val: 10, txt: 'Oct'},
                                                                             {val: 11, txt: 'Nov'},
                                                                             {val: 12, txt: 'Dec'}]},
				                      {forEl: 'effectiveMonth', valToCheck: 0,
							           elName: 'effectiveYear', valsToRemove:[{val: 2009, txt: '2009'},
                                                                              {val: 2011, txt: '2011'}]}
	                                 ],
		                prodSelectorDisplayText: 'This special offer price is only available for policies commencing between 22 March to 1 May 2010 inclusive.'
		               };

	 */

	var selectedMon = $('#effectiveMonth option:selected').val();
	var selectedYear = $('#effectiveYear option:selected').val();
	//alert('coverLevelCode = ' + coverLevelCode + ', selectedMon = ' + selectedMon + ', ' + 'selectedYear = ' + selectedYear);
	
	//check the year & month - if matching input, force the day and remove any invalid choices
	var matchedCoverLevelCode = 0;
	indices = [-1,-1,-1,-1];  //store the position of the config in the discPlanEffDatesArray, the plan, the month and year 
	//get current configurations (plans, start and end months & years, defaults to set etc)
    var today = new Date();
    var discPlanEffDatesArray = new getDiscPlanEffDatesArray();
	$.each(discPlanEffDatesArray, function(index, discConfig) {
		$.each(discConfig.plan, function(idx, planVal) {
			if (coverLevelCode == planVal && discConfig.showFrom <= today && discConfig.showUntil > today)
			{ 
				//alert('coverLevelCode = ' + coverLevelCode + ', planVal = ' + planVal);
				//are we in start month, or end month...
				if ((selectedMon == discConfig.mon && selectedYear == discConfig.year) || (selectedMon == discConfig.endMon && selectedYear == discConfig.endYear)) {
					//alert('in loop inner ... matched start or end month');
					matchedCoverLevelCode = coverLevelCode;
					indices = [index, idx, selectedMon, selectedYear]; //set discConfig and plan that tripped this
					//alert('indices:' + indices.toString() + ', matchedCoverLevelCode:' + matchedCoverLevelCode);
					return false; //got one, break out of loop.
				} else { //... or are we between the start and end months?   If so, set matched month to -1
				//assume that no time limited discount will be > 1 year's duration, so set the month to -1 (default) & year to matching year.
				//if it was possible to have > 1 year duration, then we'd have to do the same with year and check > or < as with month.
					var inBetweenStartAndEndOfDiscPeriod = false;
					if (selectedYear == discConfig.year && selectedMon > discConfig.mon) {
						//is selected month less than end month if end year is the same year, or is end year a greater year?
						//for either case we're in the disc period
						if ((selectedYear == discConfig.year && selectedMon < discConfig.endMon) || (selectedYear < discConfig.endYear)) { 
						    inBetweenStartAndEndOfDiscPeriod = true;
						}
					} else if (selectedYear == discConfig.endYear && selectedMon < discConfig.endMon) { //could end in a different year (e.g. disc across a new year period)
					//ensure not just before start month if end and start years are the same year!
						if ((selectedYear == discConfig.endYear && selectedMon > discConfig.mon) ||  (selectedYear > discConfig.year)) { 
						   inBetweenStartAndEndOfDiscPeriod = true;
						}
					} //otherwise we're not in the disc period for the matched plan.
					if (inBetweenStartAndEndOfDiscPeriod) {
					   matchedCoverLevelCode = coverLevelCode;
					   indices = [index, idx, -1, selectedYear]; //set discConfig and plan that tripped this, but month =-1
					}
				}
			}
			//else { 
			//		alert('Not disc plan');
		    //}
		});
	});



	if((previousConfigVals != [-1,-1,-1,-1]) && (indices != previousConfigVals)) { //there's been a change
	//re-insert previously removed options
		reinsertRemovedOptions(previousConfigVals, discPlanEffDatesArray);
	}

	//check that matchedPlan is non-zero and config is set (indices[0] > -1), as is plan index within that config (indices[1] > -1)
	if (matchedCoverLevelCode > 0 && indices[0] > -1 && indices[1] > -1) {
		//set the disc to match the coverLevelCode that = matchedCoverLevelCode
		//alert('in non-zero indices match, coverLevelCode: ' + matchedCoverLevelCode + ', indices[0] is: ' + indices[0] + ', indices[1] is: ' + indices[1]);
		discConfigVal = discPlanEffDatesArray[indices[0]]; //retrieve the particular discConfig that tripped above
		
		//get the matched month and find the default day to set for that month		
		//for each of month, year, set the default value of day, month, year to any defined values for the matched input month /year
		$.each(discConfigVal.defaultVal, function(index, elToSetDefault) {
			//alert ('elToSetDefault name: ' + elToSetDefault.elName + ', value: ' + elToSetDefault.valToSet);
			//var trueOrFalseFromMatchForAction = matchForAction(elToSetDefault, indices);
			//alert('true or false from matchForAction: ' + trueOrFalseFromMatchForAction);
			//if we have a month/year forEl and a match in their values to that input, or match any (0 as valToCheck)
			if (matchForAction(elToSetDefault, indices)) {
			    //alert('current val is: ' + $('#'+elToSetDefault.elName).val());
			    $('#'+elToSetDefault.elName).val(elToSetDefault.valToSet);
			    //alert('elToSetDefault.elName is: ' + elToSetDefault.elName + ', current val is: ' + $('#'+elToSetDefault.elName).val());
			}
		});


		//Having reset to disc vals, for each element to remove, get the element and iterate through to remove
		$.each(discConfigVal.elsToRemove, function(index, elObject) {
		    //alert('elObject.elName: ' + elObject.elName);
			if (matchForAction(elObject, indices)) {
				$.each(elObject.valsToRemove, function(index, valToRemove) {
				  //alert('elObject.elName: ' + elObject.elName + ', val is: ' + valToRemove.val);
				  $("#"+elObject.elName+" option[value='"+valToRemove.val+"']").remove();
				});
				//alert('elObject.elName.val(): ' + $(curElName).val());
			}
		});
	} //end if
	
	return indices;  //HTML page or other caller needs to use this for re-inserting removed elements next call.
}

function reinsertRemovedOptions(previousConfig, discPlanEffDatesArray) {
	if (previousConfig[0] > -1) {
		discConfigVal = discPlanEffDatesArray[previousConfig[0]]; //retrieve the particular discConfig that tripped above
		$.each(discConfigVal.elsToRemove, function(index, elObject) {
			if (matchForAction(elObject, previousConfig)) {
				iterElName = "#"+elObject.elName;
				var height = $(iterElName).height();
				//get currently selected value
				var curVal = $(iterElName).val();
				//alert('reinsertRemovedOptions - height is: ' + height + ', curVal is: ' + curVal);
				$.each(elObject.valsToRemove, function(index, removedValToReInsert) {
				
					alreadyInserted = false;
					optionToReInsert = "<option value='"+removedValToReInsert.val+"'>"+removedValToReInsert.txt+"</option>";
					$.each($(iterElName+" option"), function(idx, existingOption) {
					  //iterate through all existing options to insert in the right place
					  if ($(existingOption).val() > removedValToReInsert.val)
					  {
						 //gone past, insert before this
						 //alert('reinsertRemovedOptions - idx is: ' + idx + ', reinserting: ' + optionToReInsert + ' before val: ' +  $(existingOption).val());
						 $(existingOption).before(optionToReInsert);
						 alreadyInserted = true;
						 return false;
					  }
					});
					
					if (!alreadyInserted) { //bigger than the biggest in the list, before none, insert @ end
						$(iterElName+" option:last").after(optionToReInsert);
					}
					//alert('reinsertRemovedOptions - finishing outer index: ' + index);
				});
				$(iterElName).height(height+2);
			}
		});
	}
}

/**
* Get the current configurations with their times.
*/
function getDiscPlanEffDatesArray() {
    startMon = '3'; startYearVal = '2010';
    endMon = '5'; endYearVal = '2010';
	var showFromDate = new Date(2010,2,15,0,0,0,0); //date months are 0-based, March is month 2.  0 hours, min, seconds, milliseconds.
	var showUntilDate = new Date(2010,4,2,0,0,0,0); //May is month 4.  Go until the end of day 1 approx start of day 2.
	freeKidsStartMon = '5'; freeKidsEndMon = '6';
	var showFreeKidsFromDate = new Date(2010,4,2,0,0,0,0); //Start on the 2nd of May (not the 1st, biz decision).
	var showFreeKidsUntilDate = new Date(2010,5,9,0,0,0,0); //June is month 5.  Go until the end of day 1 approx start of day 2.

	var discConfig1 = { 
		                plan: ['45','47'], mon: startMon, year: startYearVal, endMon: endMon, endYear: endYearVal,
                        defaultVal: [{forEl: 'effectiveMonth', valToCheck: startMon, elName: 'effectiveDay', valToSet: 22},
							         {forEl: 'effectiveMonth', valToCheck: endMon, elName: 'effectiveDay', valToSet: 1}], 
				        elsToRemove: [{forEl: 'effectiveMonth', valToCheck: startMon, 
							           elName: 'effectiveDay', valsToRemove:[{val: 1, txt: '1'},
                                                                             {val: 8, txt: '8'},
                                                                             {val: 15, txt: '15'}]},
							          {forEl: 'effectiveMonth', valToCheck: endMon, 
							           elName: 'effectiveDay', valsToRemove:[{val: 8, txt: '8'},
                                                                             {val: 15, txt: '15'},
                                                                             {val: 22, txt: '22'}]},
				                      {forEl: 'effectiveYear', valToCheck: 0,
							           elName: 'effectiveMonth', valsToRemove:[{val: 1, txt: 'Jan'},
                                                                             {val: 2, txt: 'Feb'},
                                                                             {val: 6, txt: 'Jun'},
                                                                             {val: 7, txt: 'Jul'},
                                                                             {val: 8, txt: 'Aug'},
                                                                             {val: 9, txt: 'Sep'},
                                                                             {val: 10, txt: 'Oct'},
                                                                             {val: 11, txt: 'Nov'},
                                                                             {val: 12, txt: 'Dec'}]},
				                      {forEl: 'effectiveMonth', valToCheck: 0,
							           elName: 'effectiveYear', valsToRemove:[{val: 2009, txt: '2009'},
                                                                              {val: 2011, txt: '2011'}]}
	                                 ],
		                prodSelectorDisplayText: '',
		                showFrom: showFromDate, showUntil: showUntilDate,
						divId: 'DialogOnePlans'
		               };

	var discConfig2 = { 
		                plan: ['47'], mon: freeKidsStartMon, year: startYearVal, endMon: freeKidsEndMon, endYear: endYearVal,
                        defaultVal: [{forEl: 'effectiveMonth', valToCheck: freeKidsEndMon, elName: 'effectiveDay', valToSet: 1}], 
				        elsToRemove: [{forEl: 'effectiveMonth', valToCheck: freeKidsStartMon, 
							           elName: 'effectiveDay', valsToRemove:[{val: 1, txt: '1'}]},
							          {forEl: 'effectiveMonth', valToCheck: freeKidsEndMon, 
							           elName: 'effectiveDay', valsToRemove:[
                                                                             {val: 15, txt: '15'},
                                                                             {val: 22, txt: '22'}]},
				                      {forEl: 'effectiveYear', valToCheck: 0,
							           elName: 'effectiveMonth', valsToRemove:[{val: 1, txt: 'Jan'},
                                                                             {val: 2, txt: 'Feb'},
                                                                             {val: 3, txt: 'Mar'},
                                                                             {val: 4, txt: 'Apr'},
                                                                             {val: 7, txt: 'Jul'},
                                                                             {val: 8, txt: 'Aug'},
                                                                             {val: 9, txt: 'Sep'},
                                                                             {val: 10, txt: 'Oct'},
                                                                             {val: 11, txt: 'Nov'},
                                                                             {val: 12, txt: 'Dec'}]},
				                      {forEl: 'effectiveMonth', valToCheck: 0,
							           elName: 'effectiveYear', valsToRemove:[{val: 2009, txt: '2009'},
                                                                              {val: 2011, txt: '2011'}]}
	                                 ],
		                prodSelectorDisplayText: 'Kids are free on One+ Plan - this special offer price applies to One+ Plan policies that commence between 1st August 2010 and 30th September 2010 inclusive.',
		                showFrom: showFreeKidsFromDate, showUntil: showFreeKidsUntilDate,
						divId: 'DialogOnePlusPlan'
		               };
/*
//sample 2nd disc config, for plans 34 & 38, same start & end months and years as discConfig1 above.
//I've messed around with the year to show that the years above would be replaced and these ones removed.
//This shows that you're not limited to one config at a time.
//divId is div id to open in discount_plans_dialog.jspf, following the token discount or openDiscount
	var discConfig2 = { 
		                plan: ['34','38'], mon: startMon, year: startYearVal, endMon: endMon, endYear: endYearVal,
                        defaultVal: [{forEl: 'effectiveMonth', valToCheck: startMon, elName: 'effectiveDay', valToSet: 22},
							         {forEl: 'effectiveMonth', valToCheck: endMon, elName: 'effectiveDay', valToSet: 1}], 
				        elsToRemove: [{forEl: 'effectiveMonth', valToCheck: startMon, 
							           elName: 'effectiveDay', valsToRemove:[{val: 1, txt: '1'},
                                                                             {val: 8, txt: '8'},
                                                                             {val: 15, txt: '15'}]},
							          {forEl: 'effectiveMonth', valToCheck: endMon, 
							           elName: 'effectiveDay', valsToRemove:[{val: 8, txt: '8'},
                                                                             {val: 15, txt: '15'},
                                                                             {val: 22, txt: '22'}]},
				                      {forEl: 'effectiveYear', valToCheck: 0,
							           elName: 'effectiveMonth', valsToRemove:[{val: 1, txt: 'Jan'},
                                                                             {val: 2, txt: 'Feb'},
                                                                             {val: 6, txt: 'Jun'},
                                                                             {val: 7, txt: 'Jul'},
                                                                             {val: 8, txt: 'Aug'},
                                                                             {val: 9, txt: 'Sep'},
                                                                             {val: 10, txt: 'Oct'},
                                                                             {val: 11, txt: 'Nov'},
                                                                             {val: 12, txt: 'Dec'}]},
				                      {forEl: 'effectiveMonth', valToCheck: 0,
							           elName: 'effectiveYear', valsToRemove:[{val: 2009, txt: '2009'},
                                                                              {val: 2011, txt: '2011'}]}
	                                 ],
		                prodSelectorDisplayText: 'This special offer price is only available for policies commencing between 22 March to 1 May 2010 inclusive.',
		                showFrom: showFromDate, showUntil: showUntilDate,
						divId: 'DialogOnePlusPlan'
		               };
    //add the two configs to the array to activate them both
	var discPlanConfigsArray = [discConfig1, discConfig2];
    */
    var discPlanConfigsArray = [discConfig1, discConfig2];
	
	/**
	 *  Override standard JavaScript Object/Array toString to give meaningful output
	 */ 
	discPlanConfigsArray.toString = function () {
		var x = 'discPlanConfigsArray\n';
		for (var i = 0; i < discPlanConfigsArray.length ; i++) {
			//get the plans
			var plansText = '[';
			for (var j = 0; j < discPlanConfigsArray[i].plan.length; j++ ) {
				if(0 < j) {
                    plansText = plansText + ',';
				}
				plansText = plansText + discPlanConfigsArray[i].plan[j];
			}
			plansText = plansText + ']';
           x =  x + i + ': ' + plansText + ', ' + discPlanConfigsArray[i].mon + ', '  + discPlanConfigsArray[i].year + ', ';
		   x =  x + discPlanConfigsArray[i].endMon + ', '  + discPlanConfigsArray[i].endYear + ', ' + discPlanConfigsArray[i].prodSelectorDisplayText + '.\n'
		}
		return x;
	};

	return discPlanConfigsArray;
}

/**
 * return true if the action should be undertaken for the given object, false otherwise
 * namedObj can be any object/subobject with a forEl property and a valToCheck property.
 * indexArray in practice is either the indices or previousConfigVals array.
 * It stores the position of the config in the discPlanEffDatesArray, the plan, the month and year 
 */
function matchForAction(namedObj, indexArray) {
	var defaultValIdx = -1;
	if (namedObj.forEl == 'effectiveMonth') { //set to month index
		defaultValIdx = 2;
	} else if (namedObj.forEl == 'effectiveYear') { //set to year index
		defaultValIdx =  3;
	}
	if (-1 < defaultValIdx && (indexArray[defaultValIdx] == namedObj.valToCheck || 0 == namedObj.valToCheck)) {
		return true;
	} else {
		return false;
	}
}