function ValidateShipment()
{
	// Ship Date

	var shipDateTextBox = document.getElementById("tbShipDate");
	if (shipDateTextBox != null) // Check that the control exists, otherwise we will default to today so skip check
	{
		if (!IsDate(shipDateTextBox.value))
		{
			alert(shipDateTextBox.value + " is not a valid date (mm/dd/yyyy).");
			shipDateTextBox.focus();
			return false;
		}
	}

	// Locations

	// Determine which type of location controls we have
	var tbOriginPostalCode = document.getElementById("tbOriginPostalCode");
	var ddlOriginSites = document.getElementById("ddlOriginSites");
	var ddlDestinationSites = document.getElementById("ddlDestinationSites");
	if (tbOriginPostalCode != null || ddlOriginSites != null) // Separate origin and destination controls
	{
		// Check for valid data format
		if (ddlOriginSites == null)
		{
		    if (!IsValidLocationFormat("tbOriginPostalCode","tbOriginCity","selOriginState"))
			    return false;
		}
		if (ddlDestinationSites == null)
		{
		    if (!IsValidLocationFormat("tbDestinationPostalCode","tbDestinationCity","selDestinationState"))
			    return false;
		}
	}
	else
	{
		// We're using the location list and entries were already validated for format when added to the list
		// Check that we have at least 2 locations
		temp = document.getElementById("selLocationList");
		if (temp.options.length < 2)
		{
			alert("You must enter at least 2 locations.");
			document.getElementById("tbLocationPostalCode").focus();
			return false;
		}
	}

    // Pallets

	var palletsTextBox = document.getElementById("tbPallets");
	var pallets = false;
	if (palletsTextBox != null) // Check that the control exists
	{
		if (!IsNumeric(palletsTextBox.value) && !(trim(palletsTextBox.value) == ""))
		{
			alert("Invalid pallets value.");
			palletsTextBox.focus();
			return false;
		}
		else
		{
		    pallets = true;
		}
	}

	// Line Items

	// Determine which type of line item controls we have
	temp = document.getElementById("tbWeight1");
	if (temp != null) // Separate line item controls
	{
		// Find out how many line item rows we have
		var lineItemCount = 0;
		while (document.getElementById("tbWeight" + (lineItemCount + 1)) != null)
		{
			lineItemCount++;
		}

		var validCount = 0;
		var currentWeightId;
		var currentClassId;
		var currentPiecesId;
		for (var i = 0; i < lineItemCount; i++)
		{
			currentWeightId = "tbWeight" + (i + 1);
			currentClassId = "selClass" + (i + 1);
			currentPiecesId = "tbPieces" + (i + 1);
			temp = document.getElementById(currentWeightId);
			// The only required field is weight. Stop checking once an empty weight is found. The rest will be skipped.
			if (trim(temp.value) == "") 
			{
				if (validCount > 0)
				{
					break;
				}
				else
				{
//				    if (pallets) // If there are pallets then it's ok to have no line items
//				    {
//				        break;
//				    }
//				    else
//				    {
				        alert("Please enter a weight.");
				        temp.focus();
				        return false;
//				    }
				}
			}
			if (IsValidLineItem(currentWeightId, currentClassId, currentPiecesId))
			{
				validCount++;
			}
			else
			{
			    return false;
			}
		}
	}
	else
	{
		// We're using the line item list and entries were already validated for format when added to the list
		// Check that we have at least one line item
		temp = document.getElementById("selLineItemList");
		if (temp.options.length < 1)
		{
			// If there are no entries in the list. Then we try the line item entry controls.
			
//			temp = document.getElementById("tbWeight1");
//			if (!((trim(temp.value) == "") && pallets)) // If the weight is empty but we have pallets then it's ok, else validate the line item
//			{
//			    if (!IsValidLineItem("tbWeight", "selClass", "tbPieces"))
//			    {
			        alert("You must enter at least 1 line item.");
			        temp.focus();
			        return false;
//			    }
//            }			
		}
	}

	return true;
}

