You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2008/12/12 19:20:18 UTC

svn commit: r726079 [23/32] - in /incubator/vcl/tags/import: ./ managementnode/ managementnode/bin/ managementnode/etc/ managementnode/etc/vcl/ managementnode/legacy_vcl_vbs_scripts/ managementnode/lib/ managementnode/lib/VCL/ managementnode/lib/VCL/Mo...

Added: incubator/vcl/tags/import/web/.ht-inc/images.php
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/web/.ht-inc/images.php?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/web/.ht-inc/images.php (added)
+++ incubator/vcl/tags/import/web/.ht-inc/images.php Fri Dec 12 10:20:10 2008
@@ -0,0 +1,3737 @@
+<?php
+/*
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+*/
+
+/**
+ * \file
+ */
+
+/// signifies an error with the submitted name
+define("NAMEERR", 1);
+/// signifies an error with the submitted pretty name
+define("PRETTYNAMEERR", 1 << 1);
+/// signifies an error with the submitted minimum number amount of RAM
+define("MINRAMERR", 1 << 2);
+/// signifies an error with the submitted minimum processor speed
+define("MINPROCSPEEDERR", 1 << 3);
+/// signifies an error with the submitted estimated reload time
+define("RELOADTIMEERR", 1 << 4);
+/// signifies an error with the submitted owner
+define("IMGOWNERERR", 1 << 5);
+/// signifies an error with the submitted maximum concurrent usage
+define("MAXCONCURRENTERR", 1 << 6);
+/// signifies an error with the submitted image description
+define("IMAGEDESCRIPTIONERR", 1 << 7);
+
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn selectImageOption()
+///
+/// \brief prints a page for the user to select which image operation they want
+/// to perform; if they only have access to a few options or only a few images,
+/// just send them straight to viewImagesAll
+///
+////////////////////////////////////////////////////////////////////////////////
+function selectImageOption() {
+	# get a count of images user can administer
+	$tmp = getUserResources(array("imageAdmin"), array("administer"));
+	$imgAdminCnt = count($tmp['image']);
+
+	# get a count of images user has access to for creating new images
+	$tmp = getUserResources(array("imageAdmin"), array("available"));
+	$imgCnt = count($tmp['image']);
+
+	# get a count of image groups user can manage
+	$tmp = getUserResources(array("imageAdmin"), array("manageGroup"), 1);
+	$imgGroupCnt = count($tmp['image']);
+
+	# get a count of computer groups user can manage
+	$tmp = getUserResources(array("computerAdmin"), array("manageGroup"), 1);
+	$compGroupCnt = count($tmp['computer']);
+
+	print "<H2>Manage Images</H2>\n";
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	if($imgAdminCnt) {
+		$cont = addContinuationsEntry('viewImages');
+		print "<INPUT type=radio name=continuation value=\"$cont\" checked>Edit ";
+		print "Image Profiles<br>\n";
+		print "<img src=images/blank.gif width=20><INPUT type=checkbox name=";
+		print "details value=1>Include details<br>\n";
+	}
+
+	if($imgGroupCnt) {
+		$cont = addContinuationsEntry('viewImageGrouping');
+		print "<INPUT type=radio name=continuation value=\"$cont\">Edit ";
+		print "Image Grouping<br>\n";
+
+		if($compGroupCnt) {
+			$cont = addContinuationsEntry('viewImageMapping');
+			print "<INPUT type=radio name=continuation value=\"$cont\">Edit ";
+			print "Image Mapping<br>\n";
+		}
+	}
+
+	if($imgCnt) {
+		$cont = addContinuationsEntry('createSelectImage');
+		print "<INPUT type=radio name=continuation value=\"$cont\">Create&nbsp;/";
+		print "&nbsp;Update an Image<br>\n";
+	}
+
+	if($imgAdminCnt || $imgGroupCnt || $imgCnt)
+		print "<br><INPUT type=submit value=Submit>\n";
+	else
+		print "You don't have access to manage any images.<br>\n";
+	print "</FORM>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn viewImages()
+///
+/// \brief prints a page to view image information
+///
+////////////////////////////////////////////////////////////////////////////////
+function viewImages() {
+	global $viewmode, $user, $mode;
+	$showdeleted = getContinuationVar("showdeleted", 0);
+	$deleted = getContinuationVar("deleted");
+	$details = processInputVar("details", ARG_NUMERIC);
+
+	if($showdeleted) {
+		$images = getImages(1);
+		$resources = getUserResources(array("imageAdmin"), 
+		                              array("administer"), 0, 1);
+	}
+	else {
+		$images = getImages();
+		$resources = getUserResources(array("imageAdmin"), array("administer"));
+	}
+	$userImageIDs = array_keys($resources["image"]);
+	$platforms = getPlatforms();
+	$oslist = getOSList();
+	$depts = getDepartments();
+
+	print "<H2>Image Profiles</H2>\n";
+	if($mode == "submitDeleteImage") {
+		if($deleted) {
+			print "<font color=\"#008000\">Image successfully undeleted";
+			print "</font><br><br>\n";
+		}
+		else {
+			print "<font color=\"#008000\">Image successfully set to deleted ";
+			print "state</font><br><br>\n";
+		}
+	}
+	elseif($mode == "submitEditImage") {
+		print "<font color=\"#008000\">Image successfully updated";
+		print "</font><br><br>\n";
+	}
+	print "<TABLE border=1>\n";
+	print "  <TR>\n";
+	print "    <TD></TD>\n";
+	print "    <TH><img src=images/blank.gif width=100 height=1><br>Name</TH>\n";
+	print "    <TH>Owner</TH>\n";
+	print "    <TH>Platform</TH>\n";
+	print "    <TH><img src=images/blank.gif width=70 height=1><br>OS</TH>\n";
+	print "    <TH>Estimated Reload Time (min)</TH>\n";
+	if($details) {
+		print "    <TH>Minimum RAM (MB)</TH>\n";
+		print "    <TH>Minimum Num of Processors</TH>\n";
+		print "    <TH>Minimum Processor Speed (MHz)</TH>\n";
+		print "    <TH>Minimum Network Speed (Mbps)</TH>\n";
+		print "    <TH>Maximum Concurrent Usage</TH>\n";
+	}
+	if($showdeleted) {
+		print "    <TH>Deleted</TH>\n";
+	}
+	print "  </TR>\n";
+	foreach(array_keys($images) as $id) {
+		if(! in_array($id, $userImageIDs))
+			continue;
+		print "  <TR>\n";
+		print "    <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+		$cdata = array('imageid' => $id);
+		$cont = addContinuationsEntry('submitImageButton', $cdata);
+		print "    <INPUT type=hidden name=continuation value=\"$cont\">\n";
+		print "    <TD align=center>\n";
+		if($showdeleted && $images[$id]["deleted"] == 1) {
+			print "      <INPUT type=submit name=submode value=Undelete>\n";
+		}
+		else {
+			print "      <INPUT type=submit name=submode value=Edit>\n";
+			print "      <INPUT type=submit name=submode value=Delete><br>\n";
+		}
+		print "      <INPUT type=submit name=submode value=Details>\n";
+		print "    </TD>\n";
+		print "    </FORM>\n";
+		print "    <TD align=center>" . $images[$id]["prettyname"] . "</TD>\n";
+		print "    <TD align=center>" . $images[$id]["owner"] . "</TD>\n";
+		print "    <TD align=center>" . $images[$id]["platform"] . "</TD>\n";
+		print "    <TD align=center>" . $oslist[$images[$id]["osid"]]["prettyname"] . "</TD>\n";
+		print "    <TD align=center>" . $images[$id]["reloadtime"] . "</TD>\n";
+		if($details) {
+			print "    <TD align=center>" . $images[$id]["minram"] . "</TD>\n";
+			print "    <TD align=center>" . $images[$id]["minprocnumber"] . "</TD>\n";
+			print "    <TD align=center>" . $images[$id]["minprocspeed"] . "</TD>\n";
+			print "    <TD align=center>" . $images[$id]["minnetwork"] . "</TD>\n";
+			if($images[$id]['maxconcurrent'] == '')
+				print "    <TD align=center>N/A</TD>\n";
+			else
+				print "    <TD align=center>" . $images[$id]["maxconcurrent"] . "</TD>\n";
+		}
+		if($showdeleted) {
+			print "    <TD align=center>" . $images[$id]["deleted"] . "</TD>\n";
+		}
+		print "  </TR>\n";
+	}
+	print "</TABLE>\n";
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	if($showdeleted) {
+		$cdata = array('showdeleted' => 0);
+		print "<INPUT type=submit value=\"Hide Deleted Images\">\n";
+	}
+	else {
+		$cdata = array('showdeleted' => 1);
+		print "<INPUT type=submit value=\"Include Deleted Images\">\n";
+	}
+	$cont = addContinuationsEntry('viewImages', $cdata);
+	print "<INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "</FORM>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn viewImageGrouping()
+///
+/// \brief prints a page to view and modify image grouping
+///
+////////////////////////////////////////////////////////////////////////////////
+function viewImageGrouping() {
+	global $mode;
+	$resources = getUserResources(array("imageAdmin"), 
+	                              array("manageGroup"));
+	if(! count($resources["image"])) {
+		print "<H2>Image Grouping</H2>\n";
+		print "You don't have access to modify any image groups.<br>\n";
+		return;
+	}
+	if($mode == 'submitImageGroups')
+		$gridSelected = "selected=\"true\"";
+	else
+		$gridSelected = "";
+	
+	print "<H2>Image Grouping</H2>\n";
+	print "<div id=\"mainTabContainer\" dojoType=\"dijit.layout.TabContainer\"\n";
+	print "     style=\"width:800px;height:600px\">\n";
+
+	# by image tab
+	print "<div id=\"resource\" dojoType=\"dijit.layout.ContentPane\" title=\"By Image\">\n";
+	print "Select an image and click \"Get Groups\" to see all of the groups ";
+	print "it is in. Then,<br>select a group it is in and click the Remove ";
+	print "button to remove it from that group,<br>or select a group it is not ";
+	print "in and click the Add button to add it to that group.<br><br>\n";
+	print "Image:<select name=images id=images>\n";
+	# build list of images
+	$tmp = getUserResources(array('imageAdmin'), array('manageGroup'));
+	$images = $tmp['image'];
+	uasort($images, 'sortKeepIndex');
+	foreach($images as $id => $image) {
+		print "<option value=$id>$image</option>\n";
+	}
+	print "</select>\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"fetchGrpsButton\">\n";
+	print "	Get Groups\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	print "		getGroupsButton();\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "<table><tbody><tr>\n";
+	# select for groups image is in
+	print "<td valign=top>\n";
+	print "Groups <span style=\"font-weight: bold;\" id=inimagename></span> is in:<br>\n";
+	print "<select name=ingroups multiple id=ingroups size=20>\n";
+	print "</select>\n";
+	print "</td>\n";
+	# transfer buttons
+	print "<td style=\"vertical-align: middle;\">\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"addBtn1\">\n";
+	print "  <div style=\"width: 50px;\">&lt;-Add</div>\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	$cont = addContinuationsEntry('AJaddGroupToImage');
+	print "		addRemItem('$cont', 'images', 'outgroups', addRemImage2);\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "<br>\n";
+	print "<br>\n";
+	print "<br>\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"remBtn1\">\n";
+	print "	<div style=\"width: 50px;\">Remove-&gt;</div>\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	$cont = addContinuationsEntry('AJremGroupFromImage');
+	print "		addRemItem('$cont', 'images', 'ingroups', addRemImage2);\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "</td>\n";
+	# select for groups image is not in
+	print "<td valign=top>\n";
+	print "Groups <span style=\"font-weight: bold;\" id=outimagename></span> is not in:<br>\n";
+	print "<select name=outgroups multiple id=outgroups size=20>\n";
+	print "</select>\n";
+	print "</td>\n";
+	print "</tr><tbody/></table>\n";
+	print "</div>\n";
+
+	# by group tab
+	print "<div id=\"group\" dojoType=\"dijit.layout.ContentPane\" title=\"By Group\">\n";
+	print "Select a group and click \"Get Images\" to see all of the images ";
+	print "in it. Then,<br>select an image in it and click the Remove ";
+	print "button to remove it from the group,<br>or select an image that is not ";
+	print "in it and click the Add button to add it to the group.<br><br>\n";
+	print "Group:<select name=imgGroups id=imgGroups>\n";
+	# build list of groups
+	$tmp = getUserResources(array('imageAdmin'), array('manageGroup'), 1);
+	$groups = $tmp['image'];
+	uasort($groups, 'sortKeepIndex');
+	foreach($groups as $id => $group) {
+		print "<option value=$id>$group</option>\n";
+	}
+	print "</select>\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"fetchImgsButton\">\n";
+	print "	Get Images\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	print "		getImagesButton();\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "<table><tbody><tr>\n";
+	# select for images in group
+	print "<td valign=top>\n";
+	print "Images in <span style=\"font-weight: bold;\" id=ingroupname></span>:<br>\n";
+	print "<select name=inimages multiple id=inimages size=20>\n";
+	print "</select>\n";
+	print "</td>\n";
+	# transfer buttons
+	print "<td style=\"vertical-align: middle;\">\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"addBtn2\">\n";
+	print "  <div style=\"width: 50px;\">&lt;-Add</div>\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	$cont = addContinuationsEntry('AJaddImageToGroup');
+	print "		addRemItem('$cont', 'imgGroups', 'outimages', addRemGroup2);\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "<br>\n";
+	print "<br>\n";
+	print "<br>\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"remBtn2\">\n";
+	print "	<div style=\"width: 50px;\">Remove-&gt;</div>\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	$cont = addContinuationsEntry('AJremImageFromGroup');
+	print "		addRemItem('$cont', 'imgGroups', 'inimages', addRemGroup2);\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "</td>\n";
+	# images not in group select
+	print "<td valign=top>\n";
+	print "Images not in <span style=\"font-weight: bold;\" id=outgroupname></span>:<br>\n";
+	print "<select name=outimages multiple id=outimages size=20>\n";
+	print "</select>\n";
+	print "</td>\n";
+	print "</tr><tbody/></table>\n";
+	print "</div>\n";
+
+	# grid tab
+	$cont = addContinuationsEntry('imageGroupingGrid');
+	$loadingmsg = "<span class=dijitContentPaneLoading>Loading page (this may take a really long time)</span>";
+	print "<a jsId=\"checkboxpane\" dojoType=\"dijit.layout.LinkPane\"\n";
+	print "   href=\"index.php?continuation=$cont\"\n";
+	print "   loadingMessage=\"$loadingmsg\" $gridSelected>\n";
+	print "   Checkbox Grid</a>\n";
+
+	print "</div>\n"; # end of main tab container
+	$cont = addContinuationsEntry('jsonImageGroupingImages');
+	print "<input type=hidden id=imgcont value=\"$cont\">\n";
+	$cont = addContinuationsEntry('jsonImageGroupingGroups');
+	print "<input type=hidden id=grpcont value=\"$cont\">\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn imageGroupingGrid()
+///
+/// \brief prints a page to view and modify image grouping
+///
+////////////////////////////////////////////////////////////////////////////////
+function imageGroupingGrid() {
+	global $mode;
+	$imagemembership = getResourceGroupMemberships("image");
+	$resources = getUserResources(array("imageAdmin"), 
+	                              array("manageGroup"));
+	$tmp = getUserResources(array("imageAdmin"), 
+	                        array("manageGroup"), 1);
+	$imagegroups = $tmp["image"];
+	uasort($imagegroups, "sortKeepIndex");
+	uasort($resources["image"], "sortKeepIndex");
+
+	print "<FORM id=gridform action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	print "<TABLE border=1 summary=\"\">\n";
+	print "  <col>\n";
+	foreach(array_keys($imagegroups) as $id) {
+		print "  <col id=imggrp$id>\n";
+	}
+	print "  <TR>\n";
+	print "    <TH rowspan=2>Image</TH>\n";
+	print "    <TH class=nohlcol colspan=" . count($imagegroups) . ">Groups</TH>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	foreach($imagegroups as $id => $group) {
+		print "    <TH onclick=\"toggleColSelect('imggrp$id');\">$group</TH>\n";
+	}
+	print "  </TR>\n";
+	$count = 1;
+	foreach($resources["image"] as $imageid => $image) {
+		if($image == "No Image")
+			continue;
+		if($count % 8 == 0) {
+			print "  <TR>\n";
+			print "    <TH><img src=images/blank.gif></TH>\n";
+			foreach($imagegroups as $id => $group) {
+				print "    <TH onclick=\"toggleColSelect('imggrp$id');\">$group</TH>\n";
+			}
+			print "  </TR>\n";
+		}
+		print "  <TR id=imageid$imageid>\n";
+		print "    <TH align=right onclick=\"toggleRowSelect('imageid$imageid');\">$image</TH>\n";
+		foreach(array_keys($imagegroups) as $groupid) {
+			$name = "imagegroup[" . $imageid . ":" . $groupid . "]";
+			if(array_key_exists($imageid, $imagemembership["image"]) &&
+				in_array($groupid, $imagemembership["image"][$imageid])) {
+				$checked = "checked";
+			}
+			else {
+				$checked = "";
+			}
+			print "    <TD align=center>\n";
+			print "      <INPUT type=checkbox name=\"$name\" $checked>\n";
+			print "    </TD>\n";
+		}
+		print "  </TR>\n";
+		$count++;
+	}
+	print "</TABLE>\n";
+	$cont = addContinuationsEntry('submitImageGroups', array(), SECINWEEK, 1, 0, 1);
+	print "<INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "<INPUT type=submit value=\"Submit Changes\">\n";
+	print "<INPUT type=reset value=Reset>\n";
+	print "</FORM>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn viewImageMapping()
+///
+/// \brief prints a page to modify image group to computer group mappings
+///
+////////////////////////////////////////////////////////////////////////////////
+function viewImageMapping() {
+	global $mode;
+	$tmp = getUserResources(array("imageAdmin"), 
+                           array("manageGroup"), 1);
+	$imagegroups = $tmp["image"];
+	uasort($imagegroups, "sortKeepIndex");
+	$imagecompmapping = getResourceMapping("image", "computer");
+	$resources = getUserResources(array("computerAdmin"),
+	                              array("manageGroup"), 1);
+	$compgroups = $resources["computer"];
+	uasort($compgroups, "sortKeepIndex");
+	if(! count($imagegroups) || ! count($compgroups)) {
+		print "<H2>Image Group to Computer Group Mapping</H2>\n";
+		print "You don't have access to manage any image group to computer ";
+		print "group mappings.<br>\n";
+		return;
+	}
+	if($mode == 'submitImageMapping')
+		$gridSelected = "selected=\"true\"";
+	else
+		$gridSelected = "";
+	
+	print "<H2>Image Group to Computer Group Mapping</H2>\n";
+	print "<div id=\"mainTabContainer\" dojoType=\"dijit.layout.TabContainer\"\n";
+	print "     style=\"width:800px;height:600px\">\n";
+
+	# by image group
+	print "<div id=\"imagegrptab\" dojoType=\"dijit.layout.ContentPane\" ";
+	print "title=\"By Image Group\">\n";
+	print "Select an image group and click \"Get Computer Groups\" to see all ";
+	print "of the computer groups it maps to. Then,<br>select a computer group ";
+	print "it maps to and click the Remove button to unmap it from that group, ";
+	print "or select a<br>computer group it does not map to and click the Add ";
+	print "button to map it to that group.<br><br>\n";
+	print "Image Group:<select name=imagegrps id=imagegrps>\n";
+	foreach($imagegroups as $id => $group) {
+		print "<option value=$id>$group</option>\n";
+	}
+	print "</select>\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"fetchCompGrpsButton\">\n";
+	print "	Get Computer Groups\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	print "		getMapCompGroupsButton();\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "<table><tbody><tr>\n";
+	# select for comp groups image groups maps to
+	print "<td valign=top>\n";
+	print "Computer groups <span style=\"font-weight: bold;\" id=inimagegrpname></span> maps to:<br>\n";
+	print "<select name=incompgroups multiple id=incompgroups size=20>\n";
+	print "</select>\n";
+	print "</td>\n";
+	# transfer buttons
+	print "<td style=\"vertical-align: middle;\">\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"addBtn1\">\n";
+	print "  <div style=\"width: 50px;\">&lt;-Add</div>\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	$cont = addContinuationsEntry('AJaddCompGrpToImgGrp');
+	print "		addRemItem('$cont', 'imagegrps', 'outcompgroups', addRemCompGrpImgGrp);\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "<br>\n";
+	print "<br>\n";
+	print "<br>\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"remBtn1\">\n";
+	print "	<div style=\"width: 50px;\">Remove-&gt;</div>\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	$cont = addContinuationsEntry('AJremCompGrpFromImgGrp');
+	print "		addRemItem('$cont', 'imagegrps', 'incompgroups', addRemCompGrpImgGrp);\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "</td>\n";
+	# select for comp groups image groups does not map to
+	print "<td valign=top>\n";
+	print "Computer groups <span style=\"font-weight: bold;\" id=outimagegrpname></span> does not map to:<br>\n";
+	print "<select name=outcompgroups multiple id=outcompgroups size=20>\n";
+	print "</select>\n";
+	print "</td>\n";
+	print "</tr><tbody/></table>\n";
+	print "</div>\n";
+
+	# by computer group tab
+	print "<div id=\"group\" dojoType=\"dijit.layout.ContentPane\" title=\"By Computer Group\">\n";
+	print "Select a computer group and click \"Get Images Groups\" to see all ";
+	print "of the image groups it maps to. Then,<br>select an image group ";
+	print "it maps to and click the Remove button to unmap it from that group, ";
+	print "or select an<br>image group it does not map to and click the Add ";
+	print "button to map it to that group.<br><br>\n";
+	print "Computer Group:<select name=compgroups id=compgroups>\n";
+	# build list of groups
+	$tmp = getUserResources(array('computerAdmin'), array('manageGroup'), 1);
+	$groups = $tmp['computer'];
+	uasort($groups, 'sortKeepIndex');
+	foreach($groups as $id => $group) {
+		print "<option value=$id>$group</option>\n";
+	}
+	print "</select>\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"fetchCompsButton\">\n";
+	print "	Get Image Groups\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	print "		getMapImgGroupsButton();\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "<table><tbody><tr>\n";
+	# select for image groups comp group maps to
+	print "<td valign=top>\n";
+	print "Image groups <span style=\"font-weight: bold;\" id=incompgroupname></span> maps to:<br>\n";
+	print "<select name=inimggroups multiple id=inimggroups size=20>\n";
+	print "</select>\n";
+	print "</td>\n";
+	# transfer buttons
+	print "<td style=\"vertical-align: middle;\">\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"addBtn2\">\n";
+	print "  <div style=\"width: 50px;\">&lt;-Add</div>\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	$cont = addContinuationsEntry('AJaddImgGrpToCompGrp');
+	print "		addRemItem('$cont', 'compgroups', 'outimggroups', addRemImgGrpCompGrp);\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "<br>\n";
+	print "<br>\n";
+	print "<br>\n";
+	print "<button dojoType=\"dijit.form.Button\" id=\"remBtn2\">\n";
+	print "	<div style=\"width: 50px;\">Remove-&gt;</div>\n";
+	print "	<script type=\"dojo/method\" event=onClick>\n";
+	$cont = addContinuationsEntry('AJremImgGrpFromCompGrp');
+	print "		addRemItem('$cont', 'compgroups', 'inimggroups', addRemImgGrpCompGrp);\n";
+	print "	</script>\n";
+	print "</button>\n";
+	print "</td>\n";
+	# select for image groups comp group does not map to
+	print "<td valign=top>\n";
+	print "Images groups <span style=\"font-weight: bold;\" id=outcompgroupname></span> does not map to:<br>\n";
+	print "<select name=outimggroups multiple id=outimggroups size=20>\n";
+	print "</select>\n";
+	print "</td>\n";
+	print "</tr><tbody/></table>\n";
+	print "</div>\n";
+
+	# grid tab
+	$cont = addContinuationsEntry('imageMappingGrid');
+	$loadingmsg = "<span class=dijitContentPaneLoading>Loading page (this may take a really long time)</span>";
+	print "<a jsId=\"checkboxpane\" dojoType=\"dijit.layout.LinkPane\"\n";
+	print "   href=\"index.php?continuation=$cont\"\n";
+	print "   loadingMessage=\"$loadingmsg\" $gridSelected>\n";
+	print "   Checkbox Grid</a>\n";
+
+	print "</div>\n"; # end of main tab container
+	$cont = addContinuationsEntry('jsonImageMapCompGroups');
+	print "<input type=hidden id=compcont value=\"$cont\">\n";
+	$cont = addContinuationsEntry('jsonImageMapImgGroups');
+	print "<input type=hidden id=imgcont value=\"$cont\">\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn imageMappingGrid($imagegroups)
+///
+/// \param $imagegroups - (optional) array of imagegroups as returned by
+/// getUserResources
+///
+/// \brief prints a page to view and edit image mapping
+///
+////////////////////////////////////////////////////////////////////////////////
+function imageMappingGrid() {
+	global $mode;
+	$tmp = getUserResources(array("imageAdmin"), 
+                           array("manageGroup"), 1);
+	$imagegroups = $tmp["image"];
+	uasort($imagegroups, "sortKeepIndex");
+	$imagecompmapping = getResourceMapping("image", "computer");
+	$resources2 = getUserResources(array("computerAdmin"),
+	                               array("manageGroup"), 1);
+	$compgroups = $resources2["computer"];
+	uasort($compgroups, "sortKeepIndex");
+
+	if(! count($imagegroups) || ! count($compgroups)) {
+		print "You don't have access to manage any image group to computer group ";
+		print "mappings.<br>\n";
+		return;
+	}
+
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	print "<TABLE border=1>\n";
+	print "  <col>\n";
+	foreach(array_keys($compgroups) as $id) {
+		print "  <col id=compgrp$id>\n";
+	}
+	print "  <TR>\n";
+	print "    <TH rowspan=2>Image Group</TH>\n";
+	print "    <TH class=nohlcol colspan=" . count($compgroups) . ">Computer Groups</TH>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	foreach($compgroups as $id => $group) {
+		print "    <TH onclick=\"toggleColSelect('compgrp$id');\">$group</TH>\n";
+	}
+	print "  </TR>\n";
+	$count = 1;
+	foreach($imagegroups as $imgid => $imgname) {
+		if($count % 12 == 0) {
+			print "  <TR>\n";
+			print "    <TH><img src=images/blank.gif></TH>\n";
+			foreach($compgroups as $id => $group) {
+				print "    <TH onclick=\"toggleColSelect('compgrp$id');\">$group</TH>\n";
+			}
+			print "  </TR>\n";
+		}
+		print "  <TR id=imggrpid$imgid>\n";
+		print "    <TH align=right onclick=\"toggleRowSelect('imggrpid$imgid');\">$imgname</TH>\n";
+		foreach($compgroups as $compid => $compname) {
+			$name = "mapping[" . $imgid . ":" . $compid . "]";
+			if(array_key_exists($imgid, $imagecompmapping) &&
+				in_array($compid, $imagecompmapping[$imgid])) {
+				$checked = "checked";
+			}
+			else
+				$checked = "";
+			print "    <TD align=center>\n";
+			print "      <INPUT type=checkbox name=\"$name\" $checked>\n";
+			print "    </TD>\n";
+		}
+		print "  </TR>\n";
+		$count++;
+	}
+	print "</TABLE>\n";
+	$cont = addContinuationsEntry('submitImageMapping', array(), SECINWEEK, 1, 0, 1);
+	print "<INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "<INPUT type=submit value=\"Submit Changes\">\n";
+	print "<INPUT type=reset value=Reset>\n";
+	print "</FORM>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn createSelectImage()
+///
+/// \brief prints a page to select a base image for new image/image to update
+///
+////////////////////////////////////////////////////////////////////////////////
+function createSelectImage() {
+	global $submitErr, $user;
+	$timestamp = processInputVar("stamp", ARG_NUMERIC);
+	$imageid = processInputVar("imageid", ARG_STRING);
+	$length = processInputVar("length", ARG_NUMERIC);
+	$day = processInputVar("day", ARG_STRING);
+	$hour = processInputVar("hour", ARG_NUMERIC);
+	$minute = processInputVar("minute", ARG_NUMERIC);
+	$meridian = processInputVar("meridian", ARG_STRING);
+
+	if(! $submitErr) {
+		print "<H2>Create / Update an Image</H2>\n";
+	}
+	$resources = getUserResources(array("imageAdmin"));
+	if(empty($resources['image'])) {
+		print "You don't have access to any base images from which to create ";
+		print "new images.<br>\n";
+		return;
+	}
+	print "Please select the environment you will be updating or using as a ";
+	print "base for a new image:<br>\n";
+
+	$OSs = getOSList();
+
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	// list of images
+	uasort($resources["image"], "sortKeepIndex");
+	#printSelectInput("imageid", $resources["image"], $imageid, 1);
+	printSelectInput("imageid", $resources["image"], $imageid, 1, 0, 'imagesel', "onChange=\"updateWaitTime(1);\" tabIndex=1");
+	print "<br><br>\n";
+
+	$imagenotes = getImageNotes($imageid);
+	$desc = '';
+	if(preg_match('/\w/', $imagenotes['description'])) {
+		$desc = preg_replace("/\n/", '<br>', $imagenotes['description']);
+		$desc = preg_replace("/\r/", '', $desc);
+		$desc = "<strong>Image Description</strong>:<br>\n$desc<br><br>\n";
+	}
+	print "<div id=imgdesc>$desc</div>\n";
+
+	print "When would you like to start the imaging process?<br><br>\n";
+	print "&nbsp;&nbsp;&nbsp;<INPUT type=radio name=time id=timenow ";
+	print "onclick='updateWaitTime(0);' value=now>Now<br>\n";
+	print "&nbsp;&nbsp;&nbsp;<INPUT type=radio name=time value=future ";
+	print "onclick='updateWaitTime(0);' checked>Later:\n";
+
+	#print "&nbsp;&nbsp;&nbsp;<INPUT type=radio name=time value=now>Now<br>\n";
+	#print "&nbsp;&nbsp;&nbsp;<INPUT type=radio name=time value=future checked>Later:\n";
+	if($submitErr) {
+		$hour24 = $hour;
+		if($hour24 == 12) {
+			if($meridian == "am") {
+				$hour24 = 0;
+			}
+		}
+		elseif($meridian == "pm") {
+			$hour24 += 12;
+		}
+		list($month, $day, $year) = explode('/', $day);
+		$stamp = datetimeToUnix("$year-$month-$day $hour24:$minute:00");
+		$day = date('l', $stamp);
+		printReserveItems(1, $day, $hour, $minute, $meridian, 0, 0, 1);
+	}
+	elseif(empty($timestamp)) {
+		printReserveItems(1, NULL, NULL, NULL, NULL, 0, 0, 1);
+	}
+	else {
+		$timeArr = explode(',', date('l,g,i,a', $timestamp));
+		printReserveItems(1, $timeArr[0], $timeArr[1], $timeArr[2], $timeArr[3], 0, 0, 1);
+	}
+
+	print "<div id=waittime class=hidden></div><br>\n";
+
+	$cdata = array('length' => 480);
+	$cont = addContinuationsEntry('submitCreateImage', $cdata, SECINDAY, 1, 0);
+	print "<INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "<INPUT type=submit value=\"Create Imaging Reservation\">\n";
+	print "</FORM>\n";
+	$cont = addContinuationsEntry('AJupdateWaitTime');
+	print "<INPUT type=hidden name=waitcontinuation id=waitcontinuation value=\"$cont\">\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitCreateImage()
+///
+/// \brief checks to see if the request can fit in the schedule; adds it if
+/// it fits; notifies the user either way
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitCreateImage() {
+	global $submitErr, $user, $viewmode, $HTMLheader, $printedHTMLheader, $mode;
+
+	if($mode == 'submitCreateTestProd') {
+		$data = getContinuationVar();
+		$data["revisionid"] = processInputVar("revisionid", ARG_MULTINUMERIC);
+		# TODO check for valid revisionid
+	}
+	else {
+		$data = processRequestInput(0);
+		$data['length'] = getContinuationVar('length');
+	}
+
+	$showrevisions = 0;
+	$subimages = 0;
+	$images = getImages();
+	$revcount = count($images[$data['imageid']]['imagerevision']);
+	if($revcount > 1)
+		$showrevisions = 1;
+	if($images[$data['imageid']]['imagemetaid'] != NULL &&
+	   count($images[$data['imageid']]['subimages'])) {
+		$subimages = 1;
+		foreach($images[$data['imageid']]['subimages'] as $subimage) {
+			$revcount = count($images[$subimage]['imagerevision']);
+			if($revcount > 1)
+				$showrevisions = 1;
+		}
+	}
+
+	if($data["time"] == "now") {
+		$nowArr = getdate();
+		if($nowArr["minutes"] == 0) {
+			$subtract = 0;
+			$add = 0;
+		}
+		elseif($nowArr["minutes"] < 15) {
+			$subtract = $nowArr["minutes"] * 60;
+			$add = 900;
+		}
+		elseif($nowArr["minutes"] < 30) {
+			$subtract = ($nowArr["minutes"] - 15) * 60;
+			$add = 900;
+		}
+		elseif($nowArr["minutes"] < 45) {
+			$subtract = ($nowArr["minutes"] - 30) * 60;
+			$add = 900;
+		}
+		elseif($nowArr["minutes"] < 60) {
+			$subtract = ($nowArr["minutes"] - 45) * 60;
+			$add = 900;
+		}
+		$start = time() - $subtract;
+		$start -= $start % 60;
+		$nowfuture = "now";
+	}
+	else {
+		$add = 0;
+		$hour = $data["hour"];
+		if($data["hour"] == 12) {
+			if($data["meridian"] == "am") {
+				$hour = 0;
+			}
+		}
+		elseif($data["meridian"] == "pm") {
+			$hour = $data["hour"] + 12;
+		}
+
+		$tmp = explode('/', $data["day"]);
+		$start = mktime($hour, $data["minute"], "0", $tmp[0], $tmp[1], $tmp[2]);
+		if($start < time()) {
+			print $HTMLheader;
+			print "<H2>Create / Update an Image</H2>\n";
+			print "<font color=\"#ff0000\">The time you requested is in the past.";
+			print " Please select \"Now\" or use a time in the future.</font><br>\n";
+			$submitErr = 1;
+			createSelectImage();
+			return;
+		}
+		$nowfuture = "future";
+	}
+	// FIXME hard code length to 8 hours
+	$data["length"] = 480;
+	$end = $start + $data["length"] * 60 + $add;
+
+	// get semaphore lock
+	if(! semLock())
+		abort(3);
+
+	$max = getMaxOverlap($user['id']);
+	if(checkOverlap($start, $end, $max)) {
+		$printedHTMLheader = 1;
+		print $HTMLheader;
+		print "<H2>New Reservation</H2>\n";
+		if($max == 0) {
+			print "<font color=\"#ff0000\">The time you requested overlaps with ";
+			print "another reservation you currently have.  You are only allowed ";
+			print "to have a single reservation at any given time. Please select ";
+			print "another time to use the application. If you are finished with ";
+			print "an active reservation, click \"Current Reservations\", ";
+			print "then click the \"End\" button of your active reservation.";
+			print "</font><br><br>\n";
+		}
+		else {
+			print "<font color=\"#ff0000\">The time you requested overlaps with ";
+			print "another reservation you currently have.  You are allowed ";
+			print "to have $max overlapping reservations at any given time. ";
+			print "Please select another time to use the application. If you are ";
+			print "finished with an active reservation, click \"Current ";
+			print "Reservations\", then click the \"End\" button of your active ";
+			print "reservation.</font><br><br>\n";
+		}
+		$submitErr = 1;
+		createSelectImage();
+		return;
+	}
+	// if user is owner of the image and there is a test revision of the image
+	#   available, ask user if production or test image desired
+	if($mode != "submitCreateTestProd" && $showrevisions &&
+	   $images[$data["imageid"]]["ownerid"] == $user["id"]) {
+		$printedHTMLheader = 1;
+		print $HTMLheader;
+		print "<H2>New Reservation</H2>\n";
+		if($subimages) {
+			print "This is a cluster environment. At least one image in the ";
+			print "cluster has more than one revision available. Please select ";
+			print "the revision you desire for each image listed below:<br>\n";
+		}
+		else {
+			print "There are multiple revisions of this environment available.  Please ";
+			print "select the revision you would like to check out:<br>\n";
+		}
+		print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post><br>\n";
+		if(! array_key_exists('subimages', $images[$data['imageid']]))
+			$images[$data['imageid']]['subimages'] = array();
+		array_unshift($images[$data['imageid']]['subimages'], $data['imageid']);
+		foreach($images[$data['imageid']]['subimages'] as $subimage) {
+			print "{$images[$subimage]['prettyname']}:<br>\n";
+			print "<table summary=\"lists revisions of the selected environment, one must be selected to continue\">\n";
+			print "  <TR>\n";
+			print "    <TD></TD>\n";
+			print "    <TH>Revision</TH>\n";
+			print "    <TH>Creator</TH>\n";
+			print "    <TH>Created</TH>\n";
+			print "    <TH>Currently in Production</TH>\n";
+			print "  </TR>\n";
+			foreach($images[$subimage]['imagerevision'] as $revision) {
+				print "  <TR>\n";
+				if(array_key_exists($subimage, $data['revisionid']) && 
+				   $data['revisionid'][$subimage] == $revision['id'])
+					print "    <TD align=center><INPUT type=radio name=revisionid[$subimage] value={$revision['id']} checked></TD>\n";
+				elseif($revision['production'])
+					print "    <TD align=center><INPUT type=radio name=revisionid[$subimage] value={$revision['id']} checked></TD>\n";
+				else
+					print "    <TD align=center><INPUT type=radio name=revisionid[$subimage] value={$revision['id']}></TD>\n";
+				print "    <TD align=center>{$revision['revision']}</TD>\n";
+				print "    <TD align=center>{$revision['user']}</TD>\n";
+				print "    <TD align=center>{$revision['prettydate']}</TD>\n";
+				if($revision['production'])
+					print "    <TD align=center>Yes</TD>\n";
+				else
+					print "    <TD align=center>No</TD>\n";
+				print "  </TR>\n";
+			}
+			print "</TABLE>\n";
+		}
+		addContinuationsEntry('submitCreateImage', array(), SECINDAY, 1, 0); // we add this continuation back
+		                                                                     //   so the currently displayed
+		                                                                     //   page can be reloaded
+		$cont = addContinuationsEntry('submitCreateTestProd', $data);
+		print "<br><INPUT type=hidden name=continuation value=\"$cont\">\n";
+		print "<INPUT type=submit value=Submit>\n";
+		print "</FORM>\n";
+		return;
+	}
+	$rc = isAvailable($images, $data["imageid"], $start, $end, $data["os"]);
+	if($rc == -1) {
+		$printedHTMLheader = 1;
+		print $HTMLheader;
+		print "<H2>Create / Update an Image</H2>\n";
+		print "You have requested an environment that is limited in the number ";
+		print "of concurrent reservations that can be made. No further ";
+		print "reservations for the environment can be made for the time you ";
+		print "have selected. Please select another time to use the ";
+		print "environment.<br>";
+	}
+	elseif($rc > 0) {
+		$requestid = addRequest(1, $data['revisionid']);
+		if($data["time"] == "now") {
+			header("Location: " . BASEURL . SCRIPT . "?mode=viewRequests");
+			dbDisconnect();
+			exit;
+		}
+		else {
+			$time = prettyLength($data["length"]);
+			if($data["minute"] == 0) {
+				$data["minute"] = "00";
+			}
+			$printedHTMLheader = 1;
+			print $HTMLheader;
+			print "<H2>Create / Update an Image</H2>\n";
+			print "Your request to use <b>" . $images[$data["imageid"]]["prettyname"];
+			print "</b> on " . prettyDatetime($start) . " for $time has been ";
+			print "accepted.<br><br>\n";
+			print "When your reservation time has been reached, the ";
+			print "<b>Current Reservations</b> page will give you more ";
+			print "information on connecting to the reserved computer. If you ";
+			print "would like to modify your reservation, you can do that from ";
+			print "the <b>Current Reservations</b> page as well.<br>\n";
+		}
+	}
+	else {
+		$printedHTMLheader = 1;
+		print $HTMLheader;
+		$cdata = array('imageid' => $data['imageid'],
+		               'length' => $data['length']);
+		$cont = addContinuationsEntry('selectTimeTable', $cdata);
+		print "<H2>Create / Update an Image</H2>\n";
+		print "The reservation you have requested is not available. You may ";
+		print "<a href=\"" . BASEURL . SCRIPT . "?continuation=$cont\">";
+		print "view a timetable</a> of free and reserved times to find ";
+		print "a time that will work for you.<br>\n";
+		#addLogEntry($nowfuture, unixToDatetime($start), 
+		#            unixToDatetime($end), 0, $data["imageid"]);
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn startImage()
+///
+/// \brief prints page prompting user if updating existing image or creating a
+/// new image
+///
+////////////////////////////////////////////////////////////////////////////////
+function startImage() {
+	global $user;
+	$requestid = getContinuationVar("requestid");
+
+	$data = getRequestInfo($requestid);
+	$disableUpdate = 1;
+	$imageid = '';
+	foreach($data["reservations"] as $res) {
+		if($res["forcheckout"]) {
+			$imageid = $res["imageid"];
+			break;
+		}
+	}
+	if(! empty($imageid)) {
+		$imageData = getImages(0, $imageid);
+		if($imageData[$imageid]['ownerid'] == $user['id'])
+			$disableUpdate = 0;
+	}
+	print "<H2>Create / Update an Image</H2>\n";
+	print "Are you creating a new image from a base image or updating an ";
+	print "existing image?<br><br>\n";
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cdata = array('requestid' => $requestid);
+	$cont = addContinuationsEntry('newImage', $cdata, SECINDAY, 0);
+	print "<INPUT type=radio name=continuation value=\"$cont\" id=newimage checked>";
+	print "<label for=newimage>Creating New Image</label><br>\n";
+	if($disableUpdate) {
+		print "<INPUT type=radio name=continuation value=\"$cont\" ";
+		print "id=updateimage disabled><label for=updateimage><font color=gray>";
+		print "Update Existing Image</font></label>";
+	}
+	else {
+		$cdata['nextmode'] = 'updateExistingImageComments';
+		$cdata['multicall'] = 1;
+		$cont = addContinuationsEntry('imageClickThroughAgreement', $cdata, SECINDAY, 0);
+		print "<INPUT type=radio name=continuation value=\"$cont\" ";
+		print "id=updateimage><label for=updateimage>Update Existing Image";
+		print "</label>";
+	}
+	print "<br><br>\n";
+	print "<INPUT type=submit value=Submit>\n";
+	print "</FORM>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitImageButton
+///
+/// \brief wrapper for confirmDeleteImage, editOrAddImage(0), and 
+/// viewImageDetails
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitImageButton() {
+	$submode = processInputVar("submode", ARG_STRING);
+	if($submode == "Edit")
+		editOrAddImage(0);
+	elseif($submode == "Delete" || $submode == "Undelete")
+		confirmDeleteImage();
+	elseif($submode == "Details")
+		viewImageDetails();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn editOrAddImage($state)
+///
+/// \param $state - 0 for edit, 1 for add
+///
+/// \brief prints a form for editing an image
+///
+////////////////////////////////////////////////////////////////////////////////
+function editOrAddImage($state) {
+	global $submitErr, $mode, $submode, $user;
+
+	$images = getImages();
+	$platforms = getPlatforms();
+	$oslist = getOSList();
+	$depts = getDepartments();
+	$groups = getUserGroups(0, $user['affiliationid']);
+	$groups = array_reverse($groups, TRUE);
+	$groups[0] = array("name" => "Any");
+	$groups = array_reverse($groups, TRUE);
+
+	if($submitErr || $state == 1 || $mode == "submitEditImageButtons") {
+		$data = processImageInput(0);
+		if(get_magic_quotes_gpc()) {
+			$data["description"] = stripslashes($data['description']);
+			$data["usage"] = stripslashes($data['usage']);
+			$data["comments"] = stripslashes($data['comments']);
+		}
+		$data['imageid'] = getContinuationVar('imageid');
+		if($mode == "newImage") {
+			$requestdata = getRequestInfo($data['requestid']);
+			$imagedata = getImages(0, $requestdata["reservations"][0]["imageid"]);
+			$data["platformid"] = $imagedata[$requestdata["reservations"][0]["imageid"]]["platformid"];
+			$data["osid"] = $imagedata[$requestdata["reservations"][0]["imageid"]]["osid"];
+		}
+	}
+	elseif($mode == 'submitAddSubimage')
+		$data = getContinuationVar();
+	else {
+		$id = getContinuationVar("imageid");
+		$data = $images[$id];
+		$data["imageid"] = $id;
+		$tmp = getImageNotes($id);
+		$data['description'] = $tmp['description'];
+		$data['usage'] = $tmp['usage'];
+		# commented out sometime before 9-30-08
+		/*$data["prettyname"] = $images[$id]["prettyname"];
+		$data["deptid"] = $images[$id]["deptid"];
+		$data["owner"] = $images[$id]["owner"];
+		$data["platformid"] = $images[$id]["platformid"];
+		$data["osid"] = $images[$id]["osid"];
+		$data["minram"] = $images[$id]["minram"];
+		$data["minprocnumber"] = $images[$id]["minprocnumber"];
+		$data["minprocspeed"] = $images[$id]["minprocspeed"];
+		$data["minnetwork"] = $images[$id]["minnetwork"];
+		$data["reloadtime"] = $images[$id]["reloadtime"];*/
+	}
+
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	print "<DIV align=center>\n";
+	if($state)
+		print "<H2>Add Image</H2>\n";
+	else
+		print "<H2>Edit Image</H2>\n";
+	print "<TABLE>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Name:</TH>\n";
+	print "    <TD><INPUT type=text name=prettyname value=\"";
+	print $data["prettyname"] . "\" maxlength=60 size=40></TD>\n";
+	print "    <TD>";
+	printSubmitErr(PRETTYNAMEERR);
+	print "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Owner:</TH>\n";
+	print "    <TD><INPUT type=text name=owner value=\"" . $data["owner"];
+	print "\" size=40></TD>\n";
+	print "    <TD>";
+	printSubmitErr(IMGOWNERERR);
+	print "</TD>\n";
+	print "  </TR>\n";
+	/*print "  <TR>\n";
+	print "    <TH align=right>Platform:</TH>\n";
+	print "    <TD>\n";
+	printSelectInput("platformid", $platforms, $data["platformid"]);
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>OS:</TH>\n";
+	print "    <TD>\n";
+	printSelectInput("osid", $oslist, $data["osid"]);
+	print "    </TD>\n";
+	print "  </TR>\n";*/
+	print "  <TR>\n";
+	print "    <TD colspan=3>\n";
+	print "<fieldset>\n";
+	print "<legend>Image Description</legend>\n";
+	print "Description of image (required - users will<br>\nsee this on the <strong>";
+	print "New Reservations</strong> page):<br>\n";
+	printSubmitErr(IMAGEDESCRIPTIONERR);
+	print "<textarea dojoType=\"dijit.form.Textarea\" name=description ";
+	print "style=\"width: 400px; text-align: left;\">{$data['description']}\n\n";
+	print "</textarea>\n";
+	print "</fieldset>\n";
+	print "<fieldset>\n";
+	print "<legend>Usage Notes</legend>\n";
+	print "Optional notes to the user explaining how to use the image<br>";
+	print "(users will see this on the <strong>Connect!</strong> page):<br>\n";
+	print "<textarea dojoType=\"dijit.form.Textarea\" name=usage ";
+	print "style=\"width: 400px; text-align: left;\"\">{$data['usage']}\n\n";
+	print "</textarea>\n";
+	print "</fieldset>\n";
+	if($state) {
+		print "<fieldset>\n";
+		print "<legend>Revision Comments</legend>\n";
+		print "Notes for yourself and other admins about how the image ";
+		print "was setup/installed.<br>\nThese are optional and not visible to end ";
+		print "users.<br>\n";
+		print "<textarea dojoType=\"dijit.form.Textarea\" name=comments ";
+		print "style=\"width: 400px; text-align: left;\"\">{$data['comments']}\n\n";
+		print "</textarea>\n";
+		print "</fieldset>\n";
+	}
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "</TABLE><br>\n";
+	print "<div dojoType=\"dijit.TitlePane\" title=\"Advanced Options - leave ";
+	print "default values unless you really know what you are doing\" ";
+	print "open=false style=\"width: 500px\">\n";
+	print "<TABLE>\n";
+	print "  <TR>\n";
+	print "    <TD colspan=3 id=hide1><hr></TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TD colspan=3 id=hide2><strong>Advanced Options - leave default values unless you really know what you are doing</strong><br><br></TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum RAM (MB):</TH>\n";
+	print "    <TD><INPUT type=text name=minram value=\"";
+	print $data["minram"] . "\" maxlength=5 size=6></TD>\n";
+	print "    <TD>";
+	printSubmitErr(MINRAMERR);
+	print "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum Num of Processors:</TH>\n";
+	print "    <TD>\n";
+	$tmpArr = array("1" => "1", "2" => "2", "4" => "4", "8" => "8");
+	printSelectInput("minprocnumber", $tmpArr, $data["minprocnumber"]);
+	print "    </TD>\n";
+	print "    <TD></TD>";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum Processor Speed (MHz):</TH>\n";
+	print "    <TD><INPUT type=text name=minprocspeed value=\"";
+	print $data["minprocspeed"] . "\" maxlength=5 size=5></TD>\n";
+	print "    <TD>";
+	printSubmitErr(MINPROCSPEEDERR);
+	print "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum Network Speed (Mbps):</TH>\n";
+	print "    <TD>\n";
+	$tmpArr = array("10" => "10", "100" => "100", "1000" => "1000");
+	printSelectInput("minnetwork", $tmpArr, $data["minnetwork"]);
+	print "    </TD>\n";
+	print "    <TD></TD>";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Maximum Concurrent Usage:</TH>\n";
+	print "    <TD><INPUT type=text name=maxconcurrent value=\"";
+	print $data["maxconcurrent"] . "\" maxlength=3 size=4>(leave empty for unlimited)</TD>\n";
+	print "    <TD>";
+	printSubmitErr(MAXCONCURRENTERR);
+	print "</TD>\n";
+	print "    <TD></TD>";
+	print "  </TR>\n";
+	if(! $state) {
+		print "  <TR>\n";
+		print "    <TH align=right>Estimated Reload Time (min):</TH>\n";
+		print "    <TD><INPUT type=text name=reloadtime value=\"";
+		print $data["reloadtime"] . "\" maxlength=3></TD>\n";
+		print "    <TD>";
+		printSubmitErr(RELOADTIMEERR);
+		print "</TD>\n";
+		print "  </TR>\n";
+	}
+	print "  <TR>\n";
+	print "    <TH align=right>Available for checkout:</TH>\n";
+	print "    <TD>\n";
+	$yesno = array(1 => "Yes", 0 => "No");
+	printSelectInput("forcheckout", $yesno, $data["forcheckout"]);
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Check for logged in user:</TH>\n";
+	if(array_key_exists("checkuser", $data) && ! $data["checkuser"])
+	   $default = 0;
+	else
+		$default = 1;
+	print "    <TD>\n";
+	printSelectInput("checkuser", $yesno, $default);
+	print "    </TD>\n";
+	print "  </TR>\n";
+	# finally just limited access so only high level access people see this
+	# because it confused too many people
+	if($user["adminlevel"] == "developer") {
+		print "  <TR>\n";
+		print "    <TH align=right>User group allowed to log in:<br>\n";
+		print "    <small>(This does not grant permission to<br>\n";
+		print "make a reservation for the image)</small></TH>\n";
+		print "    <TD>\n";
+		if(! empty($data["usergroupid"])) {
+			$default = $data["usergroupid"];
+			if(! array_key_exists($default, $groups)) {
+				if($submitErr || $mode == 'submitEditImageButtons' || $mode == 'submitAddSubimage')
+					$groups[$data['usergroupid']] = array('name' => $images[$data['imageid']]['usergroup']);
+				else
+					$groups[$data['usergroupid']] = array('name' => $data['usergroup']);
+				uasort($groups, 'sortKeepIndex');
+			}
+		}
+		else
+			$default = 0;
+		printSelectInput("usergroupid", $groups, $default);
+		print "    </TD>\n";
+		print "  </TR>\n";
+	}
+	if(! $state) {
+		print "  <TR>\n";
+		print "    <TH style=\"vertical-align:top; text-align:right;\">Subimages:</TH>\n";
+		print "    <TD>\n";
+		if(array_key_exists("subimages", $images[$data["imageid"]]) &&
+			count($images[$data["imageid"]]["subimages"])) {
+			foreach($images[$data["imageid"]]["subimages"] as $imgid) {
+				print "<INPUT type=checkbox name=\"removeimgid[$imgid]\" value=$imgid>\n";
+				print "{$images[$imgid]["prettyname"]}<br>\n";
+			}
+			print "<INPUT type=submit name=submode value=\"Remove Selected\"><br>\n"; # Remove Selected
+		}
+		print "    <INPUT type=submit name=submode value=\"Add Subimage\">\n"; # Add Subimage
+		print "    </TD>\n";
+		print "  </TR>\n";
+	}
+	else {
+		if(array_key_exists("sysprep", $data) && ! $data["sysprep"])
+			$default = 0;
+		else
+			$default = 1;
+		print "  <TR>\n";
+		print "    <TH style=\"vertical-align:top; text-align:right;\">Use sysprep:</TH>\n";
+		print "    <TD>\n";
+		printSelectInput("sysprep", $yesno, $default);
+		print "    </TD>\n";
+		print "  </TR>\n";
+	}
+	print "  <TR>\n";
+	print "    <TD colspan=3 id=hide3><hr></TD>\n";
+	print "  </TR>\n";
+	print "</TABLE>\n";
+	print "</div>\n";
+	print "<TABLE>\n";
+	print "  <TR valign=top>\n";
+	print "    <TD>\n";
+	if($state) {
+		$cdata = array('requestid' => $data['requestid'],
+		               'imageid' => $data['imageid']);
+		$cont = addContinuationsEntry('submitEditImageButtons', $cdata, SECINDAY, 0);
+		print "      <INPUT type=hidden name=continuation value=\"$cont\">\n"; # confirmAddImage
+		print "      <INPUT type=submit name=submode value=\"Confirm Image\">\n";
+	}
+	else {
+		$cdata = array('imageid' => $data['imageid']);
+		$cont = addContinuationsEntry('submitEditImageButtons', $cdata, SECINDAY, 0, 1, 1);
+		print "      <INPUT type=hidden name=continuation value=\"$cont\">\n"; # confirmEditImage
+		print "      <INPUT type=submit name=submode value=\"Confirm Changes\">\n";
+	}
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "    <TD>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	if($state)
+		$cont = addContinuationsEntry('viewRequests');
+	else
+		$cont = addContinuationsEntry('viewImages');
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <INPUT type=submit value=Cancel>\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "</TABLE>\n";
+
+	if($state)
+		return;
+	print "<div id=revisiondiv>\n";
+	print getRevisionHTML($data['imageid']);
+	print "</div>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getRevisionHTML($imageid)
+///
+/// \param $imageid - id of an image
+///
+/// \return string of HTML data
+///
+/// \brief builds HTML table for in place editing of image revision data
+///
+////////////////////////////////////////////////////////////////////////////////
+function getRevisionHTML($imageid) {
+	$rt = '';
+	$rt .= "<h3>Revisions of this Image</h3>\n";
+	$rt .= "<table summary=\"\"><tr><td>\n";
+	$rt .= "<table summary=\"\" id=\"revisiontable\">\n";
+	$rt .= "  <tr>\n";
+	$rt .= "    <td></td>\n";
+	$rt .= "    <th>Revision</th>\n";
+	$rt .= "    <th>Creator</th>\n";
+	$rt .= "    <th>Created</th>\n";
+	$rt .= "    <th nowrap>In Production</th>\n";
+	$rt .= "    <th>Comments (click to edit)</th>\n";
+	$rt .= "  </tr>\n";
+	$revisions = getImageRevisions($imageid);
+	foreach($revisions AS $rev) {
+		$rt .= "  <tr>\n";
+		$rt .= "    <td><INPUT type=checkbox\n";
+		$rt .= "              id=chkrev{$rev['id']}\n";
+		$rt .= "              name=chkrev[{$rev['id']}]\n";
+		$rt .= "              value=1></td>\n";
+		$rt .= "    <td align=center>{$rev['revision']}</td>\n";
+		$rt .= "    <td>{$rev['creator']}</td>\n";
+		$created = date('g:ia n/j/Y', datetimeToUnix($rev['datecreated']));
+		$rt .= "    <td>$created</td>\n";
+		$cdata = array('imageid' => $imageid, 'revisionid' => $rev['id']);
+		$cont = addContinuationsEntry('AJupdateRevisionProduction', $cdata);
+		if($rev['production']) {
+			$rt .= "    <td align=center><INPUT type=radio\n";
+			$rt .= "           name=production\n";
+			$rt .= "           value={$rev['id']}\n";
+			$rt .= "           id=radrev{$rev['id']}\n";
+			$rt .= "           onclick=\"updateRevisionProduction('$cont');\"\n";
+			$rt .= "           checked></td>\n";
+		}
+		else {
+			$rt .= "    <td align=center><INPUT type=radio\n";
+			$rt .= "           name=production\n";
+			$rt .= "           value={$rev['id']}\n";
+			$rt .= "           id=radrev{$rev['id']}\n";
+			$rt .= "           onclick=\"updateRevisionProduction('$cont');\">\n";
+			$rt .= "           </td>\n";
+		}
+		$cdata = array('imageid' => $imageid, 'revisionid' => $rev['id']);
+		$cont = addContinuationsEntry('AJupdateRevisionComments', $cdata);
+		$rt .= "    <td width=200px><span id=comments{$rev['id']} \n";
+		$rt .= "              dojoType=\"dijit.InlineEditBox\"\n";
+		$rt .= "              editor=\"dijit.form.Textarea\"\n";
+		$rt .= "              onChange=\"updateRevisionComments('comments{$rev['id']}', '$cont');\"\n";
+		$rt .= "              noValueIndicator=\"(empty)\">\n";
+		$rt .= "        {$rev['comments']}</span></td>\n";
+		$rt .= "  </tr>\n";
+	}
+	$rt .= "</table>\n";
+	$rt .= "<div align=left>\n";
+	$keys = array_keys($revisions);
+	$cdata = array('revids' => $keys, 'imageid' => $imageid);
+	$cont = addContinuationsEntry('AJdeleteRevisions', $cdata);
+	$ids = implode(',', $keys);
+	$rt .= "<button onclick=\"deleteRevisions('$cont', '$ids'); return false;\">Delete selected revisions</button>\n";
+	$rt .= "</div>\n";
+	$rt .= "</td></tr></table>\n";
+	return $rt;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitEditImageButtons()
+///
+/// \brief wrapper for confirmEditOrAddImage, addSubimage, and removeSubimages
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitEditImageButtons() {
+	$submode = processInputVar("submode", ARG_STRING);
+	if($submode == "Confirm Image") # confirmAddImage
+		confirmEditOrAddImage(1);
+	elseif($submode == "Confirm Changes") # confirmEditImage
+		confirmEditOrAddImage(0);
+	elseif($submode == "Remove Selected")
+		removeSubImages();
+	elseif($submode == "Add Subimage")
+		printAddSubimage();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn confirmEditOrAddImage($state)
+///
+/// \param $state - 0 for edit, 1 for add
+///
+/// \brief prints a form for confirming changes to an image
+///
+////////////////////////////////////////////////////////////////////////////////
+function confirmEditOrAddImage($state) {
+	global $submitErr, $user;
+
+	$data = processImageInput(1);
+
+	if($submitErr) {
+		editOrAddImage($state);
+		return;
+	}
+
+	if(get_magic_quotes_gpc()) {
+		$data['description'] = stripslashes($data['description']);
+		$data['usage'] = stripslashes($data['usage']);
+		$data['comments'] = stripslashes($data['comments']);
+	}
+
+	$groups = getUserGroups();
+	$groups[0] = array("name" => "Any");
+	if(! $state)
+		$images = getImages();
+
+	if($state) {
+		$nextmode = "imageClickThroughAgreement";
+		$title = "Add Image";
+		$question = "Add the following image?";
+	}
+	else {
+		$nextmode = "submitEditImage";
+		$title = "Edit Image";
+		$question = "Submit changes to the image?";
+	}
+
+	$platforms = getPlatforms();
+	$oslist = getOSList();
+	$depts = getDepartments();
+
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	print "<DIV align=center>\n";
+	print "<H2>$title</H2>\n";
+	print "$question<br><br>\n";
+	print "<TABLE>\n";
+	if(! $state) {
+		/*print "  <TR>\n";
+		print "    <TH align=right>Short Name:</TH>\n";
+		print "    <TD>" . $data["name"] . "</TD>\n";
+		print "  </TR>\n";*/
+	}
+	print "  <TR>\n";
+	print "    <TH align=right>Name:</TH>\n";
+	print "    <TD>" . $data["prettyname"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Owner:</TH>\n";
+	print "    <TD>" . $data["owner"] . "</TD>\n";
+	print "  </TR>\n";
+	/*print "  <TR>\n";
+	print "    <TH align=right>Platform:</TH>\n";
+	print "    <TD>" . $platforms[$data["platformid"]] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>OS:</TH>\n";
+	print "    <TD>" . $oslist[$data["osid"]]["prettyname"] . "</TD>\n";
+	print "  </TR>\n";*/
+	print "  <TR>\n";
+	print "    <TD colspan=2>\n";
+	print "<br><strong>Image Description</strong>:<br>\n";
+	print "{$data['description']}<br><br>\n";
+	print "<strong>Usage Notes</strong>:<br>\n";
+	print "{$data['usage']}<br><br>\n";
+	if($state) {
+		print "<strong>Revision Comments</strong>:<br>\n";
+		print "{$data['comments']}<br><br>\n";
+	}
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "</TABLE>\n";
+	print "<TABLE>\n";
+	print "  <TR>\n";
+	print "    <TD colspan=2><strong>Advanced Options</strong>:</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TD colspan=2><hr></TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum RAM (MB):</TH>\n";
+	print "    <TD>" . $data["minram"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum Num of Processors:</TH>\n";
+	print "    <TD>" . $data["minprocnumber"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum Processor Speed (MHz):</TH>\n";
+	print "    <TD>" . $data["minprocspeed"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum Network Speed (Mbps):</TH>\n";
+	print "    <TD>" . $data["minnetwork"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Maximum Concurrent Usage:</TH>\n";
+	if($data['maxconcurrent'] == '')
+		print "    <TD>N/A</TD>\n";
+	else
+		print "    <TD>" . $data["maxconcurrent"] . "</TD>\n";
+	print "  </TR>\n";
+	if(! $state) {
+		print "  <TR>\n";
+		print "    <TH align=right>Estimated Reload Time (min):</TH>\n";
+		print "    <TD>" . $data["reloadtime"] . "</TD>\n";
+		print "  </TR>\n";
+	}
+	print "  <TR>\n";
+	print "    <TH align=right>Available for checkout:</TH>\n";
+	if($data["forcheckout"])
+		print "    <TD>Yes</TD>\n";
+	else
+		print "    <TD>No</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Check for logged in user:</TH>\n";
+	if($data["checkuser"])
+		print "    <TD>Yes</TD>\n";
+	else
+		print "    <TD>No</TD>\n";
+	print "  </TR>\n";
+	if($user["adminlevel"] == "developer" || $user['adminlevel'] == 'full') {
+		print "  <TR>\n";
+		print "    <TH align=right>User group allowed to log in:</TH>\n";
+		$tmp = explode('@', $groups[$data["usergroupid"]]["name"]);
+		if(array_key_exists(1, $tmp) && $tmp[1] != $user['affiliation'])
+			print "    <TD>" . $groups[$data["usergroupid"]]["name"] . "</TD>\n";
+		else
+			print "    <TD>{$tmp[0]}</TD>\n";
+		print "  </TR>\n";
+	}
+	if(! $state) {
+		print "  <TR>\n";
+		print "    <TH style=\"vertical-align:top; text-align:right;\">Subimages:</TH>\n";
+		print "    <TD>\n";
+		if(array_key_exists("subimages", $images[$data["imageid"]]) &&
+			count($images[$data["imageid"]]["subimages"])) {
+			foreach($images[$data["imageid"]]["subimages"] as $imgid) {
+				print "{$images[$imgid]["prettyname"]}<br>\n";
+			}
+		}
+		else
+			print "None";
+		print "    </TD>\n";
+		print "  </TR>\n";
+	}
+	else {
+		print "  <TR>\n";
+		print "    <TH align=right>Use sysprep:</TH>\n";
+		if($data["sysprep"])
+			print "    <TD>Yes</TD>\n";
+		else
+			print "    <TD>No</TD>\n";
+		print "  </TR>\n";
+	}
+	print "  <TR>\n";
+	print "    <TD colspan=2><hr></TD>\n";
+	print "  </TR>\n";
+	print "</TABLE>\n";
+	print "<TABLE>\n";
+	print "  <TR valign=top>\n";
+	print "    <TD>\n";
+	$data['description'] = mysql_escape_string($data['description']);
+	$data['usage'] = mysql_escape_string($data['usage']);
+	$data['comments'] = mysql_escape_string($data['comments']);
+
+	if($state) {
+		$data['nextmode'] = 'submitAddImage';
+		$cont = addContinuationsEntry($nextmode, $data, SECINDAY, 0);
+	}
+	else
+		$cont = addContinuationsEntry($nextmode, $data, SECINDAY, 0, 0);
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	if($state)
+		print "      <INPUT type=submit value=\"Add Image\">\n";
+	else
+		print "      <INPUT type=submit value=\"Submit Changes\">\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "    <TD>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	if($state)
+		$cont = addContinuationsEntry('viewRequests');
+	else
+		$cont = addContinuationsEntry('viewImages');
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <INPUT type=submit value=Cancel>\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "</TABLE>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitEditImage()
+///
+/// \brief submits changes to image and notifies user
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitEditImage() {
+	$data = getContinuationVar();
+	updateImage($data);
+	viewImages();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn imageClickThrough()
+///
+/// \brief prints a page with the software license agreement
+///
+////////////////////////////////////////////////////////////////////////////////
+function imageClickThrough() {
+	global $clickThroughText;
+	printf($clickThroughText, "");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn imageClickThroughAgreement()
+///
+/// \brief prints a page where the user must agree to the software licensing
+/// agreement before actually creating the new image
+///
+////////////////////////////////////////////////////////////////////////////////
+function imageClickThroughAgreement() {
+	global $clickThroughText;
+	$data = getContinuationVar();
+	$nextmode = $data['nextmode'];
+	$multicall = getContinuationVar('multicall', 0);
+	unset($data['nextmode']);
+	$data['fromAgreement'] = 1;
+	$buttons  = "<center>\n";
+	$buttons .= "<table summary=\"\">\n";
+	$buttons .= "  <tr>\n";
+	$buttons .= "    <td>\n";
+	$buttons .= "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cont = addContinuationsEntry($nextmode, $data, SECINDAY, 0, $multicall);
+	$buttons .= "      <input type=hidden name=continuation value=\"$cont\">\n";
+	$buttons .= "      <input type=submit value=\"I agree\">\n";
+	$buttons .= "      </FORM>\n";
+	$buttons .= "    </td>\n";
+	$buttons .= "    <td>\n";
+	$buttons .= "      <img src=\"images/blank.gif\" alt=\"\" width=30px>\n";
+	$buttons .= "    </td>\n";
+	$buttons .= "    <td>\n";
+	$buttons .= "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cont = addContinuationsEntry('viewRequests');
+	$buttons .= "      <input type=hidden name=continuation value=\"$cont\">\n";
+	$buttons .= "      <input type=submit value=\"I do not agree\">\n";
+	$buttons .= "      </FORM>\n";
+	$buttons .= "    </td>\n";
+	$buttons .= "  </tr>\n";
+	$buttons .= "  <tr>\n";
+	$buttons .= "    <td colspan=3>\n";
+	$buttons .= "      Clicking <b>I agree</b> will start the imaging process.\n";
+	$buttons .= "    </td>\n";
+	$buttons .= "  </tr>\n";
+	$buttons .= "</table>\n";
+	$buttons .= "</center>\n";
+	printf($clickThroughText, "$buttons");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitAddImage()
+///
+/// \brief adds the image and notifies user
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitAddImage() {
+	global $user, $clickThroughText;
+	$data = getContinuationVar();
+
+	// get platformid and osid
+	$requestdata = getRequestInfo($data['requestid']);
+	$imagedata = getImages(0, $requestdata["reservations"][0]["imageid"]);
+	$data["platformid"] = $imagedata[$requestdata["reservations"][0]["imageid"]]["platformid"];
+	$data["osid"] = $imagedata[$requestdata["reservations"][0]["imageid"]]["osid"];
+	$data["basedoffrevisionid"] = $requestdata["reservations"][0]["imagerevisionid"];
+
+	// add estimated reload time
+	$data["reloadtime"] = 20;
+
+	// FIXME check for existance of image again
+	if(! $imageid = addImage($data))
+		abort(10);
+
+	// change imageid in request and reservation table and set state to image(16)
+	# FIXME will need to figure out which reservation to update for multi-image
+	# requests
+
+	// get imagerevisionid
+	$query = "SELECT id "
+	       . "FROM imagerevision "
+	       . "WHERE imageid = $imageid";
+	$qh = doQuery($query, 101);
+	$row = mysql_fetch_assoc($qh);
+	$imagerevisionid = $row['id'];
+
+	$requestid = $data["requestid"];
+	$query = "UPDATE request rq, "
+	       .        "reservation rs "
+	       . "SET rs.imageid = $imageid, "
+	       .     "rs.imagerevisionid = $imagerevisionid, "
+	       .     "rq.stateid = 16,"
+	       .     "rq.forimaging = 1 "
+	       . "WHERE rq.id = $requestid AND "
+	       .       "rq.id = rs.requestid";
+	doQuery($query, 101);
+
+	if(array_key_exists('fromAgreement', $data) && $data['fromAgreement']) {
+		$agreement = sprintf($clickThroughText, "");
+		$query = "INSERT INTO clickThroughs "
+		       .        "(userid, "
+		       .        "imageid, "
+		       .        "imagerevisionid, "
+		       .        "accepted, "
+		       .        "agreement) "
+		       . "VALUES "
+		       .        "({$user['id']}, "
+		       .        "$imageid, "
+		       .        "$imagerevisionid, "
+		       .        "NOW(), "
+		       .        "'$agreement')";
+		doQuery($query, 101);
+	}
+
+	print "<H2>Add Image</H2>\n";
+	print "The image creation process has been started.  It normally takes ";
+	print "about 25 minutes to complete (though can sometimes be more than ";
+	print "two hours).  You will be notified by email ";
+	print "when the image has been created.  At that point, you will be able ";
+	print "to make a new reservation for the image.  Once you have done so ";
+	print "and tested that it works as expected, you can add it to an image ";
+	print "group on the <a href=\"" . BASEURL . SCRIPT;
+	print "?mode=viewImageOptions\">Manage Images</a> page if you have ";
+	print "sufficient access or have your computing support add it for you.<br>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn removeSubImages()
+///
+/// \brief removes submitted subimages and calls editOrAddImage
+///
+////////////////////////////////////////////////////////////////////////////////
+function removeSubImages() {
+	$removeimgids = processInputVar("removeimgid", ARG_MULTINUMERIC);
+	$imageid = getContinuationVar("imageid");
+	$data = getImages(0, $imageid);
+	if(count($removeimgids)) {
+		# remove selected images
+		$rmids = implode(',', $removeimgids);
+		$query = "DELETE FROM subimages "
+		       . "WHERE imagemetaid = {$data[$imageid]["imagemetaid"]} AND "
+		       .       "imageid IN ($rmids)";
+		doQuery($query, 101);
+
+		# check to see if any subimages left; if not, set subimages to 0
+		$query = "SELECT COUNT(imageid) "
+		       . "FROM subimages "
+		       . "WHERE imagemetaid = {$data[$imageid]["imagemetaid"]}";
+		$qh = doQuery($query, 101);
+		$row = mysql_fetch_row($qh);
+		if($row[0] == 0) {
+			$query = "UPDATE imagemeta "
+			       . "SET subimages = 0 "
+			       . "WHERE id = {$data[$imageid]["imagemetaid"]}";
+			doQuery($query, 101);
+		}
+	}
+
+	editOrAddImage(0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn printAddSubimage()
+///
+/// \brief prints a page to add a subimage to an image
+///
+////////////////////////////////////////////////////////////////////////////////
+function printAddSubimage() {
+	# FIXME need to pass on form data so if something is changed in the edit
+	# page, it remains changed when we get back there
+	$imageid = getContinuationVar("imageid");
+	$images = getImages();
+	$data = processImageInput(0);
+	print "<H2>Add Subimage</H2>\n";
+	if(array_key_exists("subimages", $images[$imageid]) &&
+	   count($images[$imageid]["subimages"])) {
+		print "Current subimages for <strong>{$images[$imageid]["prettyname"]}:";
+		print "</strong><br><br>\n";
+		foreach($images[$imageid]["subimages"] as $imgid) {
+			print "<img src=images/blank.gif width=25 height=1>\n";
+			print "{$images[$imgid]["prettyname"]}<br>\n";
+		}
+		print "<br>Add additional subimage:<br><br>\n";
+	}
+	else
+		print "There are currently no subimages for <strong>";
+		print "{$images[$imageid]["prettyname"]}</strong>.<br><br>";
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	unset($images[$imageid]);
+	printSelectInput("addimageid", $images, -1, 1);
+	$cdata = $data;
+	$cdata['imageid'] = $imageid;
+	$cont = addContinuationsEntry('submitAddSubimage', $cdata, SECINDAY, 0, 1, 1);
+	print "<INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "<br><INPUT type=submit value=Add>\n";
+	print "</FORM>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitAddSubimage()
+///
+/// \brief adds a subimage to submitted image and calls editOrAddImage
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitAddSubimage() {
+	$imageid = getContinuationVar("imageid");
+	$addimageid = processInputVar("addimageid", ARG_NUMERIC);
+	$data = getImages(0, $imageid);
+	if(empty($data[$imageid]["imagemetaid"])) {
+		$query = "INSERT INTO imagemeta "
+		       .        "(subimages) "
+		       . "VALUES (1)";
+		doQuery($query, 101);
+		$qh = doQuery("SELECT LAST_INSERT_ID() FROM imagemeta", 101);
+		if(! $row = mysql_fetch_row($qh))
+			abort(101);
+		$imagemetaid = $row[0];
+		$query = "UPDATE image "
+		       . "SET imagemetaid = $imagemetaid "
+		       . "WHERE id = $imageid";
+		doQuery($query, 101);
+	}
+	else {
+		$imagemetaid = $data[$imageid]["imagemetaid"];
+		if(! count($data[$imageid]["subimages"])) {
+			$query = "UPDATE imagemeta "
+			       . "SET subimages = 1 "
+			       . "WHERE id = $imagemetaid";
+			doQuery($query, 101);
+		}
+	}
+	$query = "INSERT INTO subimages "
+	       .        "(imagemetaid, "
+	       .        "imageid) "
+	       . "VALUES ($imagemetaid, "
+	       .        "$addimageid)";
+	doQuery($query, 101);
+	editOrAddImage(0);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn updateExistingImageComments()
+///
+/// \brief prints a page for getting install comments about the revision before
+/// continuing on to actually creating the revision
+///
+////////////////////////////////////////////////////////////////////////////////
+function updateExistingImageComments() {
+	$cdata = getContinuationVar();
+	$data = getRequestInfo($cdata['requestid']);
+	foreach($data["reservations"] as $res) {
+		if($res["forcheckout"]) {
+			$imageid = $res["imageid"];
+			$revisionid = $res['imagerevisionid'];
+			break;
+		}
+	}
+	$revisions = getImageRevisions($imageid);
+	print "<H2>Update Existing Image</H2>\n";
+	print "<h3>New Revision Comments</h3>\n";
+	print "Enter any notes for yourself and other admins about how the image ";
+	print "was setup/installed.<br>\nThese are optional and not visible to end ";
+	print "users:<br>\n";
+	print "<form action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	print "<textarea dojoType=\"dijit.form.Textarea\" name=comments ";
+	print "style=\"width: 400px; text-align: left;\"\">\n\n</textarea>\n";
+	print "<h3>Previous Revision Comments</h3>\n";
+	if(preg_match('/\w/', $revisions[$revisionid]['comments'])) {
+		print "These are the comments from the previous revision ";
+		print "({$revisions[$revisionid]['revision']}):<br>\n";
+		print "{$revisions[$revisionid]['comments']}<br><br>\n";
+	}
+	else
+		print "The previous revision did not have any comments.<br>\n";
+	print "<table summary=\"\">\n";
+	print "  <tr>\n";
+	print "    <td>\n";
+	$cont = addContinuationsEntry('updateExistingImage', $cdata, SECINDAY, 0, 0);
+	print "      <input type=hidden name=continuation value=\"$cont\">\n";
+	print "      <input type=submit value=\"Create New Revision\">\n";
+	print "      </form>\n";
+	print "    </td>\n";
+	print "    <td>\n";
+	print "      <form action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cont = addContinuationsEntry('viewRequests');
+	print "      <input type=hidden name=continuation value=\"$cont\">\n";
+	print "      <input type=submit value=\"Cancel\">\n";
+	print "      </form>\n";
+	print "    </td>\n";
+	print "  </tr>\n";
+	print "</table>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn updateExistingImage()
+///
+/// \brief sets test flag on image to 1, sets state of request to 'image' and
+/// notifies the user that the imaging process has started
+///
+////////////////////////////////////////////////////////////////////////////////
+function updateExistingImage() {
+	global $user, $clickThroughText;
+	$requestid = getContinuationVar("requestid");
+	$fromAgreement = getContinuationVar('fromAgreement', 0);
+	$comments = processInputVar("comments", ARG_STRING);
+	$comments = preg_replace("/\r/", '', $comments);
+	$comments = htmlspecialchars($comments);
+	#$comments = preg_replace("/\n/", '<br>', $comments);
+	$comments = preg_replace("/\n/", '', $comments);
+	if(get_magic_quotes_gpc())
+		$comments = stripslashes($comments);
+	$comments = mysql_escape_string($comments);
+
+	$data = getRequestInfo($requestid);
+	foreach($data["reservations"] as $res) {
+		if($res["forcheckout"]) {
+			$imageid = $res["imageid"];
+			break;
+		}
+	}
+	$imageData = getImages(0, $imageid);
+	if($imageData[$imageid]['ownerid'] != $user['id']) {
+		editOrAddImage(1);
+		return;
+	}
+	// set the test flag on the image in the image table
+	$query = "UPDATE image SET test = 1 WHERE id = $imageid";
+	doQuery($query, 101);
+
+	# add entry to imagerevision table
+	$query = "SELECT revision, "
+	       .        "imagename "
+	       . "FROM imagerevision "
+	       . "WHERE imageid = $imageid "
+	       . "ORDER BY revision DESC "
+	       . "LIMIT 1";
+	$qh = doQuery($query, 101);
+	$row = mysql_fetch_assoc($qh);
+	$newrevision = $row['revision'] + 1;
+	$newname = preg_replace("/{$row['revision']}$/",
+	                        $newrevision, $row['imagename']);
+	$query = "INSERT INTO imagerevision "
+	       .        "(imageid, "
+	       .        "revision, "
+	       .        "userid, "
+	       .        "datecreated, "
+	       .        "deleted, "
+	       .        "production, "
+	       .        "comments, "
+	       .        "imagename) "
+	       . "VALUES ($imageid, "
+	       .        "$newrevision, "
+	       .        "{$user['id']}, "
+	       .        "NOW(), "
+	       .        "1, "
+	       .        "0, "
+	       .        "'$comments', "
+	       .        "'$newname')";
+	doQuery($query, 101);
+	$qh = doQuery("SELECT LAST_INSERT_ID() FROM imagerevision", 101);
+	$row = mysql_fetch_row($qh);
+	$imagerevisionid = $row[0];
+
+	# update request and reservation
+	$query = "UPDATE request rq, "
+	       .        "reservation rs "
+	       . "SET rs.imagerevisionid = $imagerevisionid, "
+	       .     "rq.stateid = 16,"
+	       .     "rq.forimaging = 1 "
+	       . "WHERE rq.id = $requestid AND "
+	       .       "rq.id = rs.requestid AND "
+	       .       "rs.imageid = $imageid";
+	doQuery($query, 101);
+
+	if($fromAgreement) {
+		$agreement = strip_tags(sprintf($clickThroughText, ""));
+		$query = "INSERT INTO clickThroughs "
+		       .        "(userid, "
+		       .        "imageid, "
+		       .        "accepted, "
+		       .        "agreement) "
+		       . "VALUES "
+		       .        "({$user['id']}, "
+		       .        "$imageid, "
+		       .        "NOW(), "
+		       .        "'$agreement')";
+		doQuery($query, 101);
+	}
+
+	print "<H2>Update Image</H2>\n";
+	print "The image creation process has been started.  It normally takes ";
+	print "about 20-25 minutes to complete.  You will be notified by email ";
+	print "when the image has been created.  Afterward, there are a few steps ";
+	print "you need to follow to make it the production revision of the image:";
+	print "<ol class=numbers>\n";
+	print "<li>Make a new reservation for the environment (it will have the ";
+	print "same name in the drop-down list).</li>\n";
+	print "<li>After clicking <strong>Submit</strong> on the New Reservations ";
+	print "page, you will be prompted to select the revision of the environment ";
+	print "you want</li>\n";
+	print "<li>Select the most recent revision and click <strong>Submit</strong>";
+	print "</li>\n";
+	print "<li>Test the environment to make sure it works correctly</li>\n";
+	print "<li>After you are satisfied that it works correctly, click the ";
+	print "<strong>End</strong> button on the Current Reservations page</li>\n";
+	print "<li>You will be prompted to make the revision production or just end ";
+	print "the reservation</li>\n";
+	print "<li>Select the <strong>Make this the production revision</strong> ";
+	print "radio button</li> and click <strong>Submit</strong></li>\n";
+	print "</ol>\n";
+	print "Once the revision is made production, everyone that selects it will ";
+	print "get the new revision<br>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn setImageProduction()
+///
+/// \brief prompts user if really ready to set image to production
+///
+////////////////////////////////////////////////////////////////////////////////
+function setImageProduction() {
+	$requestid = getContinuationVar('requestid');
+	$data = getRequestInfo($requestid);
+	foreach($data["reservations"] as $res) {
+		if($res["forcheckout"]) {
+			$prettyimage = $res["prettyimage"];
+			break;
+		}
+	}
+	print "<H2>Change Test Image to Production</H2>\n";
+	print "This will update the <b>$prettyimage</b> ";
+	print "environment to be the newly created revision so that people will ";
+	print "start getting it when they checkout the environment.  It will also ";
+	print "cause all the blades that currently have this image preloaded to be ";
+	print "reloaded with this new image.  Are you sure the image works ";
+	print "correctly?<br>\n";
+	print "<TABLE>\n";
+	print "  <TR>\n";
+	print "    <TD>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cdata = array('requestid' => $requestid);
+	$cont = addContinuationsEntry('submitSetImageProduction', $cdata, SECINDAY, 0, 0);
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <INPUT type=submit value=Yes>\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "    <TD>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cont = addContinuationsEntry('viewRequests');
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <INPUT type=submit value=No>\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "</TABLE>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitSetImageProduction()
+///
+/// \brief sets request state to 'makeproduction', notifies user that 
+/// "productioning" process has started
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitSetImageProduction() {
+	$requestid = getContinuationVar('requestid');
+	$data = getRequestInfo($requestid);
+	foreach($data["reservations"] as $res) {
+		if($res["forcheckout"]) {
+			$prettyimage = $res["prettyimage"];
+			break;
+		}
+	}
+	/*$regs = array();
+	if(ereg('(.*)-v([0-9]){1,2}$', $data["image"], $regs)) {
+		$newname = $regs[1] . "-v" . ++$regs[2];
+		print "newname - $newname<br>\n";
+	}
+	else {
+		$newname = $data["image"] . "-v0";
+	}
+	$query = "UPDATE image "
+	       . "SET name = '$newname', "
+	       .     "test = 0 "
+	       . "WHERE id = " . $data["imageid"];*/
+	$query = "UPDATE request SET stateid = 17 WHERE id = $requestid";
+	doQuery($query, 101);
+	//deleteRequest($data);
+	print "<H2>Change Test Image to Production</H2>\n";
+	print "<b>$prettyimage</b> is in the process of being ";
+	print "updated to use the newly created image.<br>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn confirmDeleteImage()
+///
+/// \brief prints a form to confirm the deletion of an image
+///
+////////////////////////////////////////////////////////////////////////////////
+function confirmDeleteImage() {
+	$imageid = getContinuationVar("imageid");
+	$images = getImages(1);
+	if($images[$imageid]["deleted"] == 0) {
+		$deleted = 0;
+		$title = "Delete Image";
+		$question = "Delete the following image?";
+	}
+	else {
+		$deleted = 1;
+		$title = "Undelete Image";
+		$question = "Undelete the following image?";
+	}
+
+	if(! $deleted && checkForImageUsage($imageid)) {
+		print "<H2 align=center>Delete Image</H2>\n";
+		print "The image you selected is currently in use. You cannot delete ";
+		print "the image until it is no longer being used.<br>\n";
+		return;
+	}
+
+	$platforms = getPlatforms();
+	$oslist = getOSList();
+	$depts = getDepartments();
+
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	print "<DIV align=center>\n";
+	print "<H2>$title</H2>\n";
+	print "$question<br><br>\n";
+	print "<TABLE>\n";
+	/*print "  <TR>\n";
+	print "    <TH align=right>Short Name:</TH>\n";
+	print "    <TD>" . $images[$imageid]["name"] . "</TD>\n";
+	print "  </TR>\n";*/
+	print "  <TR>\n";
+	print "    <TH align=right>Long Name:</TH>\n";
+	print "    <TD>" . $images[$imageid]["prettyname"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Owner:</TH>\n";
+	print "    <TD>" . $images[$imageid]["owner"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Platform:</TH>\n";
+	print "    <TD>" . $platforms[$images[$imageid]["platformid"]] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>OS:</TH>\n";
+	print "    <TD>" . $oslist[$images[$imageid]["osid"]]["prettyname"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum RAM (MB):</TH>\n";
+	print "    <TD>" . $images[$imageid]["minram"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum Num of Processors:</TH>\n";
+	print "    <TD>" . $images[$imageid]["minprocnumber"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum Processor Speed (MHz):</TH>\n";
+	print "    <TD>" . $images[$imageid]["minprocspeed"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum Network Speed (Mbps):</TH>\n";
+	print "    <TD>" . $images[$imageid]["minnetwork"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Estimated Reload Time (min):</TH>\n";
+	print "    <TD>" . $images[$imageid]["reloadtime"] . "</TD>\n";
+	print "  </TR>\n";
+	print "</TABLE>\n";
+	print "<TABLE>\n";
+	print "  <TR valign=top>\n";
+	print "    <TD>\n";
+	$cdata = array('deleted' => $deleted,
+	               'imageid' => $imageid);
+	$cont = addContinuationsEntry('submitDeleteImage', $cdata, SECINDAY, 0, 0);
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <INPUT type=submit value=Submit>\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "    <TD>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cont = addContinuationsEntry('viewImages');
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <INPUT type=submit value=Cancel>\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "</TABLE>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitDeleteImage()
+///
+/// \brief deletes an image from the database and notifies the user
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitDeleteImage() {
+	$imageid = getContinuationVar("imageid");
+	$deleted = getContinuationVar("deleted");
+	if($deleted) {
+		$query = "UPDATE image "
+				 . "SET deleted = 0 "
+				 . "WHERE id = $imageid";
+		$qh = doQuery($query, 210);
+	}
+	else {
+		$query = "UPDATE image "
+				 . "SET deleted = 1 "
+				 . "WHERE id = $imageid";
+		$qh = doQuery($query, 211);
+		$query = "UPDATE computer "
+				 . "SET nextimageid = 0 "
+				 . "WHERE nextimageid = $imageid";
+		doQuery($query, 212);
+	}
+	viewImages();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn viewImageDetails
+///
+/// \brief prints a page with all information about an image
+///
+////////////////////////////////////////////////////////////////////////////////
+function viewImageDetails() {
+	$imageid = getContinuationVar("imageid");
+	$images = getImages(1);
+	$platforms = getPlatforms();
+	$oslist = getOSList();
+	print "<DIV align=center>\n";
+	print "<H2>Image Details</H2>\n";
+	print "<TABLE>\n";
+	/*print "  <TR>\n";
+	print "    <TH align=right>Short Name:</TH>\n";
+	print "    <TD>" . $images[$imageid]["name"] . "</TD>\n";
+	print "  </TR>\n";*/
+	print "  <TR>\n";
+	print "    <TH align=right>Long Name:</TH>\n";
+	print "    <TD>" . $images[$imageid]["prettyname"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Owner:</TH>\n";
+	print "    <TD>" . $images[$imageid]["owner"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Platform:</TH>\n";
+	print "    <TD>" . $platforms[$images[$imageid]["platformid"]] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>OS:</TH>\n";
+	print "    <TD>" . $oslist[$images[$imageid]["osid"]]["prettyname"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum RAM (MB):</TH>\n";
+	print "    <TD>" . $images[$imageid]["minram"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Minimum Num of Processors:</TH>\n";
+	print "    <TD>" . $images[$imageid]["minprocnumber"] . "</TD>\n";
+	print "  </TR>\n";

[... 1373 lines stripped ...]