function USMARCControlField(tag, data)
{
	this.tag = tag;
	this.data = data;
}

function USMARCSubfield(code, data)
{
	this.code = code;
	this.data = data;
}

function USMARCDataField(tag, input)
{
	//if (typeof _USMARCDataField_prototype_defined == "undefined")
	{
		function getSubfields(code)
		{
			var result = new Array();

			for (var i in this.subfields)
			{
				var subfield = this.subfields[i];

				if (subfield.code == code)
				{
					result[result.length] = subfield;
				}
			}

			return result;
		}

		function getSubfield(code, occurrence)
		{
			if (typeof occurrence == "undefined")
			{
				occurrence = 0;
			}

			for (var i in this.subfields)
			{
				var subfield = this.subfields[i];

				if (subfield.code == code)
				{
					if (occurrence == 0)
					{
						return subfield;
					}

					--occurrence;
				}
			}

			return null;
		}

		function getSubfieldData(code, occurrence)
		{
			var subfield = this.getSubfield(code, occurrence);

			if (subfield != null)
			{
				return subfield.data;
			}

			return "";
		}

		function getIndicator(which)
		{
			if (typeof which == "undefined")
			{
				which = "";
			}

			if (which == "i1") return this.i1;
			if (which == "i2") return this.i2;

			return this.i1 + this.i2;
		}

		USMARCDataField.prototype.getSubfields = getSubfields;
		USMARCDataField.prototype.getSubfield = getSubfield;
		USMARCDataField.prototype.getSubfieldData = getSubfieldData;
		USMARCDataField.prototype.getIndicator = getIndicator;

		//_USMARCDataField_prototype_defined = true;
	}

	this.tag = tag;
	this.i1 = " ";
	this.i2 = " ";
	this.subfields = new Array();

	var parts = input.split("\x1F");

	var first = true;

	for (var i in parts)
	{
		var part = parts[i];

		if (!first)
		{
			if (part.length >= 1)
			{
				var code = part.charAt(0);
				var data = part.substr(1, part.length - 1);

				this.subfields[this.subfields.length] = new USMARCSubfield(code, data);
			}
		}
		else if (part.length == 2)
		{
			this.i1 = part.charAt(0);
			this.i2 = part.charAt(1);
		}

		first = false;
	}
}