// Validates a single line item
function IsValidLineItem(weightId, classId, piecesId)
{
	var temp = document.getElementById(weightId);
	if (IsNumeric(temp.value))
	{
		// If the weight is good then see if we have pieces and check that
		temp = document.getElementById(piecesId);
		if (temp != null)
		{
			if (!IsNumeric(temp.value) && !(trim(temp.value) == ""))
			{
				alert("Invalid pieces.");
				temp.focus();
				return false;
			}
		}
	}
	else
	{
		alert("Invalid weight.");
		temp.focus();
		return false;
	}

	return true;
}

// Validates a single location (format only)
function IsValidLocationFormat(postalCodeId, CityId, StateId)
{
	// Check for valid postal code format
	var temp = document.getElementById(postalCodeId);
	if (!IsPostalCode(temp.value))
	{
		alert(temp.value + " is not a valid postal code format.");
		temp.focus()
		return false;
	}

	// Check that a city has been entered
	temp = document.getElementById(CityId);
	if (trim(temp.value) == "")
	{
		alert("Please provide a city.");
		temp.focus()
		return false;
	}

	// Check that a state has been selected
	temp = document.getElementById(StateId);
	if (!temp.selectedIndex > 0)
	{
		alert("Please select a state.");
		temp.focus()
		return false;
	}

	return true;        
}

// Validates that a string is a valid partial postal code (format only)
function IsValidPartialPostalCode(txt)
{
	usPostalCode = /^\d{1}$|^\d{2}$|^\d{3}$|^\d{4}$|^\d{5}$/;
	caPostalCode = /^[A-Za-z]$|^[A-Za-z]\d$|^[A-Za-z]\d[A-Za-z]$|^[A-Za-z]\d[A-Za-z]\d$|^[A-Za-z]\d[A-Za-z]\d[A-Za-z]$|^[A-Za-z]\d[A-Za-z]\d[A-Za-z]\d$/;
	return usPostalCode.test(txt) || caPostalCode.test(txt);
}

// Validates that a string is a valid postal code (format only)
function IsPostalCode(txt)
{
	usPostalCode = /^\d{5}$/;
	caPostalCode = /^[A-Za-z]\d[A-Za-z]\d[A-Za-z]\d$/;
	return usPostalCode.test(txt) || caPostalCode.test(txt);
}

// Validates that a string is a valid integer
function IsNumeric(str)
{
	var regexcheck = /^\d+$/; 
	return regexcheck.test(str);
}

// Validates that a single character is alphanumeric
function IsAlphaNumericCharacter(x)
{
	var regexcheck = /[0-9A-Za-z]/; 
	return regexcheck.test(x);
}

// Validates that a single character is alphabetic
function IsAlphaCharacter(x)
{
	var regexcheck = /[A-Za-z]/; 
	return regexcheck.test(x);
}

// Validates that a string is a valid date in the format of mm/dd/yyyy
function IsDate(datetocheck){

	// regular expression check on format (year must be 4 digits)
	var validdateformat = /^\d{2}\/\d{2}\/\d{4}$|^\d{1}\/\d{2}\/\d{4}$|^\d{2}\/\d{1}\/\d{4}$|^\d{1}\/\d{1}\/\d{4}$/; 
	if (!validdateformat.test(datetocheck))
		return false;

	// split date into parts
	var datearray = datetocheck.split("/");
	var month = datearray[0];
	var day = datearray[1];
	var year = datearray[2];

	// use javascript's Date object to verify date is ok
	var dateobj = new Date(year, month-1, day); // day is 1 based, others are 0 based
	if ((dateobj.getMonth()+1 != month) || (dateobj.getDate() != day) || (dateobj.getFullYear() != year))
		return false;

	return true;
}        

// Validates that a single key is alphanumeric
function IsAlphaNumericKey(x)
{
    // a - z
    if (x >= 65 && x <= 90) return true;
    
    // 0 - 9 
    if (x >= 48 && x <= 57) return true;    
    
    // 0 - 9 (num pad)
    if (x >= 96 && x <= 105) return true;    

	return false;
}

// Validates that a single key is alphabetic
function IsAlphaKey(x)
{
    // a - z
    if (x >= 65 && x <= 90) return true;
    
	return false;
}

// Validates that a single key is numeric
function IsNumericKey(x)
{
    // 0 - 9 
    if (x >= 48 && x <= 57) return true;    
    
    // 0 - 9 (num pad)
    if (x >= 96 && x <= 105) return true;    
    
	return false;
}
