
function property(dLowerDateCheck, dUpperDateCheck) {
	xmlObject.call(this);
	
	this.saleDate="";
	this.houseNumber="";
	this.houseExtension="";
	this.housePreDirection="";
	this.houseStreetName="";
	this.houseStreetType="";
	this.housePostDirection="";
	this.houseSuite="";
	this.county="";
	this.countyName="";
	this.city="";
	this.mapNumber="";
	this.accountNumber="";
	this.acres="";
	this.taxDistrict="";
	this.gmdDistrict="";
	this.landDistrict="";
	this.landLot="";
	this.block="";	
	this.intendedUse="";
	this.errors = new Array();	
	this.warnings = new Array();
	this.iHaveShownWarnings = 0; //incrementing count to the number of times it has been called

	//Loaded from the constructors because ASP does an easier DateAdd, used an object so the values do not appear in the XML
	this.oDateCheck = new Object();
	this.oDateCheck.toXml = new Function("return 0;");
	this.oDateCheck.dLowerDateCheck = new Date(dLowerDateCheck);
	this.oDateCheck.dUpperDateCheck = new Date(dUpperDateCheck);
	
	this.isValid = function() {
		this.errors = new Array();
		this.warnings = new Array();
		var tmpDate = new Date(this.saleDate);
		var myDataError;

		if (this.trimString(this.saleDate).length == 0) {
			myDataError = new dataError();
			myDataError.description = 'Date of Sale is Required';
			myDataError.element = 'saleDate';
			this.errors.push(myDataError);
		}
		
		if (this.trimString(this.saleDate).length > 0) {
			var dateErr = this.isValidDate(this.saleDate);
			if (dateErr != '') {
				myDataError = new dataError();
				myDataError.description = 'Date of Sale ' + dateErr;
				myDataError.element = 'saleDate';
				this.errors.push(myDataError);
			}
		}

		if (this.trimString(this.county).length == 0) {
			myDataError = new dataError();
			myDataError.description = 'County is Required';
			myDataError.element = 'county';
			this.errors.push(myDataError);
		}

		if (this.trimString(this.mapNumber).length == 0) {
			myDataError = new dataError();
			myDataError.description = 'Map & Parcel Number is Required per SB 525 effective May 10, 2006. (Please see FAQ #30 for more information)';
			myDataError.element = 'mapNumber';
			this.errors.push(myDataError);
		}

		if (this.trimString(this.acres).length > 0) {
			if (this.isFloat(this.trimString(this.acres)) == false) {
				myDataError = new dataError();
				myDataError.description = 'Please enter a valid value for Acres (ex. 1.22)';
				myDataError.element = 'acres';
				this.errors.push(myDataError);
			}
		}

		if (tmpDate < this.oDateCheck.dLowerDateCheck && this.iHaveShownWarnings == 0) {
			myDataError = new dataError();
			myDataError.description = 'The date of sale you entered is more than 3 months old.  Please verify that ' + this.saleDate + ' is the correct date of sale.';
			myDataError.element = 'saleDate';
			this.warnings.push(myDataError);
		}

		if (tmpDate > this.oDateCheck.dUpperDateCheck && this.iHaveShownWarnings == 0) {
			myDataError = new dataError();
			myDataError.description = 'The date of sale you entered is more than 1 month into the future.  Please verify that ' + this.saleDate + ' is the correct date of sale.';
			myDataError.element = 'saleDate';
			this.warnings.push(myDataError);
		}
		if (this.trimString(this.mapNumber).length == 0 && this.trimString(this.accountNumber).length == 0 && this.iHaveShownWarnings == 0) {
			myDataError = new dataError();
			myDataError.description = 'With reference to 560-11-2-.16 (1)(c) if you or your client plan on using the PT61 filing in lieu of making a tax return,  the PT 61 must contain a complete description of the property being conveyed.  Until further notice a relaxed standard applies.  Either the MAP & PARCEL  or the DIGEST ACCOUNT NUMBER ** must ** be completed if the PT 61 is to serve in lieu of a tax return.  In addition, the filing ** should ** include the number of ACRES and the SUB-DIVISION LOT AND BLOCK, (where applicable).';
			if (this.warnings.length >= 1)
				myDataError.description = '\n' + myDataError.description
			myDataError.element = 'mapNumber';
			this.warnings.push(myDataError);
		}

		return this.errors.length == 0;
	}



	/* isValidDate
	 *
	 * Checks for the following valid date formats:
	 * MM/DD/YYYY    MM-DD-YYYY
	 * Also validates that the entered numbers are correct
	 *
	 * Return values are either error message is in error
	 * or "" is correct
	 */
	this.isValidDate = function(dateStr) {
		var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/; // requires 4 digit year
		var retVal = '';

		var matchArray = dateStr.match(datePat); // is the format ok?
		if (matchArray == null) {
			retVal = dateStr + " is not in a valid format.\n\tPlease enter in mm/dd/yyyy or mm-dd-yyyy format\n";
			return retVal;
		}
		month = matchArray[1]; // parse date into variables
		day = matchArray[3];
		year = matchArray[4];
		if (month < 1 || month > 12) { // check month range
			retVal = dateStr + " Month must be between 1 and 12.";
			return retVal;
		}
		if (day < 1 || day > 31) {
			retVal = dateStr + " Day must be between 1 and 31.";
			return retVal;
		}
		if ((month==4 || month==6 || month==9 || month==11) && day==31) {
			retVal = dateStr + " Month "+month+" doesn't have 31 days!";
			return retVal;
		}
		if (month == 2) { // check for february 29th
			var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
			if (day>29 || (day==29 && !isleap)) {
			retVal = dateStr + "- February " + year + " doesn't have " + day + " days!";
			return retVal;
		   }
		}
		return retVal;
	}


	/* isFloat
	 *
	 * Checks for the following valid float formats:
	 * ####.####
	 * Also validates that the entered numbers are correct and there is at most one period
	 *
	 * Return true is correct, false if not
	 */
	this.isFloat = function(str) {
		var valid = "0123456789.";
		var periodCount = 0;

		if (str.length == 0) {
			return true;
		} else {
			for (var i=0; i < str.length; i++) {
				temp = "" + str.substring(i, i+1);
				if (temp == ".") periodCount++;
				if (valid.indexOf(temp) == "-1") {
					return false;
				}
				if ((periodCount > 1)) {
					return false;
				 }
			}
			return true;
		}
	}	
	

	/* Trim String
	*
	* Does a VB Trim on a String
	*/
	this.trimString = function(str) {
	   return str.replace(/^\s+/g, '').replace(/\s+$/g, '');
	}
}
	
