<?php

function parse($file) {
	$result = array();
	$doc = new DOMDocument();
	$doc->load($file);
	$root = $doc->documentElement;

	foreach ($root->childNodes as $child) {
		if ($child->nodeType != XML_ELEMENT_NODE) continue;
		if (strcasecmp($child->nodeName, ELEMENT_PROJECT) != 0) continue;
		$project = createProject($child);
		if ($project != NULL) array_push($result, $project);
	}
	return $result;
}

function createProject($node) {
	$project = new project();
	$project->id =$node->getAttribute(ATTRIBUTE_ID);
	$project->version = $node->getAttribute(ATTRIBUTE_VERSION);
	$status = $node->getAttribute(ATTRIBUTE_STATUS);
	if (strcasecmp($status, VALUE_STATUS_DONE) == 0) {
		$project->status = STATUS_DONE;
	}
	foreach ($node->childNodes as $child) {
		if ($child->nodeType != XML_ELEMENT_NODE) continue;
		if (strcasecmp($child->nodeName, ELEMENT_INFO) == 0) {
			$project->info = createInfo($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_CONTACT) == 0) {
			$project->contact = createContact($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_NOTES) == 0) {
			$project->notes = createNotes($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_LEGAL) == 0) {
			$project->legal[] = createLegal($child);
		} else {
			// TODO error
		}
	}
	return $project;
}

function createInfo($node) {
	$info = new info();
	foreach ($node->childNodes as $child) {
		if ($child->nodeType != XML_ELEMENT_NODE) continue;
		if (strcasecmp($child->nodeName, ELEMENT_NAME) == 0) {
			$info->name = getText($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_ORIGIN) == 0) {
			$info->origin = getText($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_REFERENCE) == 0) {
			$info->reference = getText($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_REPOSITORY) == 0) {
			$info->repository = getText($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_LOCATION) == 0) {
			$info->location = getText($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_TAG) == 0) {
			$info->tag = getText($child);
		} else {
			// TODO error
		}
	}
	return $info;
}

function getText($node) {
	foreach ($node->childNodes as $child) {
		if ($child->nodeType != XML_TEXT_NODE) continue;
		return $child->wholeText;
	}
}

function createContact($node) {
	$contact = new contact();
	foreach ($node->childNodes as $child) {
		if ($child->nodeType != XML_ELEMENT_NODE) continue;
		if (strcasecmp($child->nodeName, ELEMENT_NAME) == 0) {
			$contact->name = getText($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_EMAIL) == 0) {
			$contact->email = getText($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_COMPANY) == 0) {
			$contact->company = getText($child);
		} else  {
			// TODO error
		}
	}
	return $contact;
}

/*
 * Return an array of strings which represent the notes contained
 * in the given <notes> element.
 */
function createNotes($node) {
	$result = array();
	$children = $node->childNodes;
	foreach ($children as $child) {
		if ($child->nodeType != XML_ELEMENT_NODE) continue;
		if (strcasecmp($child->nodeName, ELEMENT_NOTE) != 0) continue;
		// we have a <note> element so store the text
		foreach ($child->childNodes as $sub) {
			if ($sub->nodeType != XML_TEXT_NODE) continue;
			$result[] = $sub->wholeText;
		}
	}
	return $result;
}

function createLegal($node) {
	$legal = new legal();
	$children = $node->childNodes;
	foreach ($children as $child) {
		if ($child->nodeType != XML_ELEMENT_NODE) continue;
		if (strcasecmp($child->nodeName, ELEMENT_IPZILLA) == 0) {
			$legal->ipzilla = $child->getAttribute(ATTRIBUTE_BUG_ID);
		} else if (strcasecmp($child->nodeName, ELEMENT_LICENSE) == 0) {
			$legal->license = createLicense($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_PACKAGE) == 0) {
			$legal->package = getText($child);
		} else {
			// TODO error
		}
	}
	return $legal;
}

function createLicense($node) {
	$license = new license();
	$children = $node->childNodes;
	foreach ($children as $child) {
		if ($child->nodeType != XML_ELEMENT_NODE) continue;
		if (strcasecmp($child->nodeName, ELEMENT_NAME) == 0) {
			$license->name = getText($child);
		} else if (strcasecmp($child->nodeName, ELEMENT_REFERENCE) == 0) {
			$license->reference = getText($child);
		} else {
			// TODO error
		}
	}
	return $license;
}

?>