function USMARC(input)
{
	this.leader = "";
	this.control_fields = new Array();
	this.data_fields = new Array();

	//if (typeof _USMARC_prototype_defined == "undefined")
	{
		function getControlFields(tag)
		{
			var result = new Array();

			for (var i in this.control_fields)
			{
				var control_field = this.control_fields[i];

				if (control_field.tag == tag)
				{
					result[result.length] = control_field;
				}
			}

			return result;
		}

		function getControlField(tag, occurrence)
		{
			if (typeof occurrence == "undefined")
			{
				occurrence = 0;
			}

			for (var i in this.control_fields)
			{
				var control_field = this.control_fields[i];

				if (control_field.tag == tag)
				{
					if (occurrence == 0)
					{
						return control_field;
					}

					--occurrence;
				}
			}

			return null;
		}

		function getControlFieldData(tag, occurrence)
		{
			var control_field = this.getControlField(tag, occurrence);

			if (control_field != null)
			{
				return control_field.data;
			}

			return "";
		}

		function getDataFields(tag)
		{
			var result = new Array();

			if (tag.length == 3)
			{
				var t = tag.charAt(0);

				var dfs = this.data_fields[t];

				if (typeof dfs != "undefined")
				{
					for (var i in dfs)
					{
						var data_field = dfs[i];

						if (data_field.tag == tag)
						{
							result[result.length] = data_field;
						}
					}
				}
			}

			return result;
		}

		function getDataField(tag, occurrence)
		{
			if (typeof occurrence == "undefined")
			{
				occurrence = 0;
			}

			if (tag.length == 3)
			{
				var t = tag.charAt(0);

				var dfs = this.data_fields[t];

				if (typeof dfs != "undefined")
				{
					for (var i in dfs)
					{
						var data_field = dfs[i];

						if (data_field.tag == tag)
						{
							if (occurrence == 0)
							{
								return data_field;
							}

							--occurrence;
						}
					}
				}
			}

			return null;
		}

		function getSubfieldData(tag, code, tag_occurrence, code_occurrence)
		{
			if (typeof tag_occurrence == "undefined")
			{
				tag_occurrence = 0;
			}

			if (typeof code_occurrence == "undefined")
			{
				code_occurrence = 0;
			}

			var data_field = this.getDataField(tag, tag_occurrence);

			if (data_field != null)
			{
				return data_field.getSubfieldData(code, code_occurrence);
			}

			return "";
		}

		function getIndicator(tag, which, occurrence)
		{
			if (typeof which == "undefined")
			{
				which = "";
			}

			if (typeof occurrence == "undefined")
			{
				occurrence = 0;
			}

			var data_field = this.getDataField(tag, occurrence);

			if (data_field != null)
			{
				if (which == "i1") return data_field.i1;
				if (which == "i2") return data_field.i2;
				return data_field.i1 + data_field.i2;
			}

			return "";
		}

		USMARC.prototype.getControlFields = getControlFields;
		USMARC.prototype.getControlField = getControlField;
		USMARC.prototype.getControlFieldData = getControlFieldData;
		USMARC.prototype.getDataFields = getDataFields;
		USMARC.prototype.getDataField = getDataField;
		USMARC.prototype.getSubfieldData = getSubfieldData;
		USMARC.prototype.getIndicator = getIndicator;

		//_USMARC_prototype_defined = true;
	}

	if (input.length >= 26 && input.charAt(input.length - 1) == "\x1D")
	{
		var parts = input.substr(0, input.length - 1).split("\x1E");

		var first = true;

		for (var i in parts)
		{
			var part = parts[i];

			if (!first)
			{
				if (part.length >= 3)
				{
					var tag = part.substr(0, 3);
					var data = part.substr(3, part.length - 3);

					if (tag.substr(0, 2) != "00")
					{
						var t = tag.charAt(0);

						var dfs = this.data_fields[t];

						if (typeof dfs == "undefined")
						{
							dfs = this.data_fields[t] = new Array();
						}

						dfs[dfs.length] = new USMARCDataField(tag, data);
					}
					else
					{
						this.control_fields[this.control_fields.length] = new USMARCControlField(tag, data);
					}
				}
			}
			else
			{
				this.leader = part;
			}

			first = false;
		}
	}
}

function toUSMARC(dst, input)
{
	dst.usmarc = new USMARC(input);
}

function getControlField(record, field, occurrence)
{
	if (typeof record.usmarc != "undefined")
	{
		return record.usmarc.getControlFieldData(field, occurrence);
	}

	return "";
}

function getDataField(record, field, occurrence)
{
	if (typeof record.usmarc != "undefined")
	{
		return record.usmarc.getDataField(field, occurrence);
	}

	return null;
}

function getSubfield(record, field, subfield)
{
	if (typeof record.usmarc != "undefined")
	{
		return record.usmarc.getSubfieldData(field, subfield);
	}

	return "";
}

function getFieldSubfield(field, subfield, occurrence)
{
	if (typeof field != "undefined")
	{
		return field.getSubfieldData(subfield, occurrence);
	}

	return "";
}

function getSubfields(record, field, subfield, delimiter, occurrence)
{
	var result = "";

	if (typeof record.usmarc != "undefined" && field.length == 3)
	{
		if (typeof subfield == "undefined") subfield = "";
		if (typeof delimiter == "undefined") delimiter = " ";
		if (typeof occurrence == "undefined") occurrence = 0;

		var data_field = record.usmarc.getDataField(field);

		if (data_field != null)
		{
			var subfields = data_field.subfields;

			if (typeof subfields != "undefined")
			{
				for (var i in subfields)
				{
					var _subfield = subfields[i];

					if (_subfield.code == subfield || subfield == "")
					{
						result += _subfield.data + delimiter;
					}
				}
			}
		}
	}

	return result;
}