function PropertyInformation(dLowerDateCheck, dUpperDateCheck) {
	Panel.call(this);
	var myProperty=new property(dLowerDateCheck, dUpperDateCheck);
	
	// This is totally a hack function because I don't feel like doing round 4 with menu colors again
	// This allows me to figure out how many times it has been called
	this.warningCount = function () {
		myProperty.iHaveShownWarnings += 1;
		return myProperty.iHaveShownWarnings;
	}
	this.setWarningCount = function (iCount) {
		myProperty.iHaveShownWarnings = iCount;
	}

	this.display = function () {
		this.getContainer().innerHTML=this.getForm();
		document.getElementById("dvTitle").innerHTML = this.getTitle();
		this.displayValues();
		this.focusFirstElement();
	}
	
	this.displayValues = function() {
		for(var i in myProperty) {		
			if(typeof myProperty[i] != "object" && typeof myProperty[i] != "function"  ){
				if (i != "iHaveShownWarnings" && i!= "countyName")
					document.getElementById(i).value = myProperty[i];
			}
		}
	}
	
	this.focusFirstElement = function() {
		if ( myProperty.errors.length == 0)
			document.getElementById("saleDate").select();
	}
	
	
	this.setData = function() {
		for(var i in myProperty) {		
			if(typeof myProperty[i] != "object" && typeof myProperty[i] != "function"  ){
				if (i != "iHaveShownWarnings" && i!= "countyName")
					myProperty[i] = document.getElementById(i).value;
				else if (i == "countyName")		//This is used for the County Verification in the Preview Screen
					myProperty[i] = document.getElementById('county').options[document.getElementById('county').selectedIndex].text;
			}
		}
	}

	
	this.hide = function() {
		this.setData();
				
		this.getContainer().innerHTML="";
	}

	this.cityLostGotFocus = function(eventType) {
		var sDesc;
		
		if (eventType=='cityfocus') {
			sDesc = 'Only fill in if the property is located within the city limits of an incorporated area.';
		} else {
			sDesc = '';
		}
		document.getElementById("dvCityText").innerHTML = sDesc;
	}

	this.trigger = function(aControl, anEvent) {
		alert('event handler does not contain this event');
	}

	
	this.isValid = function(bShow) {
		if (bShow==undefined)
			bShow = true;

		if (bShow) 
			this.setData();

		if (!myProperty.isValid()) {
			if (bShow) 
				this.displayErrors();

			return false;
		} else {
			if (myProperty.warnings.length > 0)  {
				this.displayWarnings();
				myProperty.iHaveShownWarnings += 1;
				myProperty.warnings = new Array();
			}
			
			return true;
		}
	}


	this.displayErrors = function() {
		var msgPop;

		msgPop = 'The following information is missing or incorrect:\n\n';
		for (var i in myProperty.errors) {
			msgPop += '\t' + myProperty.errors[i].description + '\n';
		}

		msgPop += '\nand will be highlighted on the form.';
		alert(msgPop);

		for (var i in myProperty.errors) {
			document.getElementById(myProperty.errors[i].element).className = 'textFieldError';
		}

		if(myProperty.errors[0].element == 'county')
			document.getElementById(myProperty.errors[0].element).focus();
		else
			document.getElementById(myProperty.errors[0].element).select();
	}


	this.displayWarnings = function() {
		var msgPop;

		msgPop = 'Important Notice:\n\n';
		for (var i in myProperty.warnings) {
			msgPop += myProperty.warnings[i].description + '\n';
		}

		alert(msgPop);
	}
	
	
	this.toXml = function() {
		return myProperty.toXml();
	}
	

	/* Trim String
	 *
	 * Does a VB Trim on a String
	 */
	this.trimString = function(str) {
	   return str.replace(/^\s+/g, '').replace(/\s+$/g, '');
	}

	/* 
	 * loadProperty
	 *
	 * Inializes the Property Object
	 */
	this.loadProperty = function(saleDate, houseNumber, houseExtension, housePreDirection, houseStreetName, houseStreetType, housePostDirection, 
	                             houseSuite, county, countyName, city, mapNumber, accountNumber, acres, taxDistrict, gmdDistrict, landDistrict, 
	                             landLot, block, intendedUse) {

		myProperty.saleDate = saleDate;
		
		if (this.trimString(houseNumber).length > 0)
			myProperty.houseNumber = houseNumber;
	
		if (this.trimString(houseExtension).length > 0)
			myProperty.houseExtension = houseExtension;

		if (this.trimString(housePreDirection).length > 0)
			myProperty.housePreDirection = housePreDirection;

		if (this.trimString(houseStreetName).length > 0)
			myProperty.houseStreetName = houseStreetName;

		if (this.trimString(houseStreetType).length > 0)
			myProperty.houseStreetType = houseStreetType;

		if (this.trimString(housePostDirection).length > 0)
			myProperty.housePostDirection = housePostDirection;

		if (this.trimString(houseSuite).length > 0)
			myProperty.houseSuite = houseSuite;

		myProperty.county = county;
		myProperty.countyName = countyName;

		if (this.trimString(city).length > 0)
			myProperty.city = city;

		if (this.trimString(mapNumber).length > 0)
			myProperty.mapNumber = mapNumber;

		if (this.trimString(accountNumber).length > 0)
			myProperty.accountNumber = accountNumber;

		if (this.trimString(acres).length > 0)
			myProperty.acres = acres;

		if (this.trimString(taxDistrict).length > 0)
			myProperty.taxDistrict = taxDistrict;

		if (this.trimString(gmdDistrict).length > 0)
			myProperty.gmdDistrict = gmdDistrict;

		if (this.trimString(landDistrict).length > 0)
			myProperty.landDistrict = landDistrict;

		if (this.trimString(landLot).length > 0)
			myProperty.landLot = landLot;

		if (this.trimString(block).length > 0)
			myProperty.block = block;	

		if (this.trimString(intendedUse).length > 0)
			myProperty.intendedUse = intendedUse;
	}
}
