#!/usr/bin/perl --
# MonArch - Groundwork Monitor Architect
# monarch.cgi
#
############################################################################
# 
# Release 2.5
# 7-Apr-2008
############################################################################
# 
# Author: Scott Parris
#
# Copyright 2007, 2008 GroundWork Open Source, Inc. (GroundWork)  
# All rights reserved. This program is free software; you can redistribute
# it and/or modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#

use lib qq(/var/www/monarch/lib);
use strict;
use CGI;
use MonarchForms;
use MonarchStorProc;
use MonarchDoc;
use MonarchValidation;
use MonarchInstrument;
use URI::Escape;
$|++;


#
############################################################################
# Global Declarations
#

my $debug = undef;
my $query = new CGI;
my $top_menu = $query->param('top_menu');
my $view = $query->param('view');
my $obj = $query->param('obj');
my $obj_view = $query->param('obj_view');
my $task = $query->param('task');
my $submit = $query->param('submit');
my $user_acct = $query->param('user_acct');
my $password = $query->param('password');
my $session_id = $query->param('CGISESSID'); 
unless ($session_id) { $session_id = $query->cookie("CGISESSID") }
my $ez = $query->param('ez');
my $page_title = 'Monarch';
my (%auth_add, %auth_modify, %auth_delete, %properties, %authentication, %hidden) = ();
my ($nagios_ver, $nagios_bin, $nagios_etc, $monarch_home, $backup_dir, $is_portal, $upload_dir, $monarch_ver, $enable_externals, $enable_groups, $enable_ez, $nagios_share) = 0;
$hidden{'selected'} = $query->param('selected'); 
$hidden{'top_menu'} = $query->param('top_menu');
$hidden{'view'} = $view;
$hidden{'obj'} = $obj;
$hidden{'nocache'} = time;
unless ($top_menu) { $top_menu = 'hosts' }
if ($task && $task ne 'No') { $hidden{'task'} = $task }
my $table = $obj;
if ($obj eq 'commands') { $table = 'commands' }
my @errors = ();
my @messages = ();
my ($body,$javascript) = undef;
my $doc_root = $ENV{'DOCUMENT_ROOT'};
my $userid = undef;
my $refresh_url = undef;
my $refresh_left = undef;
my $tab = 1;

my %property_list = StorProc->property_list();
my %db_values = StorProc->db_values();

my %required = ();
$required{'commands'} = "name,type,command_line";
$required{'contactgroups'} = "name,alias";
$required{'contact_templates'} = "name,host_notification_period,service_notification_period,host_notification_options,service_notification_options";
$required{'contacts'} = "name,alias,template";
$required{'contact_overrides'} = "host_notification_period,service_notification_period,host_notification_options,service_notification_options";
$required{'extended_host_info_templates'} = "name";
$required{'extended_host_info'} = "name,template";
$required{'extended_service_info'} = "name";
$required{'extended_service_info_templates'} = "name";
$required{'host_dependencies'} = "dependent_host,parent_host,notification_failure_criteria";
$required{'hostgroups'} = "name,alias";
$required{'host_templates'} = "name,max_check_attempts,notification_interval,notification_period,notification_options";
$required{'hosts'} = "name,alias,address";
$required{'service_dependency'} = "service_name";
$required{'service_dependency_templates'} = "name,service_name";
$required{'escalation_templates'} = "name,first_notification,last_notification,notification_interval";
$required{'service_templates'} = "name";
$required{'services'} = "name,host_name";
$required{'time_periods'} = "name,alias";

my %obj_id = StorProc->get_obj_id();

my %obj_template = ('contacts' => 'contact_templates','service_templates' => 'service_templates','services' => 'service_templates',
'service_dependency' => 'service_dependency_templates','hosts' => 'host_templates');

my %obj_template_id = ('commands' => 'command_id',
'contact_templates' => 'contacttemplate_id',
'contactgroups' => 'contactgroup_id',
'contacts' => 'contact_id',
'escalation_templates' => 'template_id',
'escalation_trees' => 'tree_id',
'extended_host_info_templates' => 'hostextinfo_id',
'extended_service_info_templates' => 'serviceextinfo_id',
'host_dependencies' => 'host_id',
'host_templates' => 'hosttemplate_id',
'hostgroups' => 'hostgroup_id',
'hosts' => 'hosttemplate_id',
'service_dependency' => 'id',
'service_dependency_templates' => 'id',
'service_templates' => 'parent_id',
'servicegroups' =>  'servicegroup_id',
'services' =>  'servicetemplate_id',
'time_periods' => 'timeperiod_id');

my %textsize = ();
$textsize{'low_flap_threshold'} = 5;
$textsize{'high_flap_threshold'} = 5;
$textsize{'notification_interval'} = 15;
$textsize{'first_notification'} = 5;
$textsize{'last_notification'} = 5;
$textsize{'max_check_attempts'} = 5;
$textsize{'normal_check_interval'} = 15;
$textsize{'retry_check_interval'} = 15;
$textsize{'check_interval'} = 15;
$textsize{'freshness_threshold'} = 15;
$textsize{'notes'} = 75;
$textsize{'notes_url'} = 75;
$textsize{'action_url'} = 75;
$textsize{'email'} = 75;
$textsize{'pager'} = 75;
$textsize{'name'} = 50;
$textsize{'alias'} = 75;
$textsize{'address'} = 16;
$textsize{'description'} = 75;
$textsize{'command_line'} = 75;
$textsize{'icon_image'} = 70;
$textsize{'icon_image_alt'} = 70;
$textsize{'vrml_image'} = 70;
$textsize{'statusmap_image'} = 70;
$textsize{'2d_coords'} = 7;
$textsize{'3d_coords'} = 7;
$textsize{'sunday'} = 75;
$textsize{'monday'} = 75;
$textsize{'tuesday'} = 75;
$textsize{'wednesday'} = 75;
$textsize{'thursday'} = 75;
$textsize{'friday'} = 75;
$textsize{'saturday'} = 75;
$textsize{'small'} = 5;
$textsize{'short_name'} = 20;
$textsize{'long_name'} = 70;
my $empty_data = qq(<?xml version="1.0" ?>
<data>
</data>);

# Some buttons

my %add = ('name' => 'add', 'value' => 'Add');
my %save = ('name' => 'save', 'value' => 'Save');
my %delete = ('name' => 'delete', 'value' => 'Delete');
my %remove = ('name' => 'remove', 'value' => 'Remove');
my %select = ('name' => 'select', 'value' => 'Select');
my %cancel = ('name' => 'cancel', 'value' => 'Cancel');
my %close = ('name' => 'close','value' => 'Close');
my %next = ('name' => 'next', 'value' => 'Next >>');
my %back = ('name' => 'back', 'value' => '<< Back');
my %continue = ('name' => 'continue', 'value' => 'Continue');
my %abort = ('name' => 'abort', 'value' => 'Abort');
my %host_vitals = ('name' => 'obj_view', 'value' => 'Host Vitals');
my %service_list = ('name' => 'obj_view', 'value' => 'Service List');
my %service_detail = ('name' => 'obj_view', 'value' => 'Service Detail');
my %rename = ('name' => 'rename', 'value' => 'Rename');
my %yes = ('name' => 'yes','value' => 'Yes');
my %no = ('name' => 'no','value' => 'No');
my %assign_contactgroups = ('name' => 'assign_contactgroups', 'value' => 'Assign Contact Groups');
my %upload = ('name' => 'upload','value' => 'Upload');
my %sync = ('name' => 'sync','value' => 'Sync With Main');
my %default = ('name' => 'set_defaults','value' => 'Set Defaults');


# for migration from contactgroup_assign to new separate tables
my %table_by_object = (
	'hosts'    			=> 'contactgroup_host',
	'monarch_group'    	=> 'contactgroup_group',
	'services'          => 'contactgroup_service',
	'host_templates'  	=> 'contactgroup_host_template',
	'service_templates' => 'contactgroup_service_template',
	'host_profiles'     => 'contactgroup_host_profile',
	'service_names'   	=> 'contactgroup_service_name',
	'hostgroups'       	=> 'contactgroup_hostgroup',
);


#
############################################################################
#	Sub to present errors
#

sub error_out($) {
	my $err = shift;
	$body .= "<h2>$err</h2><br>";
}

#
############################################################################
#	Sub to parse queries
#

sub parse_query($$) {
	my $data = shift;
	my $object = shift;
	my %data_vals = ();
	my %data_props = ();

	# explain what each of these are:
	# data_vals
	# data_props
	# properties
	# overrides
	# db_values
	# name_vals
	# object
	# checks
	# parent group
	# t
	# s	


	my @contactgroups = ();
	if ($db_values{$data} =~ /,data/) { 
		$data_vals{'data'} = "<?xml version=\"1.0\" ?>\n<data>";
	}
	my %overrides = ();
	foreach my $name ($query->param) {
		if ($name =~ /_override$/) {
			$name =~ s/_override$//;		
			$overrides{$name} = 1;
			$overrides{'template'} = 1;
		}
	}
	my %name_vals = ();
	foreach my $name ($query->param) {
		unless ($overrides{$name} || $name =~ /_override|nocache|servicename_id/) {
			my $val = $query->param($name);
			$val =~ s/^\s+|\s+$//;
			if ($val eq '0') { $val = '-zero-' }
			$name_vals{$name} = $val;
		}
	}
	if ($object eq 'host_templates' || $object eq 'host_overrides') {
		my @checks =();
		if ($nagios_ver =~ /^[23]\.x$/) {
			@checks = ('notifications_enabled','check_freshness','obsess_over_host',
				'passive_checks_enabled','active_checks_enabled','event_handler_enabled','flap_detection_enabled',
				'process_perf_data','retain_status_information','retain_nonstatus_information');
		} else {
			@checks = ('checks_enabled','notifications_enabled','event_handler_enabled','flap_detection_enabled',
				'process_perf_data','retain_status_information','retain_nonstatus_information');
		}
		foreach my $check (@checks) {
			unless ($name_vals{$check}) { $name_vals{$check} = '-zero-'}
		}
	}
	if ($object eq 'service_templates' || $object eq 'service_overrides') {
		my @checks =  ('is_volatile','active_checks_enabled','passive_checks_enabled','parallelize_check',
			'obsess_over_service','check_freshness','event_handler_enabled','flap_detection_enabled',
			'process_perf_data','retain_status_information','retain_nonstatus_information','notifications_enabled');
		foreach my $check (@checks) {
			unless ($name_vals{$check}) { $name_vals{$check} = '-zero-'}
		}
	}
	my @db_vals = split(/,/, $db_values{$data});
	my @props = split(/,/, $property_list{$object});
	my $use_template_command = $query->param('use_template_command');
	foreach my $name (keys %name_vals) {
		if ($name =~ /check_command|^event_handler$/) {
			my %c = StorProc->fetch_one('commands','name',$name_vals{$name});
			$data_vals{$name} = $c{'command_id'};
			$properties{$name} = $name_vals{$name};
			$data_props{$name} = $data_vals{$name};
		} elsif ($name eq 'command_line') {
			unless ($use_template_command || $object eq 'service_overrides') {
				my $command_line = $name_vals{$name};
				$data_vals{'data'} .= "\n  <prop name=\"command_line\"><![CDATA[$command_line]]>\n  </prop>";
				delete $data_vals{$name};
				$properties{$name} = $name_vals{$name};
				$data_props{$name} = $name_vals{$name};
			}
		} elsif ($name =~ /service_description|service_name/) {
			$properties{$name} = $name_vals{$name};
			my %s = StorProc->fetch_one('service_names','name',$properties{$name});		
			$data_vals{'servicename_id'} = $s{'servicename_id'};
		} elsif ($name eq 'host_profile') {
			my %p = StorProc->fetch_one('profiles_host','name',$name_vals{$name});
			$data_vals{'hostprofile_id'} = $p{'hostprofile_id'};
			$properties{$name} = $name_vals{$name};
		} elsif ($name eq 'dependent_host') {
			my %h = StorProc->fetch_one('hosts','name',$name_vals{$name});
			$data_vals{'host_id'} = $h{'host_id'};
			$properties{$name} = $name_vals{$name};
		} elsif ($name eq 'parent_host') {
			my %h = StorProc->fetch_one('hosts','name',$name_vals{$name});
			$data_vals{'parent_id'} = $h{'host_id'};
			$properties{$name} = $name_vals{$name};
		} elsif ($name =~ /members|contact|contactgroup|parents/) {
			my @members = $query->param($name);
			delete $properties{$name};
			if ($name eq 'contactgroup' && $obj eq 'service_templates') { @contactgroups = sort @members }
			foreach  (@members) { $properties{$name} .= "$_," }
			chop $properties{$name};
			$data_vals{$name} = $properties{$name};
			$data_props{$name} = $properties{$name};
		} elsif ($name =~ /notification_options$|^stalking_options$|^notification_failure_criteria$|^execution_failure_criteria$|^escalation_options$/) {
			my @members = $query->param($name);
			delete $properties{$name};
			foreach  (@members) { $properties{$name} .= "$_," }
			chop $properties{$name};
		} elsif ($name =~ /notification_commands/) {
			my @members = $query->param($name);
			delete $properties{$name};
			foreach my $m (@members) { 
				if ($m) {
					$properties{$name} .= "$m,";
					my %c = StorProc->fetch_one('commands','name',$m);
					$data_vals{$name} .= "$c{'command_id'},";
				}
			}
			chop $data_vals{$name};
			chop $properties{$name};
		} elsif ($name eq 'last_notification') {
			my $last_notification = $query->param('last_notification');
			if ($last_notification eq '0') { 
				$properties{'last_notification'} = '-zero-';
			} else {
				$properties{'last_notification'} = $last_notification;
			}
		} elsif ($name =~ /period/) {
			my %t = StorProc->fetch_one('time_periods','name',$name_vals{$name});
			$data_vals{$name} = $t{'timeperiod_id'};
			$data_props{$name} = $data_vals{$name};
			$properties{$name} = $name_vals{$name};
		} elsif ($name =~ /escalation/) {
			my %t = StorProc->fetch_one('escalation_trees','name',$name_vals{$name});
			$data_vals{$name} = $t{'tree_id'};
			$properties{$name} = $name_vals{$name};
		} elsif ($name =~ /template/) {
			my $value = $name_vals{$name};
			my %t = StorProc->fetch_one($obj_template{$object},'name',$value);
			$data_vals{$obj_template_id{$obj_template{$object}}} = $t{$obj_template_id{$obj_template{$object}}};
			delete $data_vals{'template'};
			if ($obj eq 'service_templates') {
				$data_props{'parent_id'} = $t{'servicetemplate_id'};
				$data_vals{'parent_id'} = $t{'servicetemplate_id'};
			}
			delete $data_vals{'template'};
			delete $data_props{'template'};
			if (!$properties{'template'}) {$properties{'template'} = $name_vals{$name}}
		} else {
			$properties{$name} = $name_vals{$name};
			$data_props{$name} = $properties{$name};
		}
		foreach my $p (@props) {
			if ($overrides{$p}) { next }
			if ($name eq 'escalation_options') {
				$data_vals{'data'} .= "\n  <prop name=\"$name\"><![CDATA[$properties{$p}]]>\n  </prop>";  
				$data_props{$name} = $properties{$p};
			}
			unless ($name =~ /^template_id|^event_handler$|command|service_description|members|contact|contactgroup|parents|escalation|period/) {
				if ($p eq $name) { 
					my $match = undef;
					foreach my $val (@db_vals) {
						unless ($val =~ /template/) {
							if ($val eq $name) { 
								$data_vals{$val} = $name_vals{$name}; # what is this for?
								$match = 1;
								last;
							}
						}
					}
					if (!$match && $data_vals{'data'}) {
						if ($properties{$p}) {
							$data_vals{'data'} .= "\n  <prop name=\"$name\"><![CDATA[$properties{$p}]]>\n  </prop>";  
							$data_props{$name} = $properties{$p};
						}
					}
				}
			}
		}
	}

	if ($obj eq 'service_templates') {
		if ($data_props{'parent_id'}) {
			%data_vals = ();
			$data_vals{'parent_id'} = $data_props{'parent_id'};
			$data_vals{'data'} = "<?xml version=\"1.0\" ?>\n<data>";
			my %parent = StorProc->get_template_properties($data_props{'parent_id'});


			foreach my $name (keys %data_props) {
				# 
				if ($parent{$name} eq $data_props{$name}) { delete $data_props{$name} }
			}
			delete $data_props{'template'};
			foreach my $name (keys %data_props) {
				my $got_it = 0;
				foreach my $p (@props) { 
					if ($name eq $p) { $got_it = 1 }
				}
				unless ($got_it) { delete $data_props{$name} }
			}
			foreach my $name (keys %data_props) {
				if ($name =~ /^event_handler$|parent_id|check_command|contactgroup|parent|period|name/) {
					$data_vals{$name} = $data_props{$name}; # what is going on here?
				} else {
					$data_vals{'data'} .= "\n  <prop name=\"$name\"><![CDATA[$data_props{$name}]]>\n  </prop>";  					
				}
			}
			foreach my $cg (@contactgroups) {
				my $got_group = 0;
				foreach my $pg (@{$parent{'contactgroup'}}) {
					if ($pg eq $cg) { $got_group = 1 }
				}
			}
		}	
	}
	$properties{'save'} = 1;
	if ($data_vals{'data'}) { $data_vals{'data'} .= "\n </data>" }
	return %data_vals;
}

#
############################################################################
# Check Fields - uniqueness/missing info
#

sub check_fields() {
	my @req = split(/,/, $required{$table});
	my $missing = undef;
	foreach my $r (@req) {
		if ($obj eq 'hostgroups' && $nagios_ver =~ /^[23]\.x$/ && $r eq 'contactgroup') { next }
		unless ($properties{$r}) {
			$required{$r} = 1;
			$required{'missing'} = 1;
			$missing .= "$r,";
		}
	}
	chop $missing;
	$missing .= ".";

	if ($required{'missing'}) {
		push @errors, "Missing required fields: $missing";
	} elsif ($query->param('add') || $submit eq 'Add') {
		unless ($obj =~ /host_dependencies/) {
			my %res = StorProc->fetch_one($table,'name',$properties{'name'}); 
			if ($res{'name'}) {
				my $type = $obj;
				$type =~ s/_/ /g;
				$type =~ s/s$//g;
				push @errors, "\u$type $properties{'name'} already exists.";
			} 
		}
	} 
	if (@errors) {
		return 1;
	} else {
		return 0;
	}
}

#
############################################################################
# Sub eval errors
#

sub eval_errors($) {
	my @eval = shift;
	my @errors = ();
	foreach my $err (@eval) {
		unless ($err =~ /duplicate|1/i) { 
			push @errors, $err;
		}
	}
	return @errors;
}

#
############################################################################
# Sub to build most forms
#

sub build_form($) {
	my $validation_mini_profile = $_[1] || {};
	my $form = undef;
	my $extended_props = undef;
	my $name = $query->param('name');
	my $source = $query->param('source');
	my $ext_props = $query->param('ext_props');

	$hidden{'source'} = $source;
	my $dfv_profile = Validation->dfv_profile_javascript($validation_mini_profile);


############################################################################
# Get Properties
#

	unless($properties{'save'}) { 
		if ($task eq 'new') {
			my @p_list = split(/,/, $property_list{$obj});
			foreach my $p (@p_list) { $properties{$p} = '' }			
		} elsif ($task =~ /copy|use/) { 
			$name = $source;
			%properties = StorProc->fetch_one($table,'name',$name); 
			if ($task eq 'use') { $properties{'template'} = $source }
			$properties{'name'} = undef;
		} else {
			%properties = StorProc->fetch_one($table,'name',$name); 
		}
	}

	if ($obj eq 'contacts' && $task eq 'new') { 
		$table = 'contact_templates'; 
		$task = 'use';
	}
	my @props = split(/,/, $property_list{$obj});

	if ($task eq 'modify') { $source = $name}

############################################################################
# Top of form
#
	my $title = undef;
	my @t_parse = split(/_/, $obj);
	foreach (@t_parse) { $_ =~ s/ies/y/g; $title .= "\u$_ "; }
	$title =~ s/s\s$//;
	$title =~ s/Wizard/Extended/;
	my $form_top = undef;
	if ($title =~ /Escalation/) { $title =~ s/Template// }
	unless ($obj eq 'service_templates') {
		$form_top = Forms->form_top("$title Properties", Validation->dfv_onsubmit_javascript());
		if ($task eq 'modify'){
			$form .= Forms->display_hidden('Name:','name',$properties{'name'});
		} elsif ($obj eq 'host_dependencies') {
			my @hosts = StorProc->fetch_list('hosts','name');
			$form .= Forms->list_box('Dependent host name:','name',\@hosts,$properties{'name'},$required{'name'});
		} else {
			$form .= Forms->text_box('Name:','name',$properties{'name'},$textsize{'name'},$required{'name'});
		}
	}
	my %props = ();
	foreach my $property (@props) { $props{$property} = $property }
	if ($obj eq 'service_templates') {
		delete $props{'check_command'};
		delete $props{'command_line'};
	}
	if ($obj eq 'host_templates') {
		if ($nagios_ver eq '1.x') {
			delete $props{'active_checks_enabled'};
			delete $props{'passive_checks_enabled'};
			delete $props{'obsess_over_host'};
			delete $props{'check_period'};
			delete $props{'check_freshness'};
			delete $props{'check_interval'};
			delete $props{'freshness_threshold'};
			delete $props{'contactgroup'};
		} else {
			delete $props{'checks_enabled'};
		}
	}
	if ($obj =~ /escalation/ && $nagios_ver eq '1.x') {
		delete $props{'escalation_period'};
		delete $props{'escalation_options'};
	}
	if ($obj eq 'hostgroups') {
		my $validation_mini_profile = { name => { constraint => '[^/\\\\`~\+!\$\%\^\&\*\|\'\"<>\?,\)\(\'=\[\]\{\}\:\#;]+' } };
		$dfv_profile = Validation->dfv_profile_javascript($validation_mini_profile);
	}

############################################################################
# Body of form
#

	my %docs = Doc->properties_doc($obj,\@props);
	foreach my $property (@props) {
		$properties{$property} =~ s/-zero-/0/g;
		my $p_title = "\u$property:";
		$p_title =~ s/_/ /g;
		if ($props{$property} =~ /^is_volatile|^checks_enabled$|^notifications_enabled$|^parallelize_check$|^obsess_over_host|^obsess_over_service$|^check_freshness$|^passive_checks_enabled$|^active_checks_enabled$|^event_handler_enabled$|^flap_detection_enabled$|^process_perf_data$|^retain_status_information$|^retain_nonstatus_information$/) {
			$form .= Forms->checkbox($p_title,$property,$properties{$property},$docs{$property},'',$tab++);
		
		} elsif ($props{$property} eq 'contactgroup') {
			my @members = ();
			if ($properties{'save'}) {
				@members = split(/,/, $properties{'contactgroup'});
			} else { 
				@members = StorProc->get_contactgroups($obj,$properties{$obj_id{$obj}}); 
			}
			my @nonmembers = StorProc->fetch_list('contactgroups','name'); 
			if ($obj =~ /escalation|host_templates|service_templates/) {
				my $validation_mini_profile = {
						contactgroup => { constraint => '[- A-Za-z_0-9]+', message => 'Value must be alphanumeric.' },
				};
				$dfv_profile = Validation->dfv_profile_javascript($validation_mini_profile);		
				$form .= Forms->members('Contact Groups:','contactgroup',\@members,\@nonmembers,$required{$property},'10',$docs{$property},'',$tab++);
				$tab += 3;
				$form_top = Forms->form_top("$title Properties", Validation->dfv_onsubmit_javascript('selIt()'));
			} else {
				$form .= Forms->list_box_multiple('Contact Groups:','contactgroup',\@nonmembers,\@members,$required{'contactgroup'},$docs{$property},'',$tab++);
			}
		
		} elsif ($props{$property} =~ /^icon_image$|^vrml_image$/) {
			if (-e "$nagios_share/images/logos") {
				my @includes = ('gif','png','jpg','jpeg');
				my @files = StorProc->get_dir("$nagios_share/images/logos",\@includes);
				$form .= Forms->list_box($p_title,$property,\@files,$properties{$property},$required{$property},$docs{$property},'',$tab++);
			} else {
				$form .= Forms->text_box($p_title,$property,$properties{$property},$textsize{$property},$required{$property},$docs{$property},'',$tab++);
			}
		} elsif ($props{$property} =~ /^statusmap_image$/) {
			if (-e "$nagios_share/images/logos") {
				my @includes = ('gd2');
				my @files = StorProc->get_dir("$nagios_share/images/logos",\@includes);
				$form .= Forms->list_box($p_title,$property,\@files,$properties{$property},$required{$property},$docs{$property},'',$tab++);
			} else {
				$form .= Forms->text_box($p_title,$property,$properties{$property},$textsize{$property},$required{$property},$docs{$property},'',$tab++);
			}
		} elsif ($props{$property} eq 'members') {
			my @members;
			if ($properties{'save'}) {
				@members = split(/,/, $properties{'members'});
			} elsif ($task =~ /copy|modify/) { 
				@members = StorProc->get_names_in('host_id','hosts','hostgroup_host','hostgroup_id',$properties{'hostgroup_id'});
			}
			my @nonmembers = StorProc->fetch_list('hosts','name'); 
			$form .= Forms->members($p_title,$property,\@members,\@nonmembers,$required{$property},'',$docs{$property},'',$tab++);
			$form_top = Forms->form_top("$title Properties", Validation->dfv_onsubmit_javascript('selIt()'));
			$tab += 3;
		} elsif ($props{$property} eq 'contact') {
			my @members = ();
			if ($properties{'save'}) {
				@members = split(/,/, $properties{'contact'});
			} elsif ($task =~ /copy|modify/) { 
				@members = StorProc->get_names_in('contact_id','contacts','contactgroup_contact','contactgroup_id',$properties{$obj_id{$obj}});
			}
			my @nonmembers = StorProc->fetch_list('contacts','name'); 
			$form .= Forms->members('Contacts:','contact',\@members,\@nonmembers,$required{$property},'',$docs{$property},'',$tab++);
			$form_top = Forms->form_top("$title Properties",'onsubmit="selIt();"');
		
		} elsif ($props{$property} eq 'stalking_options') {
			my @opts = split(/,/, $properties{$property});
			$form .= Forms->stalking_options(\@opts,$required{$property},$docs{$property},'',$tab++);
			$tab += 3;
		} elsif ($props{$property} =~ /notification_options|escalation_options/) {
			my @opts = split(/,/, $properties{$property});
			$form .= Forms->notification_options($obj,$property,\@opts,$required{$property},$nagios_ver,$docs{$property},'',$tab++);
			$tab += 6;
		} elsif ($props{$property} =~ /host_name$/) {
			my @hosts = StorProc->fetch_list('hosts','name'); 
			$form .= Forms->list_box($p_title,$property,\@hosts,$properties{$property},$required{$property},$docs{$property},'',$tab++);
		
		} elsif ($props{$property} =~ /host_escalation|service_escalation/) {
			my $type = $property;
			$type =~ s/_escalation_id//;
			my %where = ('type' => $type);
			my @list = StorProc->fetch_list_where('escalation_trees','name',\%where ); 
			%where = ('tree_id' => $properties{$property});
			my %t = StorProc->fetch_one_where('escalation_trees',\%where);
			$form .= Forms->list_box($p_title,$property,\@list,$t{'name'},'',$docs{$property},'',$tab++);

		} elsif ($props{$property} =~ /service_name$|service_description/) {
			unless ($task eq 'new' || $properties{'save'}) {
				my %s = StorProc->fetch_one('service_names','servicename_id',$properties{'servicename_id'});
				$properties{$property} = $s{'name'};
			}
			my @services = ();
			if ($obj =~ /escalation/) { push @services, '*'	}
			my @svcs = StorProc->fetch_list('service_names','name'); 
			push (@services, @svcs);
			$form .= Forms->list_box($p_title,$property,\@services,$properties{$property},$required{$property},$docs{$property},'',$tab++);
		
		} elsif ($props{$property} =~ /check_command$|event_handler$/) {
			unless ($task eq 'new' || $properties{'save'}) {
				my %p = StorProc->fetch_one('commands','command_id',$properties{$property});
				$properties{$property} = $p{'name'};
			}
			my @commands = StorProc->fetch_list('commands','name'); 
			$form .= Forms->list_box($p_title,$property,\@commands,$properties{$property},$required{$property},$docs{$property},'',$tab++);
		
		} elsif ($props{$property} eq 'type') {
			unless ($obj =~ /escalation/) {
				my @types = ('check','notify','other'); 
				$form .= Forms->list_box($p_title,$property,\@types,$properties{$property},$required{$property},$docs{$property},'',$tab++);
			
			}
		} elsif ($props{$property} =~ /notification_commands/) {
			my %w = ('type' => 'notify');
			my @commands = StorProc->fetch_list_where('commands','name',\%w); 
			my @selected = split(/,/, $properties{$property}); 
			unless ($task eq 'new' || $properties{'save'}) {
				if ($property =~ /(\S+)_notification_commands/) {
					my %w = ('type' => $1,'contacttemplate_id' => $properties{'contacttemplate_id'});
					@selected = StorProc->fetch_list_where('contact_command','command_id',\%w);
					my @sel;
					foreach (@selected) {
						my %p = StorProc->fetch_one('commands','command_id',$_);
						push @sel, $p{'name'};
					}
					@selected = @sel;
				}
			}
			$form .= Forms->list_box_multiple($p_title,$property,\@commands,\@selected,$required{$property},$docs{$property},'',$tab++);
		
		} elsif ($props{$property} =~ /notification_period|check_period|escalation_period/) {
			unless ($task eq 'new' || $properties{'save'}) {
				my %p = StorProc->fetch_one('time_periods','timeperiod_id',$properties{$property});
				$properties{$property} = $p{'name'};
			}
			my @periods = StorProc->fetch_list('time_periods','name'); 
			$form .= Forms->list_box($p_title,$property,\@periods,$properties{$property},$required{$property},$docs{$property},'',$tab++);
		
		} elsif ($props{$property} =~ /notification_failure_criteria|execution_failure_criteria/) {
			my @opts = split(/,/, $properties{$property});
			$form .= Forms->failure_criteria($property,\@opts,'',$required{$property},$docs{$property},'',$tab++);
		
		} elsif ($props{$property} eq 'template' && $obj eq 'service_templates') {
			my @templates = StorProc->get_possible_parents($properties{'servicetemplate_id'}); 
			my %t = StorProc->fetch_one('service_templates','servicetemplate_id',$properties{'parent_id'});
			$properties{$property} = $t{'name'};
			$form .= Forms->list_box_submit('Use:',$property,\@templates,'',$required{$property},$docs{$property},'',$tab++);
		
		} elsif ($props{$property} eq 'template') {
			if ($obj eq 'contacts') { $table = 'contact_templates' }
			unless ($obj eq 'service_templates' || $task eq 'new' || $properties{'save'}) {
				my %t = StorProc->fetch_one($obj_template{$obj},$obj_id{$obj_template{$obj}},$properties{$obj_id{$obj_template{$obj}}});
				$properties{$property} = $t{'name'};
			}
			my @templates = StorProc->fetch_list($table,'name'); 
			$form .= Forms->list_box('Use:',$property,\@templates,$properties{'template'},$required{$property},$docs{$property},'',$tab++);
		
		} elsif ($props{$property} =~ /^command_line/) {
			$form .= Forms->text_area($p_title,$property,$properties{$property},'',$textsize{$property},$required{$property},$docs{$property},'',$tab++);
		
		} elsif ($props{$property}) {
			unless ($property eq 'name') {
				if ($properties{'last_notification'} eq '-zero-') { $properties{'last_notification'} = 0 }
				$form .= Forms->text_box($p_title,$property,$properties{$property},$textsize{$property},$required{$property},$docs{$property},'',$tab++);
			
			}
		}
	}
	if ($obj eq 'service_templates') {
		$form .= $dfv_profile;
		$form .= &$Instrument::show_trace_as_html_comment();
		return $form;
	} else {
		$form .= Forms->hidden(\%hidden);
		my $auth = $obj;
		if ($auth =~ /escalation_templates/) { 
			$auth = 'escalations';

			my $validation_mini_profile = {
					notification_interval => { constraint => '[0-9]+', message => 'Value must be numeric.' },
					first_notification    => { constraint => '[0-9]+', message => 'Value must be numeric.' },
					last_notification     => { constraint => '[0-9]+', message => 'Value must be numeric.' },
			};
			$dfv_profile = Validation->dfv_profile_javascript($validation_mini_profile);		


		}
		if ($task eq 'modify' && $auth_delete{$auth}) {
			$form .= Forms->form_bottom_buttons(\%save,\%delete,\%rename,\%cancel,$tab++);
		} elsif ($task eq 'modify') {
			$form .= Forms->form_bottom_buttons(\%save,\%rename,\%cancel,$tab++);
		} else {
			$form .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);			
		}
		my $errstr = undef;
		if (@errors) { $errstr = Forms->form_errors(\@errors)."\n" }
		$dfv_profile .= &$Instrument::show_trace_as_html_comment();		
		return $dfv_profile.$form_top."\n".$errstr.$form;
	}
}

sub build_host_template($) {
	my $name = shift;
	my $form = undef;
	my $select_all = undef;
	$hidden{'host_id'} = $query->param('host_id');
	my $host_template = $query->param('template');
	my $check_command = undef;
	my $command_line = undef;
	my $event_handler = undef;
	my $notification_period = undef;
	my %host = ();
	my %overrides_saved = ();
	my @override_contactgroup = ();
	my $hosttemplate_id = undef;
	if ($obj eq 'hosts') {
		%host = StorProc->fetch_one('hosts','name',$name);
		%overrides_saved = StorProc->fetch_one('host_overrides','host_id',$host{'host_id'});

#		my %where = ('type' => 'hosts','object' => $host{'host_id'});
#		@override_contactgroup = StorProc->fetch_list_where('contactgroup_assign','contactgroup_id',\%where);
		my %where = ('host_id' => $host{'host_id'});
		@override_contactgroup = StorProc->fetch_list_where('contactgroup_host','contactgroup_id',\%where);

		$hosttemplate_id = $host{'hosttemplate_id'};
	} else {
		%host = StorProc->fetch_one('profiles_host','name',$name);
		%overrides_saved = StorProc->fetch_one('hostprofile_overrides','hostprofile_id',$host{'hostprofile_id'});

#		my %where = ('type' => 'host_profiles','object' => $host{'hostprofile_id'});
#		@override_contactgroup = StorProc->fetch_list_where('contactgroup_assign','contactgroup_id',\%where);
		my %where = ('hostprofile_id' => $host{'hostprofile_id'});
		@override_contactgroup = StorProc->fetch_list_where('contactgroup_host_profile','contactgroup_id',\%where);

		$hosttemplate_id = $host{'host_template_id'};
	}
	my %override = ();
	my %template = ();
	if ($host_template) {
		%template = StorProc->fetch_one('host_templates','name',$host_template);
		$hosttemplate_id = $template{'hosttemplate_id'};
	} else {
		%template = StorProc->fetch_one('host_templates','hosttemplate_id',$hosttemplate_id);
		$host_template = $template{'name'};
	}
	if ($overrides_saved{'notification_period'}) {
		my %np =  StorProc->fetch_one('time_periods','timeperiod_id',$overrides_saved{'notification_period'});
		$notification_period = $np{'name'};
	} else {
		my %np =  StorProc->fetch_one('time_periods','timeperiod_id',$template{'notification_period'});
		$notification_period = $np{'name'};
	}
	if ($overrides_saved{'check_command'}) {
		my %check =  StorProc->fetch_one('commands','command_id',$overrides_saved{'check_command'});
		$check_command = $check{'name'};
	} else {
		my %check =  StorProc->fetch_one('commands','command_id',$template{'check_command'});
		$check_command = $check{'name'};
	}
	if ($overrides_saved{'event_handler'}) {
		my %event =  StorProc->fetch_one('commands','command_id',$overrides_saved{'event_handler'});
		$event_handler = $event{'name'};
	} else {
		my %event =  StorProc->fetch_one('commands','command_id',$template{'event_handler'});
		$event_handler = $event{'name'};
	}

	my @contactgroups = ();
	my @override_contactgroups = ();

	unless ($nagios_ver eq '1.x') {
		my %cp =  StorProc->fetch_one('time_periods','timeperiod_id',$template{'check_period'});
		$template{'check_period'} = $cp{'name'};

#		my %where = ('type' => 'host_templates','object' => $template{'hosttemplate_id'});
#		my @temp_contactgroups = StorProc->fetch_list_where('contactgroup_assign','contactgroup_id',\%where);
		my %where = ('hosttemplate_id' => $template{'hosttemplate_id'});
		my @temp_contactgroups = StorProc->fetch_list_where('contactgroup_host_template','contactgroup_id',\%where);

		foreach (@temp_contactgroups) {
			my %c = StorProc->fetch_one('contactgroups','contactgroup_id',$_);
			push @contactgroups, $c{'name'};
		}
		$override{'contactgroups'} = 'checked';
		if ($obj eq 'hosts') {
#			%where = ('type' => 'hosts','object' => $host{'host_id'});
			%where = ('host_id' => $host{'host_id'});
			@override_contactgroups = StorProc->fetch_list_where('contactgroup_host','contactgroup_id',\%where);
		} else {
#			%where = ('type' => 'host_profiles','object' => $host{'hostprofile_id'});
			%where = ('hostprofile_id' => $host{'hostprofile_id'});
			@override_contactgroups = StorProc->fetch_list_where('contactgroup_host_profile','contactgroup_id',\%where);
		}
#		@override_contactgroups = StorProc->fetch_list_where('contactgroup_assign','contactgroup_id',\%where);
	}

	my @props = split(/,/, $property_list{'host_templates'});
	foreach (@props) { 
		$override{$_} = 'checked';
	} 

	if ($query->param('select_all')) {
		$select_all = 1;
	} else {
		foreach (@props) { 
			if ($overrides_saved{$_}) {
				$override{$_} = 'unchecked';
				if ($_ eq 'notification_period') {
					my %np =  StorProc->fetch_one('time_periods','timeperiod_id',$overrides_saved{'notification_period'});
					$template{$_} = $np{'name'};
				} elsif ($_ eq 'check_period') {
					my %check =  StorProc->fetch_one('time_periods','timeperiod_id',$overrides_saved{'check_period'});
					$template{$_} = $check{'name'};
				} elsif ($_ eq 'check_command') {
					my %check =  StorProc->fetch_one('commands','command_id',$overrides_saved{'check_command'});
					$template{$_} = $check{'name'};
				} elsif ($_ eq 'event_handler') {
					my %event =  StorProc->fetch_one('commands','command_id',$overrides_saved{'event_handler'});
					$template{$_} = $event{'name'};
				} else {
					$template{$_} = $overrides_saved{$_};
				}
			}
		} 
		unless ($nagios_ver eq '1.x') {
			$override{'contactgroups'} = 'checked';
			if (@override_contactgroups) {
				@contactgroups = ();
				foreach (@override_contactgroups) {
					my %c = StorProc->fetch_one('contactgroups','contactgroup_id',$_);
					push @contactgroups, $c{'name'};
				}
				$override{'contactgroups'} = 'unchecked';
			}
		}
	}
	my @timeperiods = StorProc->fetch_list('time_periods','name'); 
	my @members = StorProc->fetch_list('host_templates','name'); 
	my %docs = Doc->manage_hosts_vitals();

	$form .= Forms->list_box_submit('Host template:','template',\@members,$host_template,$required{'template'},$docs{'host_template'},$tab++);
	%docs = Doc->properties_doc('host_templates',\@props);

#	$form .= Forms->checkbox_override('Inherit all values from template','select_all',$select_all,$docs{'override'},$tab++);
	$form .= Forms->inheritance('Inherit from template',$docs{'override'},\%template);

# process_perf_data
	$form .= Forms->checkbox('Process performance data:','process_perf_data',$template{'process_perf_data'},$docs{'process_perf_data'},$override{'process_perf_data'},$tab++);

# retain_status_information
	$form .= Forms->checkbox('Retain status information:','retain_status_information',$template{'retain_status_information'},$docs{'retain_status_information'},$override{'retain_status_information'},$tab++);
# flap_detection_enabled
	$form .= Forms->checkbox('Flap detection enabled:','flap_detection_enabled',$template{'flap_detection_enabled'},$docs{'flap_detection_enabled'},$override{'flap_detection_enabled'},$tab++);
# low_flap_threshold
	$template{'low_flap_threshold'} =~ s/-zero-/0/;
	$form .= Forms->text_box('Low flap threshold:','low_flap_threshold',$template{'low_flap_threshold'},$textsize{'low_flap_threshold'},$required{'low_flap_threshold'},$docs{'low_flap_threshold'},$override{'low_flap_threshold'},$tab++);

# high_flap_threshold
	$template{'high_flap_threshold'} =~ s/-zero-/0/;
	$form .= Forms->text_box('High flap threshold:','high_flap_threshold',$template{'high_flap_threshold'},$textsize{'high_flap_threshold'},$required{'high_flap_threshold'},$docs{'high_flap_threshold'},$override{'high_flap_threshold'},$tab++);

# retain_nonstatus_information
	$form .= Forms->checkbox('Retain nonstatus information:','retain_nonstatus_information',$template{'retain_nonstatus_information'},$docs{'retain_nonstatus_information'},$override{'retain_nonstatus_information'},$tab++);
	if ($nagios_ver eq '1.x') {
# checks_enabled
		$form .= Forms->checkbox('Checks enabled:','checks_enabled',$template{'checks_enabled'},$docs{'checks_enabled'},$override{'checks_enabled'},$tab++);
	} else {
# active_checks_enabled
		$form .= Forms->checkbox('Active checks enabled:','active_checks_enabled',$template{'active_checks_enabled'},$docs{'active_checks_enabled'},$override{'active_checks_enabled'},$tab++);
		$form .= Forms->checkbox('Passive checks enabled:','passive_checks_enabled',$template{'passive_checks_enabled'},$docs{'passive_checks_enabled'},$override{'passive_checks_enabled'},$tab++);
# obsess_over_host
		$form .= Forms->checkbox('Obsess over host:','obsess_over_host',$template{'obsess_over_host'},$docs{'obsess_over_host'},$override{'obsess_over_host'},$tab++);
# check_freshness
		$form .= Forms->checkbox('Check freshness:','check_freshness',$template{'check_freshness'},$docs{'check_freshness'},$override{'check_freshness'},$tab++);
# freshness_threshold
		$template{'freshness_threshold'} =~ s/-zero-/0/;
		$form .= Forms->text_box('Freshness threshold:','freshness_threshold',$template{'freshness_threshold'},$textsize{'freshness_threshold'},$required{'freshness_threshold'},$docs{'freshness_threshold'},$override{'high_flap_threshold'},$tab++);
	}
# check_command
# command_line
	my @commands = StorProc->fetch_list('commands','name'); 
	$form .= Forms->list_box('Check command:','check_command',\@commands,$check_command,'',$docs{'check_command'},$override{'check_command'},$tab++);
	#$form .= Forms->text_area('Command line:','command_line',$template{'command_line'},'',$textsize{'command_line'},'',$docs{'command_line'},$override{'command_line'});

	
# max_check_attempts
	$form .= Forms->text_box('Max check attempts:','max_check_attempts',$template{'max_check_attempts'},$textsize{'max_check_attempts'},$required{'max_check_attempts'},$docs{'max_check_attempts'},$override{'max_check_attempts'},$tab++);

	if ($nagios_ver =~ /^[23]\.x$/) {
# check_interval
		$template{'check_interval'} =~ s/-zero-/0/;
		$form .= Forms->text_box('Check interval:','check_interval',$template{'check_interval'},$textsize{'check_interval'},$required{'check_interval'},$docs{'check_interval'},$override{'check_interval'},$tab++);
	}

# event_handler_enabled
	$form .= Forms->checkbox('Event handler enabled:','event_handler_enabled',$template{'event_handler_enabled'},$docs{'event_handler_enabled'},$override{'event_handler_enabled'},$tab++);

# event_handler
	$form .= Forms->list_box('Event handler:','event_handler',\@commands,$event_handler,'',$docs{'event_handler'},$override{'event_handler'},$tab++);

# notifications_enabled
	$form .= Forms->checkbox('Notifications enabled:','notifications_enabled',$template{'notifications_enabled'},$docs{'notifications_enabled'},$override{'notifications_enabled'},$tab++);
# notification_interval
	$template{'notification_interval'} =~ s/-zero-/0/;
	$form .= Forms->text_box('Notification interval:','notification_interval',$template{'notification_interval'},$textsize{'notification_interval'},$required{'notification_interval'},$docs{'notification_interval'},$override{'notification_interval'},$tab++);

# notification_period
	$form .= Forms->list_box('Notification period:','notification_period',\@timeperiods,$notification_period,'',$docs{'notification_period'},$override{'notification_period'},$tab++);

# notification_options
	my @opts = split(/,/, $template{'notification_options'});
	$form .= Forms->notification_options('host_templates','notification_options',\@opts,$required{'notification_options'},$nagios_ver,$docs{'notification_options'},$override{'notification_options'},$tab++);

# stalking_options
	my @opts = split(/,/, $template{'stalking_options'});
	$form .= Forms->stalking_options(\@opts,$required{'stalking_options'},$docs{'stalking_options'},$override{'stalking_options'},$tab++);

	unless ($nagios_ver eq '1.x') {
# contactgroups
		my @nonmembers = StorProc->fetch_list('contactgroups','name'); 
		$form .= Forms->members('Contact groups:','contactgroup',\@contactgroups,\@nonmembers,'','10',$docs{'contactgroup'},$override{'contactgroups'},$tab++);
	}
	return $form;
}

sub build_service_detail($) {
	my $service_id = shift;
	my $form = undef;
	my $select_all = undef;
	my $service_template = $query->param('template');
	my %service = ();
	my %overrides_saved = ();
	my @override_contactgroup = ();
	my $servicetemplate_id = undef;
	if ($obj eq 'hosts') {
		unless ($service_id) { $service_id = $query->param('service_id') }
		%service = StorProc->fetch_one('services','service_id',$service_id);
		%overrides_saved = StorProc->fetch_one('service_overrides','service_id',$service_id);
		$servicetemplate_id = $service{'servicetemplate_id'};

#		my %where = ('type' => 'services','object' => $service{'service_id'});
#		@override_contactgroup = StorProc->fetch_list_where('contactgroup_assign','contactgroup_id',\%where);
		my %where = ('service_id' => $service{'service_id'});
		@override_contactgroup = StorProc->fetch_list_where('contactgroup_service','contactgroup_id',\%where);

	} elsif ($obj eq 'services') {
		unless ($service_id) { $service_id = $query->param('servicename_id') }
		%service = StorProc->fetch_one('service_names','servicename_id',$service_id);
		%overrides_saved = StorProc->fetch_one('servicename_overrides','servicename_id',$service_id);
		$servicetemplate_id = $service{'template'};

#		my %where = ('type' => 'service_names','object' => $service{'servicename_id'});
#		@override_contactgroup = StorProc->fetch_list_where('contactgroup_assign','contactgroup_id',\%where);
		my %where = ('servicename_id' => $service{'servicename_id'});
		@override_contactgroup = StorProc->fetch_list_where('contactgroup_service_name','contactgroup_id',\%where);

	} elsif ($obj eq 'service_templates') {
		foreach my $prop (keys %properties) {
			if ($prop =~ /parent_id/) {
				$servicetemplate_id = $properties{$prop};
			} else {
				$overrides_saved{$prop} = $properties{$prop};
			}
		}

#		my %where = ('type' => 'service_templates','object' => $properties{'servicetemplate_id'});
#		@override_contactgroup = StorProc->fetch_list_where('contactgroup_assign','contactgroup_id',\%where);
		my %where = ('servicetemplate_id' => $properties{'servicetemplate_id'});
		@override_contactgroup = StorProc->fetch_list_where('contactgroup_service_template','contactgroup_id',\%where);

	}
	my %override = ();
	my %template = ();
	my @contactgroups = ();
	if ($service_template) {
		my %t = StorProc->fetch_one('service_templates','name',$service_template);
		$servicetemplate_id = $t{'servicetemplate_id'}
	} else {
		my %t = StorProc->fetch_one('service_templates','servicetemplate_id',$servicetemplate_id);
		$service_template = $t{'name'};
	}
	my @template_contactgroup = ();
	my $got_parent = 0;
	my $got_contactgroup = 0;
	my $i = 0;
	until ($got_parent || $i == 10) {
		$i++;
		my %tpl = StorProc->fetch_one('service_templates','servicetemplate_id',$servicetemplate_id);
		my @props = split(/,/, $property_list{'service_templates'});
		foreach my $t (@props) { 
			unless ($template{$t}) { 
				if ($t eq 'check_command') {
					my %c =  StorProc->fetch_one('commands','command_id',$tpl{'check_command'});
					$template{$t} = $c{'name'};
				} elsif ($t eq 'notification_period') {
					my %np =  StorProc->fetch_one('time_periods','timeperiod_id',$tpl{'notification_period'});
					$template{$t} = $np{'name'};
				} elsif ($t eq 'check_period') {
					my %cp =  StorProc->fetch_one('time_periods','timeperiod_id',$tpl{'check_period'});
					$template{$t} = $cp{'name'};
				} elsif ($t eq 'event_handler') {
					my %e =  StorProc->fetch_one('commands','command_id',$tpl{'event_handler'});
					$template{$t} = $e{'name'};
				} else { 
					$template{$t} = $tpl{$t};
				}
			}
		}
		unless ($got_contactgroup) {

#			my %where = ('type' => 'service_templates','object' => $tpl{'servicetemplate_id'});
#			@template_contactgroup = StorProc->fetch_list_where('contactgroup_assign','contactgroup_id',\%where);
			my %where = ('servicetemplate_id' => $tpl{'servicetemplate_id'});
			@template_contactgroup = StorProc->fetch_list_where('contactgroup_service_template','contactgroup_id',\%where);

			if (@template_contactgroup) { $got_contactgroup = 1 }
		}
		if ($tpl{'parent_id'}) { 
			$servicetemplate_id = $tpl{'parent_id'};
		} else {
			$got_parent = 1;
		}
	}
	
	my @props = split(/,/, $property_list{'service_templates'});
	foreach (@props) { 
		$override{$_} = 'checked';
		$properties{$_} = $template{$_};
	} 
	foreach (@template_contactgroup) {
		$override{'contactgroups'} = 'checked';
		my %g = StorProc->fetch_one('contactgroups','contactgroup_id',$_);
		push @contactgroups, $g{'name'};
	}
	if ($query->param('select_all')) {
		$select_all = 1;
	} else {
		foreach (@props) { 
			if ($overrides_saved{$_}) {
				$override{$_} = 'unchecked';
				if ($_ eq 'check_command') {
					my %c =  StorProc->fetch_one('commands','command_id',$overrides_saved{'check_command'});
					$properties{$_} = $c{'name'};
				} elsif ($_ eq 'notification_period') {
					my %np =  StorProc->fetch_one('time_periods','timeperiod_id',$overrides_saved{'notification_period'});
					$properties{$_} = $np{'name'};
				} elsif ($_ eq 'check_period') {
					my %cp =  StorProc->fetch_one('time_periods','timeperiod_id',$overrides_saved{'check_period'});
					$properties{$_} = $cp{'name'};
				} elsif ($_ eq 'event_handler') {
					my %e =  StorProc->fetch_one('commands','command_id',$overrides_saved{'event_handler'});
					$properties{$_} = $e{'name'};
				} else {
					$properties{$_} = $overrides_saved{$_};
				}
			}
		} 
		if (@override_contactgroup) {
			@contactgroups = ();
			$override{'contactgroups'} = 'unchecked';
			foreach (@override_contactgroup) {
				my %g = StorProc->fetch_one('contactgroups','contactgroup_id',$_);
				push @contactgroups, $g{'name'};
			}
		}
	}
	my @members = ();
	if ($obj eq 'service_templates') {
		push @members, '-no-template-';
		my @mems = StorProc->get_possible_parents($properties{'servicetemplate_id'});
		push (@members,(@mems));
	} else {
		@members = StorProc->fetch_list('service_templates','name'); 
	}
	my %docs = Doc->properties_doc('service_templates',\@props);
	$form .= Forms->list_box_submit('Service template:','template',\@members,$service_template,'',$docs{'template'});

#	$form .= Forms->checkbox_override('Inherit all values from template','select_all',$select_all,$docs{'override'});
	$form .= Forms->inheritance('Inherit from template',$docs{'override'},\%template);

# is_volatile
	$form .= Forms->checkbox('Is volatile:','is_volatile',$properties{'is_volatile'},$docs{'is_volatile'},$override{'is_volatile'});
# check_period,
	my @timeperiods = StorProc->fetch_list('time_periods','name'); 
	$form .= Forms->list_box('Check period:','check_period',\@timeperiods,$properties{'check_period'},'',$docs{'check_period'},$override{'check_period'});
# max_check_attempts,
	$form .= Forms->text_box('Max check attempts:','max_check_attempts',$properties{'max_check_attempts'},$textsize{'max_check_attempts'},$required{'max_check_attempts'},$docs{'max_check_attempts'},$override{'max_check_attempts'});
# normal_check_interval,
	$properties{'normal_check_interval'} =~ s/-zero-/0/;
	$form .= Forms->text_box('Normal check interval:','normal_check_interval',$properties{'normal_check_interval'},$textsize{'normal_check_interval'},$required{'normal_check_interval'},$docs{'normal_check_interval'},$override{'normal_check_interval'});
# retry_check_interval,".
	$properties{'retry_check_interval'} =~ s/-zero-/0/;
	$form .= Forms->text_box('Retry check interval:','retry_check_interval',$properties{'retry_check_interval'},$textsize{'retry_check_interval'},$required{'retry_check_interval'},$docs{'retry_check_interval'},$override{'retry_check_interval'});
# "active_checks_enabled,
	$form .= Forms->checkbox('Active checks enabled:','active_checks_enabled',$properties{'active_checks_enabled'},$docs{'active_checks_enabled'},$override{'active_checks_enabled'});

# passive_checks_enabled,
	$form .= Forms->checkbox('Passive checks enabled:','passive_checks_enabled',$properties{'passive_checks_enabled'},$docs{'passive_checks_enabled'},$override{'passive_checks_enabled'});

# parallelize_check,
	$form .= Forms->checkbox('Parallelize check:','parallelize_check',$properties{'parallelize_check'},$docs{'parallelize_check'},$override{'parallelize_check'});

# obsess_over_service,
	$form .= Forms->checkbox('Obsess over service:','obsess_over_service',$properties{'obsess_over_service'},$docs{'obsess_over_service'},$override{'obsess_over_service'});

# check_freshness,
	$form .= Forms->checkbox('Check freshness:','check_freshness',$properties{'check_freshness'},$docs{'check_freshness'},$override{'check_freshness'});

# freshness_threshold,
	$properties{'freshness_threshold'} =~ s/-zero-/0/;
	$form .= Forms->text_box('Freshness threshold:','freshness_threshold',$properties{'freshness_threshold'},$textsize{'freshness_threshold'},$required{'freshness_threshold'},$docs{'freshness_threshold'},$override{'freshness_threshold'});

# notifications_enabled,
	$form .= Forms->checkbox('Notifications enabled:','notifications_enabled',$properties{'notifications_enabled'},$docs{'notifications_enabled'},$override{'notifications_enabled'});

# notification_interval,".
	$properties{'notification_interval'} =~ s/-zero-/0/;
	$form .= Forms->text_box('Notification interval:','notification_interval',$properties{'notification_interval'},$textsize{'notification_interval'},$required{'notification_interval'},$docs{'notification_interval'},$override{'notification_interval'});
# "notification_period,
	$form .= Forms->list_box('Notification period:','notification_period',\@timeperiods,$properties{'notification_period'},'',$docs{'notification_period'},$override{'notification_period'});

# notification_options,
	my @opts = split(/,/, $properties{'notification_options'});
	$form .= Forms->notification_options('service_templates','notification_options',\@opts,$required{'notification_options'},$nagios_ver,$docs{'notification_options'},$override{'notification_options'});

# event_handler_enabled,
	$form .= Forms->checkbox('Event handler enabled:','event_handler_enabled',$properties{'event_handler_enabled'},$docs{'event_handler_enabled'},$override{'event_handler_enabled'});

# event_handler,
	my @commands = StorProc->fetch_list('commands','name'); 
	$form .= Forms->list_box('Event handler:','event_handler',\@commands,$properties{'event_handler'},$required{'event_handler'},$docs{'event_handler'},$override{'event_handler'});

# flap_detection_enabled,
	$form .= Forms->checkbox('Flap detection enabled:','flap_detection_enabled',$properties{'flap_detection_enabled'},$docs{'flap_detection_enabled'},$override{'flap_detection_enabled'});

# low_flap_threshold,
	$properties{'low_flap_threshold'} =~ s/-zero-/0/;
	$form .= Forms->text_box('Low flap threshold:','low_flap_threshold',$properties{'low_flap_threshold'},$textsize{'low_flap_threshold'},$required{'low_flap_threshold'},$docs{'low_flap_threshold'},$override{'low_flap_threshold'});

# high_flap_threshold,
	$properties{'high_flap_threshold'} =~ s/-zero-/0/;
	$form .= Forms->text_box('High flap threshold:','high_flap_threshold',$properties{'high_flap_threshold'},$textsize{'high_flap_threshold'},$required{'high_flap_threshold'},$docs{'high_flap_threshold'},$override{'high_flap_threshold'});

# process_perf_data,".
	$form .= Forms->checkbox('Process perf data:','process_perf_data',$properties{'process_perf_data'},$docs{'process_perf_data'},$override{'process_perf_data'});

# "retain_status_information,
	$form .= Forms->checkbox('Retain status information:','retain_status_information',$properties{'retain_status_information'},$docs{'retain_status_information'},$override{'retain_status_information'});

# retain_nonstatus_information
	$form .= Forms->checkbox('Retain nonstatus information:','retain_nonstatus_information',$properties{'retain_nonstatus_information'},$docs{'retain_nonstatus_information'},$override{'retain_nonstatus_information'});

# contactgroups
	my @nonmembers = StorProc->fetch_list('contactgroups','name'); 
	$form .= Forms->members('Contact Groups:','contactgroup',\@contactgroups,\@nonmembers,'','10',$docs{'contactgroup'},$override{'contactgroups'});

	return $form;
}

#
############################################################################
# Service Template
#

sub service_template() {
	my $form = undef;
	my $obj_view = $query->param('obj_view');
	my $name = $query->param('name');
	$name = uri_unescape($name);
	$name =~ s/^\s+|\s+$//;
	my $host = $query->param('host');
	if ($query->param('task') eq 'new') { $obj_view = 'new' }
	my $test_results = undef;
	my $message_applied = undef;
	%properties = StorProc->fetch_one('service_templates','name',$name);
	if ($query->param('add')) {
		if ($name) {
			unless ($properties{'name'}) {
				my @values = ('',$name,'','','','','','','','');
				my $id = StorProc->insert_obj_id('service_templates',\@values,'servicetemplate_id');
				if ($id =~ /^Error/) { 
					push @errors, $id;
					$obj_view = 'new';
				} else {
					$obj_view = 'service_detail';
					delete $hidden{'task'};
					$properties{'servicetemplate_id'} = $id;
					$properties{'name'} = $name;
				}	
			} else {
				push @errors, "Service template $name already exists";
				$obj_view = 'new';
				$required{'name'} = 1;
			}
		} else {					
			push @errors, "Service template name required";
			$obj_view = 'new';
		}
	} elsif ($query->param('close') || $query->param('cancel') || $query->param('continue')) {
		$obj_view = 'close';
	} elsif ($query->param('test_command')) {	
		my $service_desc = $query->param('service_desc');
		my $arg_string = $query->param('command_line');
		my $command = $query->param('command');
		my %cmd = StorProc->fetch_one('commands','name',$command);
		$test_results .= StorProc->test_command($command,$cmd{'command_line'},$host,$arg_string,$monarch_home,$service_desc);	
	} elsif ($query->param('save')) {
		if ($obj_view eq 'service_detail') {
			my %values = ();
			my $parent = $query->param('template'); 
			my %t = StorProc->fetch_one('service_templates','name',$parent);
			$values{'parent_id'} = $t{'servicetemplate_id'};
			my %data = parse_query('service_templates','service_templates');
			$values{'check_period'} = $data{'check_period'};
			$values{'event_handler'} = $data{'event_handler'};
			$values{'notification_period'} = $data{'notification_period'};
			$values{'data'} = $data{'data'};
			my $result = StorProc->update_obj('service_templates','name',$name,\%values);
			if ($result =~ /^Error/) { push @errors, $result }

#			my %where = ('type' => 'service_templates','object' => $properties{'servicetemplate_id'});
#			my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
			my %where = ('servicetemplate_id' => $properties{'servicetemplate_id'});
			$result = StorProc->delete_one_where('contactgroup_service_template',\%where);

			if ($result =~ /^Error/) { push @errors, $result }
			unless ($query->param('contactgroup_override')) {
				my @mems = $query->param('contactgroup');
				foreach (@mems) {
					my %cg = StorProc->fetch_one('contactgroups','name',$_);

#					my @vals = ($cg{'contactgroup_id'},'service_templates',$properties{'servicetemplate_id'});
#					$result = StorProc->insert_obj('contactgroup_assign',\@vals);
					my @vals = ($cg{'contactgroup_id'},$properties{'servicetemplate_id'});
					$result = StorProc->insert_obj('contactgroup_service_template',\@vals);

					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
			unless (@errors) { 
				$obj_view = 'saved';
			}
		} elsif ($obj_view eq 'service_check') {
			my $service_name = $query->param('service_name');
			my $service_id = $query->param('service_id');
			$hidden{'service_name'} = $service_name;
			$hidden{'service_id'} = $service_id;
			my $check_command = $query->param('command');
			my $command_line = $query->param('command_line');
			if ($query->param('inherit')) {
				my %vals = ('check_command' => '','command_line' => '');
				my $result = StorProc->update_obj('service_templates','servicetemplate_id',$properties{'servicetemplate_id'},\%vals);
				if ($result =~ /^Error/) { push @errors, $result }
			} else {
				my %check = StorProc->fetch_one('commands','name',$check_command);
				my %data = parse_query('service_templates','service_templates');
				my %vals = ('check_command' => $check{'command_id'},'command_line' => $command_line);
				my $result = StorProc->update_obj('service_templates','servicetemplate_id',$properties{'servicetemplate_id'},\%vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { 
				$obj_view = 'saved';
				$hidden{'selected'} = 'service_check';
			}
		}
 	} elsif ($query->param('rename')) {
		if ($query->param('new_name')) {
			my $new_name = $query->param('new_name');
			$new_name =~ s/^\s+|\s+$//;
			my %n = StorProc->fetch_one('profiles_host','name',$new_name);
			if ($n{'name'}) {
				push @errors, "A host profile $new_name already exists.";
			} else {
				my %values = ('name' => $new_name);
				my $result = StorProc->update_obj('service_templates','name',$name,\%values);				
				if ($result =~ /error/i) {
					push @errors, $result;
				} else {
					$name = $new_name;
					$obj_view = 'service_detail';
					$refresh_left = 1;
				}
			}
		} else {
			$obj_view = 'rename';
		}
	} elsif ($query->param('delete') || $query->param('confirm_delete')) {
		if ($query->param('confirm_delete')) {
			my $result = StorProc->delete_all('service_templates','name',$name);
			if ($result =~ /^Error/) { push @errors, $result }

#			my %where = ('type' => 'service_templates','object' => $properties{'servicetemplate_id'});
#			$result = StorProc->delete_one_where('contactgroup_assign',\%where);
			my %where = ('servicetemplate_id' => $properties{'servicetemplate_id'});
			$result = StorProc->delete_one_where('contactgroup_service_template',\%where);

			if ($result =~ /^Error/) { push @errors, $result }
			unless (@errors) { 
				$refresh_left = 1;
				$obj_view = 'deleted';
			}
		} elsif ($query->param('task') eq 'No') {
			$obj_view = 'service_detail';
		} else {
			foreach my $name ($query->param) {
				unless ($name eq 'nocache') { $hidden{$name} = $query->param($name) }
			}
			delete $hidden{'task'};
			$obj_view = 'delete';
		}
	}
	my %save = ('name' => 'save','value' => 'Save');
	my %objs = ('servicename_id' => $hidden{'servicename_id'});
	my %docs = Doc->services();
	$hidden{'name'} = $name;
	$hidden{'servicename_id'} = $query->param('servicename_id');
	unless ($hidden{'servicename_id'}) { $hidden{'servicename_id'} = $properties{'servicename_id'}	}
	$objs{'servicename_id'} = $hidden{'servicename_id'};
	unless ($obj_view) { $obj_view = 'service_detail' }
	$hidden{'obj_view'} = $obj_view;
	$form .= Forms->header($page_title,$session_id,$top_menu,'',$refresh_left);
	if ($obj_view eq 'service_detail') {
		$form .= Forms->service_template_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		if ($query->param('template') eq '-no-template-') {
			delete $properties{'parent_id'};
			$form .= build_form('');
		} elsif ($properties{'parent_id'} || $query->param('template')) {
			$form .= build_service_detail($properties{'servicetemplate_id'});
		} else {
			$form .= build_form('');
		}
		$form .= Forms->hidden(\%hidden);
		if ($auth_delete{'service_templates'}) {
			$form .= Forms->form_bottom_buttons(\%save,\%delete,\%rename,\%close,$tab++);
		} else {
			$form .= Forms->form_bottom_buttons(\%save,\%rename,\%close,$tab++);
		}
	} elsif ($obj_view eq 'service_check') {
		my %template = StorProc->fetch_one('service_templates','servicetemplate_id',$properties{'parent_id'});
		my $message = undef;
		my $inherit = 0;
		$inherit = $query->param('inherit');
		my %cmd = StorProc->fetch_one('commands','command_id', $properties{'check_command'});
		my $command = $cmd{'name'};
		my $command_save = $cmd{'name'};
		my $command_line = $properties{'command_line'};
		if ($query->param('command')) { $command = $query->param('command') }
		if ($query->param('command_save')) { $command_save = $query->param('command_save') }
		if ($query->param('command_line')) { $command_line = $query->param('command_line') }
		unless ($command eq $command_save) {
			%cmd = StorProc->fetch_one('commands','name',$command);
			$command_line = undef;
		}
		if ($inherit or !$command) {
			%cmd = StorProc->fetch_one('commands','command_id',$template{'check_command'});
			if ($cmd{'name'}) {
				$command = $cmd{'name'};
				$command_line = $template{'command_line'};
				$inherit = 1;
			} else {
				my $got_command = 0;
				my $stid = $template{'parent_id'};
				until ($got_command) {
					my %t = StorProc->fetch_one('service_templates','servicetemplate_id',$stid);
					if ($t{'check_command'}) {
						$got_command = 1;
						%cmd = StorProc->fetch_one('commands','command_id',$t{'check_command'});
						$command = $cmd{'name'};
						$command_line = $t{'command_line'};
						$got_command = 1;
					} else {
						if ($t{'parent_id'}) {
							$stid = $t{'parent_id'};
						} else {
							$got_command = 1;
							$message = ('Note: a parent template does not have a check command defined.');
							$command = undef;
							$command_line = undef;
						}
					}
				}
			}
		}
		%cmd = StorProc->fetch_one('commands','name',$command);
		my $arg_string = $command_line;
		$arg_string =~ s/$command!//;
		my $usage = $command;
		my @args = split(/ARG/i,$cmd{'command_line'});
		my $args = undef;
		if ($args[1]) {
			$usage .= "!";
			my $cnt = 1;
			pop @args;
			foreach (@args) { 
				if ($cmd{'command_line'} =~ /ARG$cnt/i) { $args .= "ARG$cnt!" }
				$cnt++;
			}
			chop $args;
			$usage .= $args;
			unless ($command_line =~ /$command/) {
				$command_line = "$command!$args";
				$arg_string = $args;
			}
		}
		$form .= Forms->service_template_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Parent template:','',$template{'name'});
		if ($properties{'parent_id'}) {
			$form .= Forms->checkbox_override('Inherit check from template','inherit',$inherit,$docs{'override'});
		}
		my %where = ('type' => 'check');
		my @commands = StorProc->fetch_list_where('commands','name',\%where);
		if ($message) { $form .= Forms->form_doc($message) }
		$form .= Forms->list_box_submit('Check command:','command',\@commands,$command,'');
		$form .= Forms->display_hidden('Command definition:','',$cmd{'command_line'});
		$form .= Forms->display_hidden('Usage:','',$usage);
		$form .= Forms->text_area('Command line:','command_line',$command_line,'3','80','',$docs{'command_line'});
		$form .= Forms->test_service_check($test_results,$host,$arg_string);
		$hidden{'command_save'} = $command;
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'delete') {
		my $message = qq(Are you sure you want to remove service $name from all hosts and profiles?);
		$form .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden);
	} elsif ($obj_view eq 'deleted') {
		$form .= Forms->form_top('Deleted','');
		my @message = ("$name");
		$form .= Forms->form_message('Removed:',\@message,'row1');			
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%continue);
	} elsif ($obj_view eq 'saved') {
		my %objs = ('service_id' => $properties{'servicename_id'},'name' => $name);
		$form .= Forms->service_template_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		$form .= Forms->display_hidden('Saved:','',$name);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%close);
	} elsif ($obj_view eq 'rename') {
		$form .= Forms->form_top('Rename Service','','');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Name:','name',$name,$textsize{'name'},'');
		$form .= Forms->text_box('Rename:','new_name','',$textsize{'name'},'');
		$hidden{'obj_view'} = 'rename';
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%rename,\%cancel,$tab++);
	} elsif ($obj_view eq 'new') {
		my $template = $query->param('template');
		$form .= Forms->form_top('New Service Template','','');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->text_box('Name:','name',$name,$textsize{'name'},'',$docs{'name'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);
	}
	return $form;
}

#
############################################################################
# Build Contact
#

sub build_contact() {
	my $form = undef;
	my $select_all = undef;
	my $name = $query->param('name');
	if ($task eq 'copy') { 
		$name = $query->param('source');
		delete $hidden{'task'};	
	}
	$hidden{'contact_id'} = $query->param('contact_id');
	my %contact = StorProc->fetch_one('contacts','name',$name);
	my %template = StorProc->fetch_one('contact_templates','contacttemplate_id',$contact{'contacttemplate_id'});
	$contact{'template'} = $template{'name'};
	if ($query->param('alias')) { $contact{'alias'} = $query->param('alias') }
	if ($query->param('pager')) { $contact{'pager'} = $query->param('pager') }
	if ($query->param('email')) { $contact{'email'} = $query->param('email') }
	if ($query->param('template')) { 
		%template = StorProc->fetch_one('contact_templates','name',$query->param('template'));
		$contact{'template'} = $query->param('template');
	}
	my %overrides_saved = StorProc->fetch_one('contact_overrides','contact_id',$contact{'contact_id'});
	my %override = ();
	my @props = split(/,/, $property_list{'contact_templates'});
	foreach (@props) { 
		$override{$_} = 'checked';
	} 

	my %np =  StorProc->fetch_one('time_periods','timeperiod_id',$template{'host_notification_period'});
	$template{'host_notification_period'} = $np{'name'};
	%np =  StorProc->fetch_one('time_periods','timeperiod_id',$template{'service_notification_period'});
	$template{'service_notification_period'} = $np{'name'};

	my @host_commands = StorProc->get_command_contact_template($template{'contacttemplate_id'},'host');
	my @service_commands = StorProc->get_command_contact_template($template{'contacttemplate_id'},'service');
	my @override_host_commands = StorProc->get_command_contact($contact{'contact_id'},'host');
	my @override_service_commands = StorProc->get_command_contact($contact{'contact_id'},'service');

	if ($query->param('select_all')) {
		$select_all = 1;
	} else {
		foreach (@props) { 
			if ($overrides_saved{$_}) {
				$override{$_} = 'unchecked';
				if ($_ eq 'host_notification_period') {
					%np =  StorProc->fetch_one('time_periods','timeperiod_id',$overrides_saved{'host_notification_period'});
					$template{$_} = $np{'name'};
				} elsif ($_ eq 'service_notification_period') {
					%np =  StorProc->fetch_one('time_periods','timeperiod_id',$overrides_saved{'service_notification_period'});
					$template{$_} = $np{'name'};
				} else {
					$template{$_} = $overrides_saved{$_};
				}
			}
		} 
		if (@override_host_commands) {
			@host_commands = ();
			$override{'host_notification_commands'} = 'unchecked';
			foreach (@override_host_commands) {
				push @host_commands, $_;
			}
		}
		if (@override_service_commands) {
			@service_commands = ();
			$override{'service_notification_commands'} = 'unchecked';
			foreach (@override_service_commands) {
				push @service_commands, $_;
			}
		}	
	}
	my @contact_props = split(/,/, $property_list{'contacts'});
	my %docs = Doc->properties_doc('contacts',\@contact_props);
	if (@errors) { $form .= Forms->form_errors(\@errors) }
#  contact_name 
	if ($view eq 'design') {
		$form .= Forms->text_box('Name:','name',$name,$textsize{'name'},$required{'name'},$docs{'name'});
	} else {
		$form .= Forms->display_hidden('Name:','name',$name);
	}
	$form .= Forms->text_box('Alias:','alias',$contact{'alias'},$textsize{'alias'},$required{'alias'},$docs{'alias'});
	$form .= Forms->text_box('Email:','email',$contact{'email'},$textsize{'email'},'',$docs{'email'});
	$form .= Forms->text_box('Pager:','pager',$contact{'pager'},$textsize{'pager'},'',$docs{'pager'});

	my @members = StorProc->fetch_list('contact_templates','name'); 
	$form .= Forms->list_box_submit('Contact template:','template',\@members,$template{'name'},$required{'template'},$docs{'template'});
	%docs = Doc->properties_doc('contact_templates',\@props);
#	$form .= Forms->checkbox_override('Inherit all values from template','select_all',$select_all,$docs{'override'});
	$form .= Forms->inheritance('Inherit from template',$docs{'override'},\%template);
	my @timeperiods = StorProc->fetch_list('time_periods','name');
	my %where = ('type' => 'notify');
	my @commands = StorProc->fetch_list_where('commands','name',\%where);

	%docs = Doc->properties_doc('contact_templates',\@props);

# host_notification_period
	$form .= Forms->list_box('Host notification period:','host_notification_period',\@timeperiods,$template{'host_notification_period'},$required{'host_notification_period'},$docs{'host_notification_period'},$override{'host_notification_period'});
# host_notification_options
	my @opts = split(/,/, $template{'host_notification_options'});
	$form .= Forms->notification_options('contact_templates','host_notification_options',\@opts,$required{'host_notification_options'},$nagios_ver,$docs{'host_notification_options'},$override{'host_notification_options'});
# host_notification_commands 
	$form .= Forms->list_box_multiple('Host notification commands','host_notification_commands',\@commands,\@host_commands,'',$docs{'host_notification_commands'},$override{'host_notification_commands'});
# service_notification_period
	$form .= Forms->list_box('Service notification period:','service_notification_period',\@timeperiods,$template{'service_notification_period'},$required{'service_notification_period'},$docs{'service_notification_period'},$override{'service_notification_period'});
# service_notification_options
	my @opts = split(/,/, $template{'service_notification_options'});
	$form .= Forms->notification_options('contact_templates','service_notification_options',\@opts,$required{'service_notification_options'},$nagios_ver,$docs{'service_notification_options'},$override{'service_notification_options'});
# service_notification_commands
	$form .= Forms->list_box_multiple('Service notification commands','service_notification_commands',\@commands,\@service_commands,'',$docs{'service_notification_commands'},$override{'service_notification_commands'});
# contactgroups
	my @contactgroups = $query->param('contactgroup');
	unless (@contactgroups) { @contactgroups = StorProc->get_contactgroup_contact($contact{'contact_id'}) }
	my @nonmembers = StorProc->fetch_list('contactgroups','name'); 
	$form .= Forms->members('Contact groups:','contactgroup',\@contactgroups,\@nonmembers,'','10',$docs{'contactgroup'});

	return $form;
}

#
############################################################################
# Build Command
#

sub command_wizard() {
	my $form = undef;
	my @command_props = split(/,/, $property_list{'commands'});
	push @command_props, 'usage';
	my %docs = Doc->properties_doc('commands',\@command_props);
	my %save = ('name' => 'save', 'value' => 'Save');
	my %done = ('name' => 'save', 'value' => 'Done');
	my %test = ('name' => 'test', 'value' => 'Test');
	my $command = $query->param('command');
	my $command_line = $query->param('command_line');
	my $name = $query->param('name');
	my $type = $query->param('type');
	my $host = $query->param('host');
	my $arg_string = $query->param('arg_string');
	my $service_desc = $query->param('service_desc');
	my $results = undef;
	my $resource_sav = undef;
	my $got_form = 0;

	if ($query->param('back')) {

	} elsif ($query->param('bail')) {
		$task = 'modify';

	} elsif ($task eq 'external') {
		$task = 'modify';
	} elsif ($query->param('continue') || $query->param('cancel')) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$got_form = 1;
	} elsif ($query->param('delete')) {
		$form .= delete_object('',$name);
		$got_form = 1;
	} elsif ($query->param('rename')) {
		$form .= rename_object('',$name);
		$got_form = 1;
	} elsif ($query->param('add') || $query->param('save')) {
		if ($name && $type && $command_line) {
			my $data = qq(<?xml version="1.0" ?>
<data>
  <prop name="command_line"><![CDATA[$command_line]]>
  </prop>
</data>);
			if ($query->param('add')) {
				$name =~ s/^\s+|\s+$//;
				my %command = StorProc->fetch_one('commands','name',$name);
				if ($command{'name'}) {
					push @errors, "Duplicate: Command $name already exists.";
				} else {
					my @values = ('',$name,$type,$data,'');
					my $result = StorProc->insert_obj('commands',\@values);
					if ($result =~ /^Error/) { 
						push @errors, $result;
					} 
				}
			} else {
				my %values = ('type' => $type,'data' => $data);
				my $result = StorProc->update_obj('commands','name',$name,\%values);
				if ($result =~ /^Error/) { push @errors, $result }
			}
		} else {
			$required{'name'} = 1;
			$required{'type'} = 1;
			$required{'command_line'} = 1;
			push @errors, "Missing required fields: Name, Type, Command line.";	
		}
		if ($obj eq 'commands') {
			unless (@errors) {
				$form .= Forms->header($page_title,$session_id,$top_menu);
				$form .= Forms->form_top("Command",'');
				if ($query->param('add')) {
					my @message = ("Command $name added.");
					$form .= Forms->form_message('Saved:',\@message,'row1');	
				} else {
					my @message = ("Command $name updated.");
					$form .= Forms->form_message('Saved:',\@message,'row1');	
				}
				delete $hidden{'task'};
				$form .= Forms->hidden(\%hidden);
				$form .= Forms->form_bottom_buttons(\%continue,$tab++);						
				$got_form = 1;
			}
		}
	} elsif ($query->param('update_resource')) {
		$resource_sav = $query->param('resource');
		my $resource_value = $query->param('resource_value');
		my $comment = $query->param('comment');
		my %values = ('value' => $resource_value);
		my $result = StorProc->update_obj('setup','name',$resource_sav,\%values);
		if ($result =~ /error/i) { push @errors, $result }
		my $label = $resource_sav;
		$label =~ s/user//;
		my %values = ('value' => $comment);
		my $result = StorProc->update_obj('setup','name',"resource_label$label",\%values);
		if ($result =~ /error/i) { push @errors, $result }
	} elsif ($query->param('upload')) {
		$resource_sav = $query->param('resource');
		my %res = StorProc->fetch_one('setup','name',$resource_sav);
		my $file = $query->param('file');
		my $now = time;
		my $fname = StorProc->upload($res{'value'},$file,"monarch_import_$now.tmp");
		if ($fname =~ /Error/) { 
			push @errors, $fname;	
			$task = 'new_plugin';
		} else {
			$task = 'new_command';
			$hidden{'task'} = 'new_command';
			$resource_sav = uc($resource_sav);
			$command = $fname;
			$command_line = "\$$resource_sav\$/$fname";
		}
	} elsif ($query->param('test_command')) {
		$results .= StorProc->test_command($name,$command_line,$host,$arg_string,$monarch_home,$service_desc);	
	} elsif ($query->param('new_command')) {
		$task = 'new_command';
		$hidden{'task'} = 'new_command';
	}
	unless ($got_form) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		if ($task eq 'new') {
			my $resource = undef;
			my $resource_value = undef;
			$form .= Forms->form_top("Command Wizard",'');
			$form .= Forms->form_doc('Select resource');
			if (@errors) { $form .= Forms->form_errors(\@errors) }
			my %resources = StorProc->get_resources();
			my %resource_doc = StorProc->get_resources_doc();
			my %selected = ();
			if ($resource_sav) {
				$resource = $resource_sav;
			} else {
				foreach my $name ($query->param) {
					if ($name =~ /^resource_(user\d+)/) { $resource = $1 }
				}
			}
			if ($resource) {
				$resource_value = $resources{$resource};
				%selected = ('name' => $resource,'value' => $resource_value);
				my %res = StorProc->fetch_one('setup','name',$resource);
				my @plugins = StorProc->get_dir($res{'value'});
				$hidden{'resource'} = $resource;
				$hidden{'type'} = 'check';
				$form .= Forms->list_box('Plugin:','command',\@plugins,'','','');
			}
			$form .= Forms->resource_select(\%resources,\%resource_doc,\%selected,$top_menu);
			$hidden{'obj_view'} = 'new_command';
			$form .= Forms->hidden(\%hidden);
			my %next = ('name' => 'new_command','value' => 'Next >>');
			$form .= Forms->form_bottom_buttons(\%next,$tab++);

		} elsif ($task eq 'new_plugin') {
			my $resource = undef;
			my $resource_value = undef;
			$form .= Forms->form_top("Command Wizard",'');
			$form .= Forms->form_doc('Upload plugin');
			if (@errors) { $form .= Forms->form_errors(\@errors) }
			my %resources = StorProc->get_resources();
			my %resource_doc = StorProc->get_resources_doc();
			my %selected = ();
			if ($resource_sav) {
				$resource = $resource_sav;
			} else {
				foreach my $name ($query->param) {
					if ($name =~ /^resource_(user\d+)/) { $resource = $1 }
				}
			}
			if ($resource) {
				$resource_value = $resources{$resource};
				%selected = ('name' => $resource,'value' => $resource_value);
			}
			$form .= Forms->resource_select(\%resources,\%resource_doc,\%selected);		
			$form .= Forms->form_file();
			$form .= Forms->hidden(\%hidden);
			$form .= Forms->form_bottom_buttons(\%upload,\%cancel,$tab++);

		} elsif ($task =~ /new_command|copy|modify/) {
			my $arg_string = $query->param('arg_string');
			if ($obj eq 'commands') {
				$form .= Forms->form_top("Command Wizard",'');
			}
			if ($task eq 'copy') {
				my $source = $query->param('source');
				unless ($name) { $name = "Copy-of-$source" }
				my %command = StorProc->fetch_one('commands','name',$source);
				unless ($command_line) { $command_line = $command{'command_line'} }
				unless ($type) { $type = $command{'type'} }
				$form .= Forms->display_hidden("Copy:",'source',$source);
				if (@errors) { $form .= Forms->form_errors(\@errors) }
				$form .= Forms->text_box('Name:','name',$name,$textsize{'name'},$required{'name'});
			} elsif ($task eq 'modify') {
				my %command = StorProc->fetch_one('commands','name',$name);
				unless ($command_line) { $command_line = $command{'command_line'} }
				unless ($type) { $type = $command{'type'} }
				if (@errors) { $form .= Forms->form_errors(\@errors) }
				$form .= Forms->display_hidden("Name:",'name',$name);
			} else {
				if (@errors) { $form .= Forms->form_errors(\@errors) }
				$form .= Forms->text_box('Name:','name',$name,$textsize{'name'},$required{'name'});
				unless ($command_line) {
					my $command = $query->param('command');
					my $resource = $query->param('resource');
					$command_line = "\$".uc($resource)."\$/$command";
				}
			}
			my @args = split(/ARG/i,$command_line);
			my $usage = undef;
			if (@args) {
				my $cnt = 1;
				pop @args;
				my $ags = undef;
				foreach (@args) { 
					if ($command_line =~ /ARG$cnt/) { $usage .= "ARG$cnt!" }
					$cnt++;
				}
				chop $usage;
				unless ($arg_string) { $arg_string = $usage }
				if ($usage) { 
					$usage = "$name!$usage";
				} else {
					$usage = $name;
				}
			} else {
				$usage = "$name";
			}
			unless ($host) { $host = 'localhost' }
			my @types = ('check','notify','other');
			$form .= Forms->list_box('Type:','type',\@types,$type,'',$docs{'type'});
			$form .= Forms->text_area('Command line:','command_line',$command_line,'',$textsize{'command_line'},'',$docs{'command_line'});
			$form .= Forms->display_hidden("Usage:",'',$usage);
			$form .= Forms->command_test($results,$host,$arg_string,$service_desc);
			if ($obj eq 'commands') {
				$form .= Forms->hidden(\%hidden);
				if ($task eq 'modify') {
					if ($auth_delete{'commands'}) {
						$form .= Forms->form_bottom_buttons(\%save,\%rename,\%delete,\%cancel,$tab++);
					} else {		
						$form .= Forms->form_bottom_buttons(\%save,\%rename,\%cancel,$tab++);
					}
				} else {
					$form .= Forms->form_bottom_buttons(\%cancel,\%add,$tab++);
				}
			}
#		} else {
#			unless ($got_form) {
#				$form .= Forms->form_top("Command Wizard",'');
#				if (@errors) { $form .= Forms->form_errors(\@errors) }
#				my @commands = StorProc->fetch_list('commands','name');
#				my %selected = ();
#				$form .= Forms->command_select(\@commands,\%selected);
#				$form .= Forms->hidden(\%hidden);
#				$form .= Forms->form_bottom_buttons(\%next);
#			}
		}
	}
	return $form;
}


#
############################################################################
# Service Groups
#

sub service_group() {
	my $form = undef;
	my %save = ('name' => 'save', 'value' => 'Save');
	my %done = ('name' => 'save', 'value' => 'Done');
	my $got_form = 0;
	my $name = $query->param('name');
	$name =~ s/^\s+|\s+$//;
	my $alias = $query->param('alias');
	my %svcgrp = StorProc->fetch_one('servicegroups','name',$name);
	unless ($alias) { $alias = $svcgrp{'alias'} }
	my %docs = Doc->servicegroups();
	if ($query->param('continue') || $query->param('cancel')) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$got_form = 1;
	} elsif ($task eq 'new' || $query->param('add')) {
		$got_form = 1;
		my $name = $query->param('name');
		my $alias = $query->param('alias');
		my $validate = $query->param('validate');
		if ($name && $alias) {
			if ($svcgrp{'name'}) {
				push @errors, "Duplicate: Service group $name already exists.";
			} else {
				my @values = ('',$name,$alias,'');
				my $result = StorProc->insert_obj('servicegroups',\@values);
				if ($result =~ /error/i) { 
					push @errors, $result;
				} else {
					delete $hidden{'task'};
					$got_form = 0;
				}
			}
		} elsif ($validate) { 
			$required{'name'} = 1;
			$required{'alias'} = 1;
			push @errors, "Missing required fields: Name, Alias";
		}
		if ($got_form) {
			$form .= Forms->header($page_title,$session_id,$top_menu);
			$form .= Forms->form_top("Service Group",'');
			if (@errors) { $form .= Forms->form_errors(\@errors) }
			$form .= Forms->text_box('Name:','name',$name,$textsize{'name'},$required{'name'},$docs{'name'});
			$form .= Forms->text_box('Alias:','alias',$alias,$textsize{'alias'},$required{'alias'},$docs{'alias'});
			$hidden{'validate'} = 1;
			$form .= Forms->hidden(\%hidden);
			$form .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);		
		}
	} elsif ($query->param('add_services')) {
		my $host = $query->param('host');
		my @services = $query->param('services');
		my %h = StorProc->fetch_one('hosts','name',$host);
		if (@services && $host) {
			foreach my $service (@services) {
				my %sn = StorProc->fetch_one('service_names','name',$service);
				my %where = ('host_id' => $h{'host_id'},'servicename_id' => $sn{'servicename_id'});
				my %s = StorProc->fetch_one_where('services',\%where);
				my @values = ($svcgrp{'servicegroup_id'},$h{'host_id'},$s{'service_id'});
				my $result = StorProc->insert_obj('servicegroup_service',\@values);
				if ($result =~ /^Error/ && !$result =~ /duplicate/i) { push @errors, $result }
			}
		}
	} elsif ($query->param('add_hosts')) {
		my $service = $query->param('service');
		my @hosts = $query->param('hosts');
		my %sn = StorProc->fetch_one('service_names','name',$service);
		if (@hosts && $service) {
			foreach my $host (@hosts) {
				my %h = StorProc->fetch_one('hosts','name',$host);
				my %where = ('host_id' => $h{'host_id'},'servicename_id' => $sn{'servicename_id'});
				my %s = StorProc->fetch_one_where('services',\%where);
				my @values = ($svcgrp{'servicegroup_id'},$h{'host_id'},$s{'service_id'});
				my $result = StorProc->insert_obj('servicegroup_service',\@values);
				if ($result =~ /^Error/ && !$result =~ /duplicate/i) { push @errors, $result }
			}
		}
	} elsif ($query->param('remove_service')) {
		my $host = $query->param('del_host');
		my $service = $query->param('del_service');
		my %h = StorProc->fetch_one('hosts','name',$host);
		my %sn = StorProc->fetch_one('service_names','name',$service);
		my %where = ('host_id' => $h{'host_id'},'servicename_id' => $sn{'servicename_id'});
		my %s = StorProc->fetch_one_where('services',\%where);
		%where = ('servicegroup_id' => $svcgrp{'servicegroup_id'},'service_id' => $s{'service_id'},'host_id' => $h{'host_id'});
		my $result = StorProc->delete_one_where('servicegroup_service',\%where);
		if ($result =~ /^Error/) { push @errors, $result }
	} elsif ($query->param('save')) {
		my %values = ('alias' => $alias);
		my $escalation = $query->param('escalation');
		if ($escalation) {
			my %esc = StorProc->fetch_one('escalation_trees','name',$escalation);
			$values{'escalation_id'} = $esc{'tree_id'};
		}
		my $result = StorProc->update_obj('servicegroups','name',$name,\%values);
		if ($result =~ /^Error/) { push @errors, $result }
		unless (@errors) {
			$form .= Forms->header($page_title,$session_id,$top_menu);
			$form .= Forms->form_top('Service Group');
			my @message = ("Changes to $name accepted.");
			$form .= Forms->form_message('Updated:',\@message,'row1');					
			$form .= Forms->hidden(\%hidden);
			$form .= Forms->form_bottom_buttons(\%continue,$tab++);
			$got_form = 1;
		}
	} elsif ($query->param('rename')) {
		$form .= rename_object('',$name);
		$got_form = 1;
	} elsif ($query->param('delete') || $query->param('confirm_delete')) {
		if ($query->param('confirm_delete')) {
			my $result = StorProc->delete_all('servicegroups','servicegroup_id',$svcgrp{'servicegroup_id'});
			if ($result =~ /^Error/) { push @errors, $result }
			unless (@errors) { 
				$form .= Forms->header($page_title,$session_id,$top_menu,'','1');
				$form .= Forms->form_top('Deleted','');
				my @message = ("$name");
				$form .= Forms->form_message('Removed:',\@message,'row1');			
				$form .= Forms->hidden(\%hidden);
				$form .= Forms->form_bottom_buttons(\%continue,$tab++);
				$name = undef;
				$got_form = 1;	
			}
		} elsif ($query->param('task') eq 'No') {
			$got_form = 0;	
		} else {
			foreach my $name ($query->param) {
				$hidden{$name} = $query->param($name);
			}
			delete $hidden{'task'};
			$hidden{'delete'} = 1;
			$form .= Forms->header($page_title,$session_id,$top_menu);
			my $message = qq(Are you sure you want to remove $name?);
			$form .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden);
			$name = undef;
			$got_form = 1;
		}	
	} 
	unless ($got_form) {
		my $host = $query->param('host');
		my $service = $query->param('service');
		my $escalation = $query->param('escalation');
		unless($escalation) {
			my %esc = StorProc->fetch_one('escalation_trees','tree_id',$svcgrp{'escalation_id'});
			$escalation = $esc{'name'};
		}
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Forms->form_top("Service Group",'');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Name:','name',$name);
		$form .= Forms->text_box('Alias:','alias',$alias,$textsize{'alias'},$required{'alias'},$docs{'alias'});
		my %host_service = StorProc->get_servicegroup($svcgrp{'servicegroup_id'});
		my %h = StorProc->fetch_one('hosts','name',$host);
		my @host_nonmembers = StorProc->get_host_services($h{'host_id'});
		my @hosts = StorProc->fetch_list('hosts','name');
		my %s = StorProc->fetch_one('service_names','name',$service);
		my @serivce_nonmembers = StorProc->get_service_hosts($s{'servicename_id'});
		my @services = StorProc->fetch_list('service_names','name');
		$form .= Forms->service_group($session_id,$view,$name,\%host_service,$host,\@host_nonmembers,\@hosts,$service,\@serivce_nonmembers,\@services);
		my %where = ('type' => 'service');
		my @serviceesc = StorProc->fetch_list_where('escalation_trees','name',\%where);
		$form .= Forms->list_box_submit('Service escalation:','escalation',\@serviceesc,$escalation,'','');
		if ($escalation) {
			my ($ranks, $templates) = StorProc->get_tree_detail($escalation);
			my %ranks = %{$ranks};
			my %templates = %{$templates};
			$form .= Forms->escalation_tree(\%ranks,\%templates,'escalations');
		}
		$form .= Forms->hidden(\%hidden);
		if ($auth_delete{'servicegroups'}) {
			$form .= Forms->form_bottom_buttons(\%save,\%delete,\%rename,$tab++);		
		} else {
			$form .= Forms->form_bottom_buttons(\%save,\%rename,$tab++);		
		}
	}
	return $form;
}


#
############################################################################
# Host Wizard
#

sub host_wizard() {
	my $service_next = undef;
	my $form = undef;
	my $test_results = undef;
	my $name = $query->param('name');
	$name =~ s/^\s+|\s+$//;
	my $host = $query->param('host');
	$hidden{'name'} = $name;
	my %service_detail = ();
	$service_detail{'service'} = $query->param('service');
	$service_detail{'template'} = $query->param('template');
	$service_detail{'command'} = $query->param('command');
	$service_detail{'command_line'} = $query->param('command_line');
	$service_detail{'inherit'} = $query->param('inherit');
	$service_detail{'ext_info'} = $query->param('ext_info');
	$service_detail{'escalation'} = $query->param('escalation');
	$service_detail{'dependency'} = $query->param('dependency');
	$service_detail{'command_save'} = $query->param('command_save');
	%properties = StorProc->fetch_one('hosts','name',$name);
	my %profile = StorProc->fetch_one('profiles_host','hostprofile_id',$properties{'hostprofile_id'});
	my $alias = $query->param('alias');
	my $step = $query->param('step');
	my @profiles = ();
	my @services = ();
	my %param_vals = ();
#
############################################################################
# Check for existing session
#
	unless ($step) {
		if ($query->param('yes')) {
			my %where = ('user_acct' => $session_id, 'type' => 'wizard_design');
			my %host = StorProc->fetch_one_where('stage_hosts',\%where);
			my %where = ('host' => $name,'user_acct' => $session_id,'type' => $view,'status' => 'edit_added');
			my %service_list = StorProc->fetch_list_hash_array('stage_host_services',\%where);
			my @services = ();
			foreach my $svc (keys %service_list) { unless ($svc =~ /HASH/) { push @services, $svc } }
			@services = sort @services;
			$service_next = pop @services; 
			$step = $host{'info'};
			if ($service_next) {
				my %where = ('host' => $name,'user_acct' => $session_id,'type' => $view,'status' => '3');
				my %service = StorProc->fetch_one_where('stage_host_services',\%where);
				%where = ('service_id' => $service{'service_id'});
				my $result = StorProc->delete_all('services','service_id',$service{'service_id'});
				if ($result =~ /^Error/) { push @errors, $result }
				$step = 'service_detail';	
			}
		} elsif ($query->param('no')) {
			my $result = StorProc->delete_all('hosts','name',$name);
			if ($result =~ /^Error/) { push @errors, $result }
			my %where = ('name' => $name, 'user_acct' => $session_id);
			$result = StorProc->delete_one_where('stage_hosts',\%where);
			if ($result =~ /^Error/) { push @errors, $result }
			%where = ('host' => $name, 'user_acct' => $session_id);
			$result = StorProc->delete_one_where('stage_host_services',\%where);
			if ($result =~ /^Error/) { push @errors, $result }
			$step = 'host_vitals';
		} else {
			my %where = ('user_acct' => $session_id, 'type' => 'wizard_design');
			my %host = StorProc->fetch_one_where('stage_hosts',\%where);
			if ($host{'name'}) { 
				$hidden{'name'} = $host{'name'};
				my %h = StorProc->fetch_one('hosts','name',$host{'name'});
				$hidden{'host_id'} = $h{'host_id'};
				$hidden{'host_profile'} = $host{'hostprofile'};
				$hidden{'service_profile'} = $host{'service_profile'};
				$form .= Forms->header($page_title,$session_id,$top_menu);
				$form .= Validation->dfv_profile_javascript();
				$form .= &$Instrument::show_trace_as_html_comment();
				$form .= Forms->form_top('New Host Wizard', Validation->dfv_onsubmit_javascript());
				my $message = qq(An existing host wizard session exists for $host{'name'}. Do you wish to continue with this host definition? (No will delete the host).&nbsp;);
				$form .= Forms->form_doc($message);
				$form .= Forms->hidden(\%hidden);
				$form .= Forms->form_bottom_buttons(\%yes,\%no,$tab++);
			} else {
				$step = 'host_vitals';
			}
		}
############################################################################
# Test command
#
	} elsif ($query->param('test_command')) {	
		my $arg_string = $query->param('command_line');
		my $command = $query->param('command');
		my %cmd = StorProc->fetch_one('commands','name',$command);
		$test_results .= StorProc->test_command($command,$cmd{'command_line'},$name,$arg_string,$monarch_home,$service_detail{'service'});	

############################################################################
# Save as profile
#
	} elsif ($query->param('save_as_profile')) {
		$step = 'save_as_profile'
	} elsif ($query->param('save')) {
		my $host_profile = $query->param('host_profile');
		my $service_profile = $query->param('service_profile');
		if ($service_profile && $host_profile) {
			my %h = StorProc->fetch_one('profiles_host','name',$host_profile);
			my %s = StorProc->fetch_one('profiles_service','name',$service_profile);
			if ($h{'name'}) {
				push @errors, "Duplicate: Host profile name $host_profile already in use.";
			}
			if ($s{'name'}) {
				push @errors, "Duplicate: Service profile name $service_profile already in use.";
			}
			unless (@errors) {
				$service_profile =~ s/^\s+|\s+$//;
				$host_profile =~ s/^\s+|\s+$//;
				my $data = "<?xml version=\"1.0\" ?>\n<data>\n</data>";
				my %host = StorProc->fetch_one('hosts','name',$name);
				my %w = ('host_id' => $host{'host_id'});
				my @hostgroups = StorProc->fetch_list_where('hostgroup_host','hostgroup_id',\%w);
				my @parents = StorProc->fetch_list_where('host_parent','parent_id',\%w);
				my @services = StorProc->fetch_list_where('services','servicename_id',\%w);
				my @sids = StorProc->fetch_list_where('services','service_id',\%w);
				my @values = ('',$service_profile,"saved from host wizard by $session_id",$data);
				my $spid = StorProc->insert_obj_id('profiles_service',\@values,'serviceprofile_id');
				if ($spid =~ /^Error/) { push @errors, $spid }
				unless (@errors) {
					foreach my $snid (@services) {
						@values = ($snid,$spid);
						my $result = StorProc->insert_obj('serviceprofile',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
				unless (@errors) {
					@values = ('',$host_profile,"saved from host wizard by $user_acct",$host{'hosttemplate_id'},$host{'hostextinfo_id'},
						$host{'host_escalation_id'},$host{'service_escalation_id'},$data);
					my $id = StorProc->insert_obj_id('profiles_host',\@values,'hostprofile_id');
					@values = ($id,$spid);
					my $result = StorProc->insert_obj('profile_host_profile_service',\@values);
					if ($result =~ /^Error/) { push @errors, $result }
					foreach my $hgid (@hostgroups) {
						@values = ($id,$hgid);
						my $result = StorProc->insert_obj('profile_hostgroup',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
					foreach my $hid (@parents) {
						@values = ($id,$hid);
						my $result = StorProc->insert_obj('profile_parent',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
					my %w = ('host_id' => $properties{'host_id'});
					my %u = ('hostprofile_id' => $id);
					my $result = StorProc->update_obj_where('hosts',\%u,\%w);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
		} else {
			push @errors, "Required Host profile name, service profile name";
		}
		if (@errors) {
			my $result = StorProc->delete_all('profiles_host','name',$host_profile);
			my $result = StorProc->delete_all('profiles_service','name',$service_profile);
			if ($result =~ /^Error/) { push @errors, $result }
			$step = 'save_as_profile';
		} else {
			$step = 'saved';
		}
	} elsif ($query->param('bail')) {
		$step = 'host_vitals';
		$name = undef;
############################################################################
# Back
#
	} elsif ($query->param('back')) {
		if ($step eq 'host_attribs') {
			$step = 'host_vitals';
			%properties = StorProc->fetch_one('stage_hosts','name',$name);
			my $result = StorProc->delete_all('stage_hosts','name',$name);
			if ($result =~ /^Error/) { push @errors, $result }
			$result = StorProc->delete_all('hosts','name',$name);
			if ($result =~ /^Error/) { push @errors, $result }
		} elsif ($step eq 'host_attribs2') {
			$step = 'host_attribs';
			my %values = ('info' => $step);
			my $result = StorProc->update_obj('stage_hosts','name',$name,\%values);
			if ($result =~ /^Error/) { push @errors, $result }
		} elsif ($step eq 'service_list') {
			$step = 'host_attribs2';
			my $result = StorProc->delete_all('stage_host_services','host',$name);
			if ($result =~ /^Error/) { push @errors, $result }
			my %values = ('info' => $step);
			$result = StorProc->update_obj('stage_hosts','name',$name,\%values);
			if ($result =~ /^Error/) { push @errors, $result }
		} elsif ($step eq 'service_detail') {
			my %values = ('user_acct' => $session_id,'status' => '3','type' => $view,'host' => $name);
			my %service_list = StorProc->fetch_list_hash_array('stage_host_services',\%values);
			my @services = ();
			foreach my $svc (keys %service_list) { unless ($svc =~ /HASH/) { push @services, $svc } }
			@services = sort @services;
			$service_next = pop @services; 
			if ($service_next) {
				$step = 'service_detail';
				my %where = ('host' => $name,'user_acct' => $session_id,'name' => $service_next);
				my %service_stage = StorProc->fetch_one_where('stage_host_services',\%where);
				my $sid = $service_stage{'service_id'};
				my $result = StorProc->delete_all('services','service_id',$service_stage{'service_id'});
				if ($result =~ /^Error/) { push @errors, $result }
				my %values = ('service_id' => '','status' => 'edit');
				my $result = StorProc->update_obj('stage_host_services','service_id',$service_stage{'service_id'},\%values);
				if ($result =~ /^Error/) { push @errors, $result }
			} else {
				$step = 'service_list';
				my @sids = StorProc->fetch_unique('stage_host_services','service_id','host',$name);
				foreach my $sid (@sids) {
					my $result = StorProc->delete_all('services','service_id',$sid);
					if ($result =~ /^Error/) { push @errors, $result }
				}
				my $result = StorProc->delete_all('stage_host_services','host',$name);
				if ($result =~ /^Error/) { push @errors, $result }
			}
		}
############################################################################
# Continue
#
	} elsif ($query->param('continue')) {
		$step = 'host_vitals';

############################################################################
# Cancel
#

	} elsif ($query->param('cancel')) {
		if ($query->param('yes')) {
			$step = 'host_vitals';
			%properties = StorProc->fetch_one('stage_hosts','name',$name);
			my $result = StorProc->delete_all('hosts','name',$name);
			if ($result =~ /^Error/) { push @errors, $result }
			my %where = ('name' => $properties{'name'}, 'user_acct' => $session_id);
			$result = StorProc->delete_one_where('stage_hosts',\%where);
			if ($result =~ /^Error/) { push @errors, $result }
			%where = ('host' => $properties{'name'}, 'user_acct' => $session_id);
			$result = StorProc->delete_one_where('stage_host_services',\%where);
			if ($result =~ /^Error/) { push @errors, $result }
		} elsif ($query->param('no')) {
			# nothing
		} else {
			foreach my $name ($query->param) {
				unless ($name eq 'task' || $name eq 'nocache' || $name eq 'parents' || $name eq 'hostgroups') { $hidden{$name} = $query->param($name) }
			}
			$form .= Forms->header($page_title,$session_id,$top_menu);
			$form .= Validation->dfv_profile_javascript();
			$form .= &$Instrument::show_trace_as_html_comment();
			$form .= Forms->form_top('New Host Wizard', Validation->dfv_onsubmit_javascript());
			my $message = qq(Are you sure you want to remove host $name?<br><br>);
			$form .= Forms->form_doc($message);
			my @parents = $query->param('parents');
			foreach my $parent (@parents) {
				my %hide = ('parents' => $parent);
				$form .= Forms->hidden(\%hide);
			}
			my @hostgroups = $query->param('hostgroups');
			foreach my $hostgroup (@hostgroups) {
				my %hide = ('hostgroups' => $hostgroup);
				$form .= Forms->hidden(\%hide);
			}
			$form .= Forms->hidden(\%hidden);
			$form .= Forms->form_bottom_buttons(\%yes,\%no,$tab++);
			$step = 'cancel';
		}

############################################################################
# Next
#
	} elsif ($query->param('next')) {
		if ($step eq 'host_vitals') {
			$submit = 'Add';
			my %data = parse_query('hosts','hosts');
			my $field_ck = check_fields();
			if ($field_ck == 0) {
				my $host_profile = $query->param('host_profile');
				my @values = ();
				$data{'status'} = 1;
				my @data_cols = split(/,/, $db_values{$obj});
				my $primary_key = '';
				push @values, $primary_key; 
				foreach my $val (@data_cols) {
					$val =~ s/^\s+|\s+$//;
					push @values, $data{$val};
				}
				my $id = StorProc->insert_obj_id('hosts',\@values,'host_id');
				if ($id =~ /^Error/) { push @errors, $id }
				%properties = StorProc->fetch_one('hosts','name',$name);
				%profile = StorProc->fetch_one('profiles_host','name',$host_profile);

				$hidden{'host_id'} = $id;
				@values = ($name,$session_id,'wizard_design','incomplete',$data{'alias'},$data{'address'},$data{'os'},$host_profile,'','host_attribs');
				my $result = StorProc->insert_obj('stage_hosts',\@values);
				if ($result =~ /^Error/) { push @errors, $result }
				if ($profile{'hostprofile_id'}) {
					my %w = ('hostprofile_id' => $profile{'hostprofile_id'});
					my @externals = StorProc->fetch_list_where('external_host_profile','external_id',\%w);
					foreach my $ext (@externals) {
						my %e = StorProc->fetch_one('externals','external_id',$ext);
						my @vals = ($ext,$id,$e{'display'});
						$result = StorProc->insert_obj('external_host',\@vals);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
				if ($profile{'hostprofile_id'}) {
					my @hosts = ($id);
					my @errs = StorProc->host_profile_apply($profile{'hostprofile_id'},\@hosts);
					if (@errs) { push (@errors,@errs) }
				}	
			}
			$step = 'host_attribs';
			if (@errors || $field_ck == 1) {
				$step = 'host_vitals';
			}
		} elsif ($step eq 'host_attribs') {
			$step = 'host_attribs2';
			my %values = ();
			my $template = $query->param('host_template');
			my %w = ('name' => $template);
			my %t = StorProc->fetch_one_where('host_templates',\%w);
			$values{'hosttemplate_id'} = $t{'hosttemplate_id'};
			my @parents = $query->param('parents');
			if (!$values{'hosttemplate_id'}) { 
				$required{'host_template'} = 1;
				push @errors, "Required: host template.";
			}
			unless (@errors) {
				my $result = StorProc->update_obj('hosts','host_id',$properties{'host_id'},\%values);
				if ($result =~ /^Error/) { push @errors, $result }
				%values = ('serviceprofile' => $hidden{'service_profile'},'info' => $step);
				$result = StorProc->update_obj('stage_hosts','name',$name,\%values);
				if ($result =~ /^Error/) { push @errors, $result }
				$result = StorProc->delete_all('host_parent','host_id',$properties{'host_id'});
				if ($result =~ /^Error/) { push @errors, $result }
				foreach my $parent (@parents) { 
					if (!$parent) { next }
					my %p = StorProc->fetch_one('hosts','name',$parent);
					my @values = ($properties{'host_id'},$p{'host_id'});
					my $result = StorProc->insert_obj('host_parent',\@values);
					if ($result =~ /^Error/) { push @errors, $result }	
				}
			}
			if (@errors) {
				$step = 'host_attribs';
			}
		} elsif ($step eq 'host_attribs2') {
			$step = 'service_list';
			my %values = ();
			my @hostgroups = $query->param('hostgroups');
			my $coords2d = $query->param('coords2d');
			my $coords3d = $query->param('coords3d');
			my $extended_info = $query->param('extended_info');
			my %w = ('name' => $extended_info);
			my %t = StorProc->fetch_one_where('extended_host_info_templates',\%w);
			$values{'hostextinfo_id'} = $t{'hostextinfo_id'};
			my $host_escalation = $query->param('host_escalation');
			%w = ('name' => $host_escalation,'type' => 'host');
			%t = StorProc->fetch_one_where('escalation_trees',\%w);
			$values{'host_escalation_id'} = $t{'tree_id'};
			my $service_escalation = $query->param('service_escalation');
			%w = ('name' => $service_escalation,'type' => 'service');
			%t = StorProc->fetch_one_where('escalation_trees',\%w);
			$values{'service_escalation_id'} = $t{'tree_id'};
			$hidden{'service_profile'} = $query->param('service_profile');
			unless (@errors) {
				my $result = StorProc->update_obj('hosts','host_id',$properties{'host_id'},\%values);
				if ($result =~ /^Error/) { push @errors, $result }
				%values = ('serviceprofile' => $hidden{'service_profile'},'info' => $step);
				$result = StorProc->update_obj('stage_hosts','name',$name,\%values);
				if ($result =~ /^Error/) { push @errors, $result }
				$result = StorProc->delete_all('hostgroup_host','host_id',$properties{'host_id'});
				if ($result =~ /^Error/) { push @errors, $result }
				foreach my $hg (@hostgroups) { 
					if (!$hg) { next }
					my %h = StorProc->fetch_one('hostgroups','name',$hg);
					my @values = ($h{'hostgroup_id'},$properties{'host_id'});
					my $result = StorProc->insert_obj('hostgroup_host',\@values);
					if ($result =~ /^Error/) { push @errors, $result }	
				}
				if ($coords2d || $coords3d) { 
					$result = StorProc->delete_all('extended_info_coords','host_id',$properties{'host_id'});
					if ($result =~ /^Error/) { push @errors, $result }
					my $data = "<?xml version=\"1.0\" ?>\n<data>";
					if ($coords2d) { $data .= "\n  <prop name=\"2d_coords\"><![CDATA[$coords2d]]>\n  </prop>" }
					if ($coords3d) { $data .= "\n  <prop name=\"3d_coords\"><![CDATA[$coords3d]]>\n  </prop>" }
					$data .= "\n</data>";
					my @vals = ($properties{'host_id'},$data);
					$result = StorProc->insert_obj('extended_info_coords',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }	
				}
			}
			if (@errors) {
				$step = 'host_attribs2';
			}
		} elsif ($step eq 'service_list') {
			my $result = StorProc->delete_all('services','host_id',$properties{'host_id'});
			if ($result =~ /^Error/) { push @errors, $result }
			$result = StorProc->delete_all('stage_host_services','host',$name);
			if ($result =~ /^Error/) { push @errors, $result }
			foreach my $service ($query->param) {
				if ($query->param($service) eq 'add') {
					my %s = StorProc->fetch_one('service_names','name',$service);
					my @values = ('',$properties{'host_id'},$s{'servicename_id'},$s{'template'},$s{'extinfo'},$s{'escalation'},'1',$s{'check_command'},$s{'command_line'},'');
					my $id = StorProc->insert_obj_id('services',\@values,'service_id');
					if ($id =~ /^Error/) { push @errors, $id }	
					@values = ($service,$session_id,$name,$view,'1',$id);
					$result = StorProc->insert_obj('stage_host_services',\@values);
					if ($result =~ /^Error/) { push @errors, $result }	
					my %w = ('servicename_id' => $s{'servicename_id'});
					my @externals = StorProc->fetch_list_where('external_service_names','external_id',\%w);
					foreach my $ext (@externals) {
						my %e = StorProc->fetch_one('externals','external_id',$ext);
						my @vals = ($ext,$properties{'host_id'},$id,$e{'display'});
						$result = StorProc->insert_obj('external_service',\@vals);
						if ($result =~ /^Error/) { push @errors, $result }
					}
					my @errs = StorProc->apply_service_overrides($id,$s{'servicename_id'});
					if (@errs) { push (@errors,@errs) }
				} elsif ($query->param($service) eq 'edit') {
					my @values = ($service,$session_id,$name,$view,'2','');
					my $result = StorProc->insert_obj('stage_host_services',\@values);
					if ($result =~ /^Error/) { push @errors, $result }	
				}
			}
			my $result = StorProc->delete_all('serviceprofile_host','host_id',$properties{'host_id'});
			if ($result =~ /^Error/) { push @errors, $result }
			my %profiles_name = StorProc->get_table_objects('profiles_service');
			my @profiles = $query->param('profiles');
			foreach my $profile (@profiles) {
				if ($profiles_name{$profile}) {
					my @values = ($profiles_name{$profile},$properties{'host_id'});
					my $result = StorProc->insert_obj('serviceprofile_host',\@values);
					if ($result =~ /^Error/) { push @errors, $result }	
				}
			}
			my %values = ('user_acct' => $session_id,'status' => '2','type' => $view,'host' => $name);
			my %service_list = StorProc->fetch_list_hash_array('stage_host_services',\%values);
			my @services;
			foreach my $svc (keys %service_list) { unless ($svc =~ /HASH/) { push @services, $svc } }
			@services = sort { $b cmp $a } @services;
			$service_next = pop @services;
			if ($service_next) {
				$step = 'service_detail';
			} else {
				$step = 'completed';
				my $result = StorProc->delete_all('stage_hosts','name',$name);
				if ($result =~ /^Error/) { push @errors, $result }
				my $result = StorProc->delete_all('stage_host_services','host',$name);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			if (@errors) {
				$step = 'service_list';
			}
		} elsif ($step eq 'service_detail') {
			my %s = StorProc->fetch_one('service_names','name',$service_detail{'service'});
			my %t = StorProc->fetch_one('service_templates','name',$service_detail{'template'});
			my %c = StorProc->fetch_one('commands','name',$service_detail{'command'});
			my $command_line = $query->param('command_line');
			if ($service_detail{'inherit'}) {
				delete $c{'command_id'};
				delete $service_detail{'command_line'};
			}
			my %x = StorProc->fetch_one('extended_service_info_templates','name',$service_detail{'ext_info'});
			my %e = StorProc->fetch_one('escalation_trees','name',$service_detail{'escalation'});
			my @values = ('',$properties{'host_id'},$s{'servicename_id'},$t{'servicetemplate_id'},$x{'serviceextinfo_id'},$e{'tree_id'},'1',$c{'command_id'},$service_detail{'command_line'},'');
			my $id = StorProc->insert_obj_id('services',\@values,'service_id');
			if ($id =~ /^Error/) { push @errors, $id }	
			my %where = ('name' => $service_detail{'service'},'user_acct' => $session_id,'host' => $name);
			my %values = ('status' => '3','service_id' => $id);
			my $result = StorProc->update_obj_where('stage_host_services',\%values,\%where);
			if ($result =~ /^Error/) { push @errors, $result }	
			my %w = ('servicename_id' => $s{'servicename_id'});
			my @externals = StorProc->fetch_list_where('external_service_names','external_id',\%w);
			foreach my $ext (@externals) {
				my %e = StorProc->fetch_one('externals','external_id',$ext);
				my @vals = ($ext,$properties{'host_id'},$id,$e{'display'});
				$result = StorProc->insert_obj('external_service',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			my @errs = StorProc->apply_service_overrides($id,$s{'servicename_id'});
			if (@errs) { push (@errors,@errs) }
			if (@errors) {
				$step = 'service_detail';
			} else {
				delete $service_detail{'service'};
				delete $service_detail{'template'};
				delete $service_detail{'command'};
				delete $service_detail{'command_line'};
				delete $service_detail{'use_template_command'};
				delete $service_detail{'ext_info'};
				delete $service_detail{'escalation'};
				delete $service_detail{'dependency'};
				delete $service_detail{'command_save'};
				my %values = ('user_acct' => $session_id,'status' => '2','type' => $view,'host' => $name);
				my %service_list = StorProc->fetch_list_hash_array('stage_host_services',\%values);
				my @services;
				foreach my $svc (keys %service_list) { unless ($svc =~ /HASH/) { push @services, $svc } }
				@services = sort { $b cmp $a } @services;
				$service_next = pop @services;
				if ($service_next) {
					$step = 'service_detail';
				} else {
					$step = 'completed';
					my $result = StorProc->delete_all('stage_hosts','name',$name);
					if ($result =~ /^Error/) { push @errors, $result }
					$result = StorProc->delete_all('stage_host_services','host',$name);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
		}
	} elsif ($query->param('add_profile') || $query->param('add_service')) {
		$step = 'service_list';
	}
	if ($step eq 'completed') {
		# insert service dependencies
		my $result = StorProc->add_dependencies($properties{'host_id'});
		if ($result =~ /^Error/i) { push @errors, $result } 	
	}

############################################################################
# Pages
#
	$hidden{'step'} = $step;
	if ($step eq 'host_vitals') {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		my %docs = Doc->host_wizard_vitals();
		delete $hidden{'name'};
		delete $hidden{'host'};
		$form .= Validation->dfv_profile_javascript();
		$form .= &$Instrument::show_trace_as_html_comment();
		$form .= Forms->form_top('New Host Wizard', Validation->dfv_onsubmit_javascript());
		if (!$properties{'host_profile'}) { $properties{'host_profile'} = $query->param('host_profile') }
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->form_doc('Host Vitals');
		$form .= Forms->text_box('Name:','name',$properties{'name'},$textsize{'name'},$required{'name'});
		$form .= Forms->text_box('Alias:','alias',$properties{'alias'},$textsize{'alias'},$required{'alias'},$docs{'alias'});
		$form .= Forms->text_box('Address:','address',$properties{'address'},$textsize{'address'},$required{'address'},$docs{'address'});
		my @profiles =  StorProc->fetch_list('profiles_host','name'); 
		$form .= Forms->list_box('Host profile:','host_profile',\@profiles,$properties{'host_profile'},$required{'host_profile'},$docs{'host_profile'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%next,\%cancel,$tab++);
	} elsif ($step eq 'host_attribs') {	
		$form .= Forms->header($page_title,$session_id,$top_menu);
		my %docs = Doc->host_wizard_attribs_1();
		my %w = ('hosttemplate_id' => $properties{'hosttemplate_id'});
		my %t = StorProc->fetch_one_where('host_templates',\%w);
		my $template = $t{'name'};
		unless ($template) {
			my %w = ('hosttemplate_id' => $profile{'host_template_id'});
			my %t = StorProc->fetch_one_where('host_templates',\%w);
			$template = $t{'name'};
		}
		my @parents = StorProc->get_host_parent($properties{'host_id'});
		unless (@parents) {
			@parents = StorProc->get_profile_parent($profile{'hostprofile_id'});
		}
		$form .= Validation->dfv_profile_javascript();
		$form .= &$Instrument::show_trace_as_html_comment();
		$form .= Forms->form_top('New Host Wizard', Validation->dfv_onsubmit_javascript('selIt()'));
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->form_doc('Host Properties 1');
		$form .= Forms->display_hidden('Name:','name',$name);
		my @members = StorProc->fetch_list('host_templates','name'); 
		$form .= Forms->list_box('Host template:','host_template',\@members,$template,$required{'host_template'},$docs{'host_template'});
		my @nonmembers = StorProc->fetch_list('hosts','name');
		$form .= Forms->members('Parents:','parents',\@parents,\@nonmembers,'','',$docs{'parents'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%back,\%next,\%cancel,$tab++);
	} elsif ($step eq 'host_attribs2') {	
		$form .= Forms->header($page_title,$session_id,$top_menu);
		my %docs = Doc->host_wizard_attribs_2();
		my $coords2d = $query->param('coords2d');
		my $coords3d = $query->param('coords3d');
		my $extended_info = $query->param('extended_info');
		unless ($extended_info) {
			my %w = ('hostextinfo_id' => $properties{'hostextinfo_id'});
			my %t = StorProc->fetch_one_where('extended_host_info_templates',\%w);
			$extended_info = $t{'name'};
			my %coords = StorProc->fetch_one('extended_info_coords','host_id',$properties{'host_id'});
			unless ($coords2d) { $coords2d = $coords{'2d_coords'} }
			unless ($coords3d) { $coords3d = $coords{'3d_coords'} }
		}
		unless ($extended_info) {
			my %w = ('hostextinfo_id' => $profile{'host_extinfo_id'});
			my %t = StorProc->fetch_one_where('extended_host_info_templates',\%w);
			$extended_info = $t{'name'};
			unless ($coords2d) { $coords2d = $t{'2d_coords'} }
			unless ($coords3d) { $coords3d = $t{'3d_coords'} }
		}
		my $host_escalation = $query->param('host_escalation');
		unless ($host_escalation) {
			my %w = ('tree_id' => $properties{'host_escalation_id'},'type' => 'host');
			my %t = StorProc->fetch_one_where('escalation_trees',\%w);
			$host_escalation = $t{'name'};
		}
		unless ($host_escalation) {
			my %w = ('tree_id' => $profile{'host_escalation_id'},'type' => 'host');
			my %t = StorProc->fetch_one_where('escalation_trees',\%w);
			$host_escalation = $t{'name'};
		}
		my $service_escalation = $query->param('service_escalation');
		unless ($service_escalation) {
			my %w = ('tree_id' => $properties{'service_escalation_id'},'type' => 'service');
			my %t = StorProc->fetch_one_where('escalation_trees',\%w);
			$service_escalation = $t{'name'};
		}
		unless ($service_escalation) {
			my %w = ('tree_id' => $profile{'service_escalation_id'},'type' => 'service');
			my %t = StorProc->fetch_one_where('escalation_trees',\%w);
			$service_escalation = $t{'name'};
		}
		my @hostgroups = $query->param('hostgroups');
		unless (@hostgroups) {
			@hostgroups = StorProc->get_hostgroup_host($name);
		}
		unless (@hostgroups) {
			@hostgroups = StorProc->get_profile_hostgroup($profile{'hostprofile_id'});
		}
		$form .= Validation->dfv_profile_javascript();
		$form .= &$Instrument::show_trace_as_html_comment();
		$form .= Forms->form_top('New Host Wizard', Validation->dfv_onsubmit_javascript('selIt()'));
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->form_doc('Host Properties 2');
		$form .= Forms->display_hidden('Name:','name',$name);
		my @nonmembers = StorProc->fetch_list('hostgroups','name'); 
		$form .= Forms->members('Hostgroups:','hostgroups',\@hostgroups,\@nonmembers,'','',$docs{'hostgroups'});
		my @members = StorProc->fetch_list('extended_host_info_templates','name'); 
		$form .= Forms->list_box('Extended host info:','extended_info',\@members,$extended_info,'',$docs{'extinfo'});
		$form .= Forms->text_box('2d status map coords:','coords2d',$coords2d,'10','',$docs{'coords2d'});
		$form .= Forms->text_box('3d status map coords:','coords3d',$coords3d,'10','',$docs{'coords3d'});
		my %where = ('type' => 'host');
		@members = StorProc->fetch_list_where('escalation_trees','name',\%where); 
		$form .= Forms->list_box('Host escalation tree:','host_escalation',\@members,$host_escalation,'',$docs{'host_escalation_tree'});
		if ($host_escalation) {
			my ($ranks, $templates) = StorProc->get_tree_detail($host_escalation);
			my %ranks = %{$ranks};
			my %templates = %{$templates};
			$form .= Forms->escalation_tree(\%ranks,\%templates,'escalations');
		}
		%where = ('type' => 'service');
		@members = StorProc->fetch_list_where('escalation_trees','name',\%where); 
		$form .= Forms->list_box('Service escalation tree:','service_escalation',\@members,$service_escalation,'',$docs{'service_escalation_tree'});
		if ($service_escalation) {
			my ($ranks, $templates) = StorProc->get_tree_detail($service_escalation);
			my %ranks = %{$ranks};
			my %templates = %{$templates};
			$form .= Forms->escalation_tree(\%ranks,\%templates,'escalations');
		}
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%back,\%next,\%cancel,$tab++);
	} elsif ($step eq 'service_list') {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		my %docs = Doc->host_wizard_select_services();
		$form .= Validation->dfv_profile_javascript();
		$form .= &$Instrument::show_trace_as_html_comment();
		$form .= Forms->form_top('New Host Wizard', Validation->dfv_onsubmit_javascript());
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->form_doc('Select Servcies');
		$form .= Forms->display_hidden('Host name:','name',$name);
		$form .= Forms->form_doc($docs{'services'});
		my @profiles = ();
		my $got_profile = 0;
		my %selected = ();
		if ($query->param('back')) {
			my %where = ('host' => $name,'user_acct' => $session_id);
			my @services = StorProc->fetch_list_where('stage_host_services','name',\%where);			
			foreach my $service (@services) { $selected{$service} = 'add' }
		} else {
			foreach my $service ($query->param) {		
				$service = uri_unescape($service);
				if ($query->param($service) eq 'add') { 
					$selected{$service} = 'add';
				} elsif ($query->param($service) eq 'edit') { 
					$selected{$service} = 'edit';
				} elsif ($query->param($service) eq 'discard') { 
					$selected{$service} = 'discard';
				}
			}	
		}
		my %sp_selected = ();
		my $remove_profile = undef;
		my @query_profiles = $query->param('profiles');
		foreach my $profile (@query_profiles) {
			$got_profile = 1;
			if ($query->param("remove_$profile")) {
				$profile = uri_unescape($profile);
				$remove_profile = $profile;
			} elsif ($profile) {
				$profile = uri_unescape($profile);
				push @profiles, $profile; 
			}
		}
		unless ($got_profile) {
			my %sps = StorProc->get_host_profile_service_profiles($properties{'hostprofile_id'});
			foreach my $sp (sort keys %sps) { push @profiles, $sp }
		}
		$form .= Forms->profile_list($session_id,$name,\@profiles,$tab++);
		my @query_services = $query->param('services');
		foreach my $service (@query_services) {
			if ($service) { $selected{$service} = 'add' }
		}
		if ($remove_profile) {
			my %sp = StorProc->fetch_one('profiles_service','name',$remove_profile);
			my %svs = StorProc->get_service_profile_services($sp{'serviceprofile_id'});
			foreach my $service (keys %svs) { delete $selected{$service} }
		}	
		my %services = ();
		foreach my $profile (@profiles) {
			$sp_selected{$profile} = 1;
			my %sp = StorProc->fetch_one('profiles_service','name',$profile);
			my %svs = StorProc->get_service_profile_services($sp{'serviceprofile_id'});
			foreach my $service (keys %svs) { 
				$services{$service} = $svs{$service};
				unless (defined $selected{$service}) { $selected{$service} = 'add' }
			}
		}
		foreach my $service (keys %selected) {
			unless (defined $services{$service}) {
				my %svc = StorProc->get_service_detail($service);
				$services{$service} = $svc{$service};
			}
		}
		$form .= Forms->service_select(\%services,\%selected);
		my @service_profiles = StorProc->fetch_list('profiles_service','name');
		my @profile_list = ();
		foreach my $s (@service_profiles) { unless ($sp_selected{$s}) { push @profile_list, $s } }
		@profile_list = sort { $a <=> $b } @profile_list;
		$form .= Forms->add_service_profile(\@profile_list);
		
		my @service_names = StorProc->fetch_list('service_names','name');
		my @service_list = ();
		foreach my $s (@service_names) { unless ($selected{$s}) { push @service_list, $s } }
		@service_list = sort { $a <=> $b } @service_list;
		$form .= Forms->add_service(\@service_list);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%back,\%next,\%cancel,$tab++);
	} elsif ($step eq 'service_detail') {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		my %docs = Doc->host_wizard_service_detail();
		$hidden{'file'} = $query->param('file');
		my $service = $service_next;
		unless ($service) { $service = $service_detail{'service'} }
		my %svc = StorProc->get_service_detail($service);
		my %service = ();
		foreach my $key (keys %{$svc{$service_next}}) {
			if ($key eq 'command') {
				my @cmd = split (/!/, $svc{$service_next}{$key});
				$service{'check_command'} = $cmd[0];
				$service{'command_line'} = $svc{$service_next}{$key};
			}
			$service{$key} = $svc{$service_next}{$key};
		}
		$form .= Validation->dfv_profile_javascript();
		$form .= &$Instrument::show_trace_as_html_comment();
		$form .= Forms->form_top('New Host Wizard', Validation->dfv_onsubmit_javascript());
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->form_doc('Service Detail');
		$form .= Forms->display_hidden('Service:','service',$service);

#
# Template
#
		my $template = $service_detail{'template'};
		unless ($template) {
			$template = $service{'template'};
		}
		my @members = StorProc->fetch_list('service_templates','name'); 
		$form .= Forms->list_box_submit('Service template:','template',\@members,$template,'',$docs{'template'});
		my %template = StorProc->fetch_one('service_templates','name',$template);

#
# Service check
#

		my $message = undef;
		my $inherit = 0;
		$inherit = $service_detail{'inherit'};
		my %cmd = StorProc->fetch_one('commands','name', $service{'check_command'});
		my $command = $cmd{'name'};
		my $command_save = $cmd{'name'};
		my $command_line = $service{'command_line'};
		if ($service_detail{'command'}) { $command = $service_detail{'command'} }
		if ($service_detail{'command_save'}) { $command_save = $service_detail{'command_save'} }
		if ($service_detail{'command_line'}) { $command_line = $service_detail{'command_line'} }
		unless ($command eq $command_save) {
			%cmd = StorProc->fetch_one('commands','name',$command);
			$command_line = undef;
		}
		if ($inherit or !$command) {
			%cmd = StorProc->fetch_one('commands','command_id',$template{'check_command'});
			if ($cmd{'name'}) {
				$command = $cmd{'name'};
				$command_line = $template{'command_line'};
				$inherit = 1;
			} else {
				my $got_command = 0;
				my $stid = $template{'parent_id'};
				until ($got_command) {
					my %t = StorProc->fetch_one('service_templates','servicetemplate_id',$stid);
					if ($t{'check_command'}) {
						$got_command = 1;
						%cmd = StorProc->fetch_one('commands','command_id',$t{'check_command'});
						$command = $cmd{'name'};
						$command_line = $t{'command_line'};
						$got_command = 1;
					} else {
						if ($t{'parent_id'}) {
							$stid = $t{'parent_id'};
						} else {
							$got_command = 1;
							$message = ('Note: a parent template does not have a check command defined.');
							$required{'check_command'} = 1;
							$command = undef;
							$command_line = undef;
						}
					}
				}
			}
		}
		%cmd = StorProc->fetch_one('commands','name',$command);
		my $arg_string = $command_line;
		$arg_string =~ s/$command!//;
		my $usage = $command;
		my @args = split(/ARG/i,$cmd{'command_line'});
		my $args = undef;
		if ($args[1]) {
			$usage .= "!";
			my $cnt = 1;
			pop @args;
			foreach (@args) { 
				if ($cmd{'command_line'} =~ /ARG$cnt/i) { $args .= "ARG$cnt!" }
				$cnt++;
			}
			chop $args;
			$usage .= $args;
			unless ($command_line =~ /$command/) {
				$command_line = "$command!$args";
				$arg_string = $args;
			}
		}
		$form .= Forms->checkbox_override('Inherit check from template','inherit',$inherit,$docs{'override'});
		my %where = ('type' => 'check');
		my @commands = StorProc->fetch_list_where('commands','name',\%where);
		$form .= Forms->list_box_submit('Check command:','command',\@commands,$command,$required{'check_command'});
		$form .= Forms->display_hidden('Command definition:','',$cmd{'command_line'});
		$form .= Forms->display_hidden('Usage:','',$usage);
		$form .= Forms->text_area('Command line:','command_line',$command_line,'3','80','',$docs{'command_line'});
		unless ($host) { $host = $name }
		$form .= Forms->test_service_check($test_results,$host);
		$hidden{'command_save'} = $command;

#
# dependency
#
		my $dependency = $service_detail{'dependency'};
		unless ($dependency) {
			$dependency = $service{'dependency'};
		}
		@members = StorProc->fetch_list('service_dependency_templates','name'); 
		$form .= Forms->list_box('Service dependency:','dependency',\@members,$dependency,'',$docs{'dependency'});
		my $ext_info = $service_detail{'ext_info'};
		unless ($ext_info) {
			$ext_info = $service{'extinfo'};
		}
#
# ext_info
#
		my @members = StorProc->fetch_list('extended_service_info_templates','name'); 
		$form .= Forms->list_box('Extended info:','ext_info',\@members,$ext_info,'',$docs{'extinfo'});
#
# escalation
#
		my $escalation = $service_detail{'escalation'};
		unless ($escalation) {
			$escalation = $service{'escalation'};
		}
		my %where = ('type' => 'service');
		@members = StorProc->fetch_list_where('escalation_trees','name',\%where); 
		$form .= Forms->list_box_submit('Escalation tree:','escalation',\@members,$escalation,'',$docs{'escalation'});
		if ($escalation) {
			my ($ranks, $templates) = StorProc->get_tree_detail($escalation);
			my %ranks = %{$ranks};
			my %templates = %{$templates};
			$form .= Forms->escalation_tree(\%ranks,\%templates,'service_detail');
		}
		my @profiles = $query->param('profiles');
		foreach my $profile (@profiles) {
			my %prof = ('profiles' => $profile);
			$form .= Forms->hidden(\%prof);
		}
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%back,\%next,\%cancel,$tab++);

	} elsif ($step eq 'completed') {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Validation->dfv_profile_javascript();
		$form .= &$Instrument::show_trace_as_html_comment();
		$form .= Forms->form_top('New Host Wizard', Validation->dfv_onsubmit_javascript());
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Added host:','name',$name);
		my @services = StorProc->get_host_services($properties{'host_id'});
		$form .= Forms->form_message('Services:',\@services,'row1');
		my %save_to_profile = ('name' => 'save_as_profile','value' => 'Save As Profile');
		$form .= Forms->hidden(\%hidden);		
		$form .= Forms->form_bottom_buttons(\%save_to_profile,\%continue,$tab++);
	} elsif ($step eq 'save_as_profile') {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Validation->dfv_profile_javascript();
		$form .= &$Instrument::show_trace_as_html_comment();
		$form .= Forms->form_top('New Host Wizard', Validation->dfv_onsubmit_javascript());
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Host name:','name',$name);
		$form .= Forms->text_box('Host profile name:','host_profile',$name,'50');
		$form .= Forms->text_box('Service profile name:','service_profile',$name,'50');
		my %bail = ('name' => 'bail','value' => 'Cancel');
		$form .= Forms->hidden(\%hidden);		
		$form .= Forms->form_bottom_buttons(\%save,\%bail,$tab++);
	} elsif ($step eq 'saved') {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Validation->dfv_profile_javascript();
		$form .= &$Instrument::show_trace_as_html_comment();
		$form .= Forms->form_top('New Host Wizard', Validation->dfv_onsubmit_javascript());
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Profile name:','name',$name);
		$form .= Forms->hidden(\%hidden);		
		$form .= Forms->form_bottom_buttons(\%continue,$tab++);
	}
	return $form;
}

#
############################################################################
# Design
#

sub design() {
	my $page = undef;
	my $got_form = undef;
	my $title = undef;
	my @t_parse = split(/_/, $obj);
	my %required = ();
	
	foreach (@t_parse) { $title .= "\u$_ " }
	if ($query->param('cancel') || $query->param('close') || $query->param('continue')) { 
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$got_form = 1;
	} else {
#
# Contacts
#
		if ($obj eq 'contacts') {
			if ($query->param('add')) {
				my $name = $query->param('name');
				$name =~ s/^\s+|\s+$//;
				$hidden{'name'} = $name;
				my %data = parse_query('contacts','contacts');
				$properties{'template'} = $query->param('template');
				my $field_ck = check_fields();
				if ($field_ck == 0) {
					my %t = StorProc->fetch_one('contact_templates','name',$properties{'template'});
					my @vals = ('',$name,$data{'alias'},$data{'email'},$data{'pager'},$t{'contacttemplate_id'},'1','');
					my $id = StorProc->insert_obj_id('contacts',\@vals,'contact_id');
					if ($id =~ /^Error/) { push @errors, $id }
					unless (@errors) {		
						my @mems = $query->param('contactgroup');
						foreach (@mems) {
							my %cg = StorProc->fetch_one('contactgroups','name',$_);
							my @vals = ($cg{'contactgroup_id'},$id);
							my $result = StorProc->insert_obj('contactgroup_contact',\@vals);
							if ($result =~ /^Error/) { push @errors, $result }
						}
						unless (@errors) {
							my %where = ('contact_id' => $id);
							my $result = StorProc->delete_one_where('contact_overrides',\%where);
							if ($result =~ /^Error/) { push @errors, $result }
							my %values = ();
							my $got_override = undef;
							unless ($query->param('host_notification_period_override')) {
								my $np = $query->param('host_notification_period');
								my %np = StorProc->fetch_one('time_periods','name',$np);
								$values{'host_notification_period'} = $np{'timeperiod_id'};
								$got_override = 1;
							}
							unless ($query->param('service_notification_period_override')) {
								my $np = $query->param('service_notification_period');
								my %np = StorProc->fetch_one('time_periods','name',$np);
								my %np = StorProc->fetch_one('time_periods','name',$np);
								$values{'service_notification_period'} = $np{'timeperiod_id'};
								$got_override = 1;
							}
							my $data = undef;
							unless ($query->param('host_notification_options_override')) {
								my @no = $query->param('host_notification_options');
								my $str = undef;
								foreach (@no) { $str .= "$_," }
								chop $str;
								$data .= "\n  <prop name=\"host_notification_options\"><![CDATA[$str]]>\n  </prop>";
								$got_override = 1;
							}
							unless ($query->param('service_notification_options_override')) {
								my @no = $query->param('service_notification_options');
								my $str = undef;
								foreach (@no) { $str .= "$_," }
								chop $str;
								$data .= "\n  <prop name=\"service_notification_options\"><![CDATA[$str]]>\n  </prop>";
								$got_override = 1;
							}
							if ($data) {
								$values{'data'} = "<?xml version=\"1.0\" ?>\n<data>".$data."\n</data>";
							}
							if ($got_override) {
								my @vals = ($id,$values{'host_notification_period'},$values{'service_notification_period'},$values{'data'});
								$result = StorProc->insert_obj('contact_overrides',\@vals);
								if ($result =~ /^Error/) { push @errors, $result }					
							}
							my %where = ('contact_id' => $id);
							my $result = StorProc->delete_one_where('contact_command_overrides',\%where);
							if ($result =~ /^Error/) { push @errors, $result }
							unless ($query->param('host_notification_commands_override')) {
								my @mems = $query->param('host_notification_commands');
								foreach (@mems) {
									my %c = StorProc->fetch_one('commands','name',$_);
									my @vals = ($id,'host',$c{'command_id'});
									$result = StorProc->insert_obj('contact_command_overrides',\@vals);
									if ($result =~ /^Error/) { push @errors, $result }					
								}
							}
							unless ($query->param('service_notification_commands_override')) {
								my @mems = $query->param('service_notification_commands');
								foreach (@mems) {
									my %c = StorProc->fetch_one('commands','name',$_);
									my @vals = ($id,'service',$c{'command_id'});
									$result = StorProc->insert_obj('contact_command_overrides',\@vals);
									if ($result =~ /^Error/) { push @errors, $result }					
								}
							}
							unless (@errors) {
								$page .= Forms->header($page_title,$session_id,$top_menu);
								my $message = "Contact $name added.";
								$page .= Forms->success('Added:',$message,'continue',\%hidden);
								$got_form = 1;
							}
						}
					}
				}
			}
			unless ($got_form) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Contact Properties','onsubmit="selIt();"');
				$page .= build_contact();
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);
				$got_form = 1;
			}

#
# Externals
#
		} elsif ($obj eq 'externals') {
			$page .= externals();
			$got_form = 1;

#
# Other
#
		} elsif ($query->param('add')) {
			my $result = undef;
			$table = $obj;
			my %data = parse_query($table,$obj);
			my $field_ck = check_fields();
			if ($field_ck == 0) {
				my @values;
				unless ($obj =~ /host_dependencies/) { push @values, ''}
				$data{'name'} =~ s/^\s+|\s+$//;
				my @data_cols = split(/,/, $db_values{$table});
				foreach my $val (@data_cols) {
					if ($val eq 'comment') { 
						push @values, "# $obj $properties{'name'}";
					} else {
						push @values, $data{$val};
					}
				}
				my $id = StorProc->insert_obj_id($table,\@values,$obj_id{$table});
				if ($id =~ /^Error/) { 
					if ($id =~ /duplicate/i) {
						$id =~ s/ies/y/;
						my $ltitle = $obj;
						$ltitle =~ s/_/ /g;
						$ltitle =~ s/ies$/y/;
						push @errors, "Error: \u$ltitle already exists";
					} else {
						push @errors, $id; 		
					}
				} else {
					if ($data{'members'}) {
						my @mems = split(/,/, $data{'members'});
						foreach (@mems) {
							my %m = StorProc->fetch_one('hosts','name',$_);
							my @vals = ($id,$m{'host_id'});
							$result = StorProc->insert_obj('hostgroup_host',\@vals);
							if ($result =~ /^Error/) { push @errors, $result }
						}
					}

					if ($data{'contact'}) {
						my @mems = split(/,/, $data{'contact'});
						foreach (@mems) {
							my %c = StorProc->fetch_one('contacts','name',$_);
							my @vals = ($id,$c{'contact_id'});
							$result = StorProc->insert_obj('contactgroup_contact',\@vals);
							if ($result =~ /^Error/) { push @errors, $result }
						}
					}

					if ($data{'contactgroup'}) {
						my %o = StorProc->fetch_one($table,'name',$data{'name'});
						my @mems = split(/,/, $data{'contactgroup'});
						foreach (@mems) {
							my %cg = StorProc->fetch_one('contactgroups','name',$_);

							my $table_name = $table_by_object{$obj};
#							my @vals = ($cg{'contactgroup_id'},$obj,$id);
							my @vals = ($cg{'contactgroup_id'}, $id);
#							$result = StorProc->insert_obj('contactgroup_assign',\@vals);
							$result = StorProc->insert_obj($table_name,\@vals);

							if ($result =~ /^Error/) { push @errors, $result }
						}
					}

					if ($data{'host_notification_commands'}) {
						my %o = StorProc->fetch_one($table,'name',$data{'name'});
						my %w = ('contacttemplate_id' => $o{'contacttemplate_id'},'type' => 'host');
						my $result = StorProc->delete_one_where('contact_command',\%w);
						my @c = split(/,/, $data{'host_notification_commands'});		
						foreach (@c) {
							my @vals = ($o{'contacttemplate_id'},'host',$_);
							my $result = StorProc->insert_obj('contact_command',\@vals);
							if ($result =~ /Error/) { push @errors, $result }
						}	
					}

					if ($data{'service_notification_commands'}) {
						my %o = StorProc->fetch_one($table,'name',$data{'name'});
						my %w = ('contacttemplate_id' => $o{'contacttemplate_id'},'type' => 'service');
						my $result = StorProc->delete_one_where('contact_command',\%w);
						my @c = split(/,/, $data{'service_notification_commands'});		
						foreach (@c) {
							my @vals = ($o{'contacttemplate_id'},'service',$_);
							my $result = StorProc->insert_obj('contact_command',\@vals);
							if ($result =~ /Error/) { push @errors, $result }
						}	
					}
				}
				unless (@errors) {
					$page .= Forms->header($page_title,$session_id,$top_menu);
					my $message = "$data{'name'} has been saved.";
					$hidden{'name'} = undef;
					$hidden{'task'} = undef;
					$page .= Forms->success('Added',$message,'continue',\%hidden);
					$got_form = 1;
				} else {
					$page .= Forms->header($page_title,$session_id,$top_menu);
					$page .= build_form('');
					$got_form = 1;	
				}
			} elsif ($field_ck == 1) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= build_form('');
				$got_form = 1;
			}
		}
		if ($query->param('bail')) {
			$got_form = 0;
		}
		unless ($got_form) {
			$page .= Forms->header($page_title,$session_id,$top_menu);
			my $title = undef;
			my $l_title = undef;
			my @t_parse = split(/_/, $obj);
			foreach (@t_parse) { 
				$l_title .= "$_ ";
				$title .= "\u$_ ";
			}
			$l_title =~ s/s\s$//;
			$l_title =~ s/ie$/y/;
			my $template = $query->param('source');
			if ($obj eq 'contacts' || $task || $template) {
				if (!$template && $task =~ /copy|use/) {
					$page .= Forms->form_top('Select','');
					my @templates = StorProc->fetch_list($table,'name'); 
					$page .= Forms->list_box("\u$l_title:",'source',\@templates);
					$hidden{'task'} = $task;
					$page .= Forms->hidden(\%hidden);
					$page .= Forms->form_bottom_buttons(\%next,\%cancel,$tab++);
				} else {
					$page .= build_form('');
				}
			} elsif ($obj eq 'contacts') {
				$page .= Forms->form_top('Select','');
				my @templates = StorProc->fetch_list('contact_templates','name'); 
				$page .= Forms->list_box('Contact template:','source',\@templates);
				$hidden{'task'} = 'use';
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%next,\%cancel,$tab++);
			}
		}
	}
	return $page;
}


#
# host_dependencies
#

sub host_dependencies() {
	my $got_form = 0;
	my $page = undef;
	my $dependent_host = $query->param('dependent_host');
	my $parent_host = $query->param('parent_host');
	unless ($dependent_host && $parent_host) {
		my $name = $query->param('name');
		my @dp = split(/::--::/, $name);
		$dependent_host = $dp[0];
		$parent_host = $dp[1];
	}
	my %d = StorProc->fetch_one('hosts','name',$dependent_host);
	my %p = StorProc->fetch_one('hosts','name',$parent_host);
	if ($query->param('cancel') || $query->param('continue')) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$got_form = 1;
	} elsif ($query->param('delete') or $query->param('confirm_delete')) {
		if ($query->param('confirm_delete')) {
			my %where = ('host_id' => $d{'host_id'},'parent_id' => $p{'host_id'});
			my $result = StorProc->delete_one_where('host_dependencies',\%where); 
			if ($result =~ /^Error/) { push @errors, $result }		
			unless (@errors) {
				my $message = "Host dependency $dependent_host - $parent_host.";
				$hidden{'name'} = undef;
				$page .= Forms->header($page_title,$session_id,$top_menu,'','1');
				$page .= Forms->success('Removed',$message,'continue',\%hidden);
				$got_form = 1;
			}
		} else {
			$hidden{'dependent_host'} = $dependent_host;
			$hidden{'parent_host'} = $parent_host;
			$page .= Forms->header($page_title,$session_id,$top_menu);
			my $message = qq(Are you sure you want to remove the host dependency for $dependent_host and $parent_host?);
			$page .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden);
			$got_form = 1;
		}
	} elsif ($query->param('save') || $query->param('add')) {
		my @execution = $query->param('execution_failure_criteria');
		my $efc = undef;
		foreach my $n (@execution) {
			$efc .= "$n,";
		}
		chop $efc;
		my $data = qq(
  <prop name="execution_failure_criteria"><![CDATA[$efc]]>
  </prop>);
		my @notify = $query->param('notification_failure_criteria');
		my $nfc = undef;
		foreach my $n (@notify) {
			$nfc .= "$n,";
		}
		chop $nfc;
		$data .= qq(
  <prop name="notification_failure_criteria"><![CDATA[$nfc]]>
  </prop>);
		my $inherits_parent = $query->param('inherits_parent');
		if ($inherits_parent) {
			$data .= qq(
  <prop name="inherits_parent"><![CDATA[$inherits_parent]]>
  </prop>);
		}
		$data = "<?xml version=\"1.0\" ?>\n<data>$data\n</data>";
		if ($notify[0] && $p{'host_id'} && $d{'host_id'}) {
			if ($query->param('save')) {		
#				my %dep_hash = StorProc->get_host_dependencies();
				my $result = '';
#				if (defined($dep_hash{$d{'parent_id'}}{$d{'host_id'}})) { # reversed because we are checking for the reversed case
#					$result = "Error: Cannot create cyclical dependency (host is already the parent to proposed parent $d{'parent_id'}).";	
#				}
#				else {
					my %values = ('data' => $data);
					my %where = ('host_id' => $d{'host_id'},'parent_id' => $p{'host_id'});
					$result = StorProc->update_obj_where('host_dependencies',\%values,\%where);
#				}
				if ($result =~ /^Error/) { push @errors, $result }
				unless (@errors) {
					my $message = "Changes to host dependency $dependent_host-$parent_host have been saved.";
					$hidden{'name'} = undef;
					$page .= Forms->header($page_title,$session_id,$top_menu);
					$page .= Forms->success('Updated',$message,'continue',\%hidden);
					$got_form = 1;
				}
			} else {
				my %where = ('parent_id' => $d{'host_id'},'host_id' => $p{'host_id'});
				my %dep = StorProc->fetch_one_where('host_dependencies',\%where);
				if ($dep{'host_id'}) {
					push @errors, "Cannot create cyclical dependency. Host $dependent_host is currently the parent to proposed parent host $parent_host.";	
				}
				else {					
					my %where = ('parent_id' => $p{'host_id'},'host_id' => $d{'host_id'});
					my %dep = StorProc->fetch_one_where('host_dependencies',\%where);
					unless ($dep{'host_id'}) {
						my @vals = ($d{'host_id'},$p{'host_id'},$data,'');
						my $result = StorProc->insert_obj('host_dependencies',\@vals);
						if ($result =~ /^Error/) { push @errors, $result }	
						unless (@errors) {
							my $message = "Added: host dependency $dependent_host - $parent_host saved.";
							$hidden{'name'} = undef;
							$page .= Forms->header($page_title,$session_id,$top_menu);
							$page .= Forms->success('Updated',$message,'continue',\%hidden);
							$got_form = 1;
						}
					} else {
						push @errors, "Already exists: host dependency $dependent_host - $parent_host";
					}
				}
			}
		} else {
			push @errors, "Please correct missing fields (All are required)";
		}
	}
	unless ($got_form) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		my @props = ('dependent_host','parent_host','inherits_parent','execution_failure_criteria','notification_failure_criteria');
		my %docs = Doc->properties_doc('host_dependencies',\@props);
		if ($query->param('task') eq 'new') {
			my @hosts = StorProc->fetch_list('hosts','name');
			$page .= Forms->form_top('Host Dependency Properties','');
			if (@errors) { $page .= Forms->form_errors(\@errors) }
			$page .= Forms->list_box("Dependent host:",'dependent_host',\@hosts,$properties{'dependent_host'},$required{'dependent_host'},$docs{'dependent_host'});
			$page .= Forms->list_box("Parent:",'parent_host',\@hosts,$properties{'parent_host'},$required{'parent_host'},$docs{'parent_host'});
			if ($nagios_ver =~ /^[23]\.x$/) {
				my @opts = split(/,/, $properties{'execution_failure_criteria'});
				$page .= Forms->failure_criteria('execution_failure_criteria',\@opts,'','host_dependencies',$docs{'execution_failure_criteria'});
				$page .= Forms->checkbox('Inherits parent::','inherits_parent',$properties{'inherits_parent'},$docs{'inherits_parent'});
			}
			my @opts = split(/,/, $properties{'notification_failure_criteria'});
			$page .= Forms->failure_criteria('notification_failure_criteria',\@opts,'','host_dependencies',$docs{'notification_failure_criteria'});
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);
		} else {
			my @parents = StorProc->fetch_list('hosts','name');
			my %where = ('host_id' => $d{'host_id'},'parent_id' => $p{'host_id'});
			%properties = StorProc->fetch_one_where('host_dependencies',\%where);
			$page .= Forms->form_top('Host Dependency Properties','');
			if (@errors) { $page .= Forms->form_errors(\@errors) }
			$page .= Forms->display_hidden("Host:",'dependent_host',$dependent_host);
			$page .= Forms->display_hidden("Parent:",'parent_host',$parent_host);
			if ($nagios_ver =~ /^[23]\.x$/) {
				my @opts = split(/,/, $properties{'execution_failure_criteria'});
				$page .= Forms->failure_criteria('execution_failure_criteria',\@opts,'','host_dependencies',$docs{'execution_failure_criteria'});
				$page .= Forms->checkbox('Inherits parent::','inherits_parent',$properties{'inherits_parent'},$docs{'inherits_parent'});
			}
			my @opts = split(/,/, $properties{'notification_failure_criteria'});
			$page .= Forms->failure_criteria('notification_failure_criteria',\@opts,'','host_dependencies',$docs{'notification_failure_criteria'});
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%save,\%delete,\%cancel,$tab++);
		}
	}
	return $page;
}




#
# Clone host
#

sub clone_host() {
	my $got_form = 0;
	my $page = undef;
	if ($query->param('cancel')) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$got_form = 1;
	} elsif ($query->param('add_clone_host')) {
		my $host = $query->param('host');
		my $name = $query->param('name');
		my $alias = $query->param('alias');
		my $address = $query->param('address');
		my %exists = StorProc->fetch_one('hosts','name',$name);
		if ($exists{'name'}) {	
			push @errors, "Host $name already exists.";
		} else {
			if ($host && $name && $alias && $address) {
				@errors = StorProc->clone_host($host,$name,$alias,$address);
				unless ($errors[0]) {
					$obj = 'hosts';
					$page .= Forms->header($page_title,$session_id,$top_menu);
					$hidden{'view'} = 'manage_host';
					$page .= manage_host($name,'name');	
					$got_form = 1;
				}
			} else {
				unless ($host) { $required{'host'} = 1 }
				unless ($name) { $required{'name'} = 1 }
				unless ($alias) { $required{'alias'} = 1 }
				unless ($address) { $required{'address'} = 1 }
				push @errors, "Check required fields.";
			}
		}
	}
	unless ($got_form) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		my %docs = Doc->host_wizard_vitals();
		my $host = $query->param('host');
		my $name = $query->param('name');
		my $alias = $query->param('alias');
		my $address = $query->param('address');
		$page .= Forms->form_top('Clone Host','');
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		my @hosts = StorProc->fetch_list('hosts','name'); 
		$page .= Forms->text_box('Name:','name',$name,'50',$required{'name'});
		$page .= Forms->text_box('Alias:','alias',$alias,'70',$required{'alias'},$docs{'alias'});
		$page .= Forms->text_box('Address:','address',$address,'20',$required{'address'},$docs{'address'});
		$page .= Forms->list_box('Host:','host',\@hosts,$host,$required{'host'});
		$hidden{'view'} = 'clone_host';
		$page .= Forms->hidden(\%hidden);
		my %clone_host = ('name' => 'add_clone_host','value' => 'Clone Host');
		$page .= Forms->form_bottom_buttons(\%clone_host,\%cancel,$tab++);
	}
	return $page;
}

#
# Parent child
#

sub parent_child() {
	my $got_form = 0;
	my $page = undef;
	my $name = $query->param('name');
	my $parent = $query->param('parent');
	if ($query->param('continue') || $query->param('cancel')) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$got_form = 1;
	} elsif ($query->param('save')) {
		my @children = $query->param('children');
		if ($parent && @children) {
			my %p = StorProc->fetch_one('hosts','name',$name);
			my %w = ('parent_id' => $p{'host_id'});
			my $result = StorProc->delete_one_where('host_parent',\%w);
			if ($result =~ /^Error/) { push @errors, $result }
			%p = StorProc->fetch_one('hosts','name',$parent);
			%w = ('parent_id' => $p{'host_id'});
			$result = StorProc->delete_one_where('host_parent',\%w);
			if ($result =~ /^Error/) { push @errors, $result }
			foreach my $child (@children) {
				if (!$child) { next }
				my %h = StorProc->fetch_one('hosts','name',$child);
				my @vals = ($h{'host_id'},$p{'host_id'});
				my $result = StorProc->insert_obj('host_parent',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { 
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Saved','');
				$page .= Forms->display_hidden('Parent:','name',$parent);
				$page .= Forms->hidden(\%hidden);		
				$page .= Forms->form_bottom_buttons(\%continue,$tab++);
				$got_form = 1;
			}
		} else {
			push @errors, "A parent and at least one child must be selected.";
		}
	} elsif ($query->param('bail')) {
		$got_form = 0;
	} elsif ($query->param('delete') or $query->param('confirm_delete')) {
		if ($query->param('confirm_delete')) {
			$page .= Forms->header($page_title,$session_id,$top_menu);
			my %p = StorProc->fetch_one('hosts','name',$parent);
			my %w = ('parent_id' => $p{'host_id'});
			my $result = StorProc->delete_one_where('host_parent',\%w);
			if ($result =~ /^Error/) { 
				push @errors, $result;
			} else {
				$page .= Forms->header($page_title,$session_id,$top_menu,'','1');
				$page .= Forms->form_top('Deleted','');
				my @message = ("$parent");
				$page .= Forms->form_message('Removed:',\@message,'row1');			
				$page .= Forms->hidden(\%hidden);		
				$page .= Forms->form_bottom_buttons(\%continue,$tab++);
				$got_form = 1;	
			}
		} else {	
			$page .= Forms->header($page_title,$session_id,$top_menu);
			my $message = qq(Are you sure you want to remove parent $name? (Note: $name will still remain as a host).);
			$hidden{'name'} = $parent;
			$hidden{'parent'} = $parent;
			$page .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden);
			$got_form = 1;
		}
	}
	unless ($got_form) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		my @hosts = StorProc->fetch_list('hosts','name');
		my @parents = StorProc->get_parents();
		my @poss_parents = ();
		foreach my $host (@hosts) {
			my $got_parent = 0;
			foreach my $parent (@parents) {
				if ($host eq $parent) { $got_parent = 1 }
				if ($host eq $name) { $got_parent = 0 }
			}
			unless ($got_parent) { push @poss_parents, $host }
		}
		my %pid = StorProc->fetch_one('hosts','name',$name);
		my @children = StorProc->get_children($pid{'host_id'});
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top('Parent Child','onsubmit="selIt();"');
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		$hidden{'name'} = $name;
		$page .= Forms->list_box("Parent host:",'parent',\@poss_parents,$name);
		$page .= Forms->members('Children:','children',\@children,\@hosts,'','10');
		$hidden{'name'} = $name;
		$page .= Forms->hidden(\%hidden);
		$page .= Forms->form_bottom_buttons(\%save,\%delete,\%cancel,$tab++);		
	}
	return $page;
}

############################################################################
# Externals
#

sub externals($) {
	my $type = shift;
	my $form = undef;
	unless ($type) { $type = $query->param('type') }
	$hidden{'type'} = $type;
	my $task = $query->param('task');
	$hidden{'task'} = $task;
	my $name = $query->param('name');
	$name =~ s/^\s+|\s+$//;
	my $display =  $query->param('display');
	my $got_form = 0;
	$hidden{'update_main'} = 1;

	my %external =  StorProc->fetch_one('externals','name',$name);
	

	if ($query->param('continue') || $query->param('close') || $query->param('cancel')) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$got_form = 1;
	} elsif ($query->param('add')) {
		if ($name && $type) {
			unless ($external{'name'}) {
				my @vals = ('',$name,'',$type,$display,'');
				my $result = StorProc->insert_obj('externals',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			} else {
				push @errors, "Record $name already exists.";		
			}
		} else {
			push @errors, "Please fill in the required fields";		
			$required{'name'} = 1;
			$required{'type'} = 1;
		}
		unless (@errors) { 
			$form .= Forms->header($page_title,$session_id,$top_menu);
			$form .= Forms->form_top('Saved','');
			$form .= Forms->display_hidden('External:','name',$name);
			$form .= Forms->hidden(\%hidden);		
			$form .= Forms->form_bottom_buttons(\%continue,$tab++);
			$got_form = 1;
		}
	} elsif ($query->param('save')) {
		if ($type) {
			my %values = ('type' => $type,'display' => $display);
			my $result = StorProc->update_obj('externals','name',$name,\%values);
			if ($result =~ /^Error/) { push @errors, $result }
		} else {
			push @errors, "Please fill in the required fields";		
			$required{'type'} = 1;
		}
		unless (@errors) { 
			$form .= Forms->header($page_title,$session_id,$top_menu,'','');
			$form .= Forms->form_top('Saved','');
			$form .= Forms->display_hidden('External:','name',$name);
			$form .= Forms->hidden(\%hidden);
			my %apply = ('name' => 'apply','value' => 'Apply to Services');
			if ($type eq 'host') {
				%apply = ('name' => 'apply','value' => 'Apply to Hosts');
			}
			$form .= Forms->form_bottom_buttons(\%apply,\%continue,$tab++);
			$got_form = 1;
		}
	} elsif ($query->param('apply')) {
		my %w = ('external_id' => $external{'external_id'});
		my %values = ('data' => $external{'display'});
		if ($type eq 'service') {
			my $result = StorProc->update_obj_where('external_service',\%values,\%w);			
			if ($result =~ /^Error/) { push @errors, $result }
		} else {
			my $result = StorProc->update_obj_where('external_host',\%values,\%w);			
			if ($result =~ /^Error/) { push @errors, $result }
		}
		unless (@errors) {
			$form .= Forms->header($page_title,$session_id,$top_menu);
			$form .= Forms->form_top('Applied','');
			my @message = ("$name applied to $type\s");
			$form .= Forms->form_message('Saved:',\@message,'row1');			
			$form .= Forms->hidden(\%hidden);
			$form .= Forms->form_bottom_buttons(\%continue,$tab++);
			$got_form = 1;
		}
	} elsif ($query->param('delete') || $query->param('confirm_delete')) {
		foreach my $name ($query->param) {
			unless ($name eq 'nocache') { $hidden{$name} = $query->param($name) }
		}
		if ($query->param('confirm_delete')) {
			my $result = StorProc->delete_all('externals','external_id',$external{'external_id'});
			if ($result =~ /^Error/) { push @errors, $result }
			unless (@errors) { 
				$form .= Forms->header($page_title,$session_id,$top_menu,'','1');
				$form .= Forms->form_top('Deleted','');
				my @message = ("$name");
				$form .= Forms->form_message('Removed:',\@message,'row1');	
				$form .= Forms->hidden(\%hidden);
				$form .= Forms->form_bottom_buttons(\%continue,$tab++);
				$name = undef;
				$got_form = 1;	
			}
		} elsif ($query->param('task') eq 'No') {
			$got_form = 0;	
		} else {
			delete $hidden{'task'};
			$hidden{'delete'} = 1;
			$form .= Forms->header($page_title,$session_id,$top_menu);
			my $message = qq(Are you sure you want to remove $name? (Warning: $name will be removed from all $type\s and profiles).);
			$form .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden);
			$name = undef;
			$got_form = 1;
		}
	}
	unless ($got_form) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Forms->form_top("\u$type External",'');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		if ($task eq 'new') {
			$form .= Forms->text_box('Name:','name',$name,$textsize{'name'},$required{'name'});
		} else {
			unless ($display) { $display = $external{'display'} }
			$form .= Forms->display_hidden('Name:','name',$name);
			delete $hidden{'task'};
		}
		$form .= Forms->display_hidden("Type:",'type',$type);
		$form .= Forms->text_area('Detail:','display',$display,'30','140');
		$form .= Forms->hidden(\%hidden);
		if ($task eq 'new') {
			$form .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);
		} else {
			$form .= Forms->form_bottom_buttons(\%save,\%delete,\%cancel,$tab++);
		}

	}	
	return $form;
}


############################################################################
# Escalations
#
sub escalations() {
	my $page = undef;
	my $type = $query->param('type');
	my $name = $query->param('name');
	$table = "escalation_templates";
	$hidden{'obj'} = $obj;
	$hidden{'type'} = $type;
	my $got_form = 0;

	# for validation - not yet hooked up
	my $validation_mini_profile = {
		notification_interval => { constraint => '[0-9]+', message => 'Value must be numeric.' },
		first_notification    => { constraint => '[0-9]+', message => 'Value must be numeric.' },
		last_notification     => { constraint => '[0-9]+', message => 'Value must be numeric.' },
	};
	my $escalation = $query->param('escalation');
	if ($query->param('continue') || $query->param('close') || $query->param('cancel')) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$got_form = 1;
	} elsif ($query->param('add')) {
		my %data = parse_query($table,$obj);
		my $field_ck = check_fields();
		if ($field_ck == 0) {
			my @values = ('');
			my @data_cols = split(/,/, $db_values{$table});
			foreach my $val (@data_cols) {
				$val =~ s/^\s+|\s+$//;
				if ($val eq 'comment') { 
					push @values, "# $obj $properties{'name'}";
				} else {
					push @values, $data{$val};
				}
			}
			my %esc = StorProc->fetch_one('escalation_templates','name',$properties{'name'});
			if ($esc{'name'}) {
				push @errors, "An escalation with name $properties{'name'} already exists.";
			} else {
				my $result = StorProc->insert_obj('escalation_templates',\@values,$obj_id{$table});
				if ($result =~ /^Error/) { push @errors, $result }
			}		
			unless (@errors) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				my $message = "$data{'name'} has been saved.";
				$hidden{'name'} = undef;
				$hidden{'task'} = undef;
				$page .= Forms->success('Added',$message,'continue',\%hidden);
				$got_form = 1;
			} else {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= build_form($validation_mini_profile);
				#$page .= build_form('');
				$got_form = 1;
			}
		} elsif ($field_ck == 1) {
			$page .= Forms->header($page_title,$session_id,$top_menu);
			$page .= build_form($validation_mini_profile);
			#$page .= build_form('');
			$got_form = 1;
		}
	} elsif ($query->param('save')) {
		my %values = ();
		my %data = parse_query($table,$obj);
		my $field_ck = check_fields();
		if ($field_ck == 0) {
			foreach my $key (keys %data) {
				unless ($key =~ /HASH|^name$|^contactgroup$|members$/) {
					$values{$key} = $data{$key};					
				}
			}
			my $result = StorProc->update_obj('escalation_templates','name',$data{'name'},\%values);
			if ($result =~ /^Error/) { push @errors, $result }
			unless (@errors) {
				my $message = "Changes to $name have been saved.";
				$hidden{'name'} = undef;
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->success('Updated',$message,'continue',\%hidden);
				$got_form = 1;
			} else {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= build_form($validation_mini_profile);
				#$page .= build_form('');
				$got_form = 1;
			}
		} elsif ($field_ck == 1) {
			$page .= Forms->header($page_title,$session_id,$top_menu);
			$page .= build_form($validation_mini_profile);
			#$page .= build_form('');
			$got_form = 1;
		}
	} elsif ($query->param('rename')) {
		$page .= rename_object('',$name);
		$got_form = 1;
	} elsif ($query->param('bail')) {
		$task = 'modify';
		$hidden{'task'} = 'modify';
	} elsif ($query->param('delete') or $query->param('confirm_delete')) {
		$hidden{'task'} = 'modify';
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= delete_object('',$name);
		$got_form = 1;
	}
	unless ($got_form) {
		if ($obj =~ /escalation_templates/) {
			$page .= Forms->header($page_title,$session_id,$top_menu);
			$hidden{'type'} = $type;
			$hidden{'task'} = $task;
			$page .= build_form($validation_mini_profile);
			#$page .= build_form('');
		}
	}
	return $page;
}

sub escalation_trees() {
	my @views = ('detail','assign_hostgroups','assign_hosts','assign_service_groups','assign_services');
	unless ($obj_view eq 'assign_contactgroups') {
		foreach my $v (@views) {
			if ($query->param($v)) { $obj_view = $v }
		}
	}
	foreach my $name ($query->param) {
		if ($name =~ /assign_contactgroups_(\d+)/) {
			$hidden{'id'} = $1;
			$obj_view = 'assign_contactgroups';
		} 
		if ($name =~ /remove_escalation_(\d+)/) {
			$hidden{'id'} = $1;
			$obj_view = 'remove_escalation';
		} 
	}
	my $message = undef;
	my $page = undef;
	my $type = $query->param('type');
	my $name = $query->param('name');
	$name =~ s/^\s+|\s+$//;
	$hidden{'obj'} = $obj;
	$hidden{'type'} = $type;
	my %tree = StorProc->fetch_one('escalation_trees','name',$name);
	my $escalation = $query->param('escalation');
	my $got_form = 0;
	if ($query->param('continue') || $query->param('close')) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$got_form = 1;
	} elsif ($query->param('cancel')) {
		$obj_view = 'detail';
	} elsif ($query->param('add')) {
		my %t = StorProc->fetch_one('escalation_trees','name',$name);
		if ($t{'name'}) {
			push @errors,  "Duplicate: Escalation tree $name already exists.";
			$name = undef;
			$obj_view = 'new';
		} else {
			my @values = ('',$name,'',$type);
			my $result = StorProc->insert_obj('escalation_trees',\@values);
			if ($result =~ /^Error/) { 
				push @errors, $result;
			} else {
				$task = undef;
				delete $hidden{'task'};
				$obj_view = 'detail';
			}
		}
	} elsif ($query->param('save')) {
		if ($query->param('save_hostgroups')) {
			my %w = ("$type\_escalation_id" => $tree{'tree_id'});
			my %u = ("$type\_escalation_id" => '');
			my $result = StorProc->update_obj_where('hostgroups',\%u,\%w);
			if ($result =~ /^Error/) { push @errors, $result }
			my %hostgroup_name = StorProc->get_table_objects('hostgroups');
			my @hostgroups = $query->param('hostgroups');
			foreach my $assn (@hostgroups) {
				my %values = ("$type\_escalation_id" => $tree{'tree_id'});
				my $result = StorProc->update_obj('hostgroups','hostgroup_id',$hostgroup_name{$assn},\%values);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) {
				$obj_view = 'saved';
				$message = "Hostgroups assigned.";
			}

		} elsif ($query->param('save_hosts')) {
			my %w = ("$type\_escalation_id" => $tree{'tree_id'});
			my %u = ("$type\_escalation_id" => '');
			my $result = StorProc->update_obj_where('hosts',\%u,\%w);
			if ($result =~ /^Error/) { push @errors, $result }
			my %host_name = StorProc->get_table_objects('hosts');
			my @hosts = $query->param('hosts');
			foreach my $assn (@hosts) {
				my %values = ("$type\_escalation_id" => $tree{'tree_id'});
				my $result = StorProc->update_obj('hosts','host_id',$host_name{$assn},\%values);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) {
				$obj_view = 'saved';
				$message = "Hosts assigned.";
			}
		} elsif ($query->param('save_service_groups')) {
			my %w = ('escalation_id' => $tree{'tree_id'});
			my %u = ('escalation_id' => '');
			my $result = StorProc->update_obj_where('servicegroups',\%u,\%w);
			if ($result =~ /^Error/) { push @errors, $result }
			my %servicegroup_name = StorProc->get_table_objects('servicegroups');
			my @servicegroups = $query->param('servicegroups');
			foreach my $assn (@servicegroups) {
				my %values = ('escalation_id' => $tree{'tree_id'});
				my $result = StorProc->update_obj('servicegroups','servicegroup_id',$servicegroup_name{$assn},\%values);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) {
				$obj_view = 'saved';
				$message = "Service groups assigned.";
			}
		} elsif ($query->param('save_services')) {
			my %w = ('escalation' => $tree{'tree_id'});
			my %u = ('escalation' => '');
			my $result = StorProc->update_obj_where('service_names',\%u,\%w);
			if ($result =~ /^Error/) { push @errors, $result }
			my %service_name = StorProc->get_table_objects('service_names');
			my @services = $query->param('service_names');
			foreach my $assn (@services) {
				my %values = ('escalation' => $tree{'tree_id'});
				my $result = StorProc->update_obj('service_names','servicename_id',$service_name{$assn},\%values);
				if ($result =~ /^Error/) { push @errors, $result }
				if ($query->param('apply_hosts')) {
					my %values = ('escalation_id' => $tree{'tree_id'});
					my $result = StorProc->update_obj('services','servicename_id',$service_name{$assn},\%values);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
			unless (@errors) {
				$obj_view = 'saved';
				$message = "Services assigned.";
			}
		}
	} elsif ($query->param('rename')) {
		$page .= rename_object('',$name);
		$got_form = 1;
	} elsif ($query->param('bail')) {
		$task = 'modify';
		$obj_view = 'detail'
	} elsif ($query->param('delete') or $query->param('confirm_delete')) {
		$hidden{'task'} = 'modify';
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= delete_object('',$name);
		$got_form = 1;
	} elsif ($query->param('add_escalation')) {
		my $escalation = $query->param('escalation');
		if ($escalation) {
			my %tree = StorProc->fetch_one('escalation_trees','name',$name);
			my %esc = StorProc->fetch_one('escalation_templates','name',$escalation);
			my @values = ($tree{'tree_id'},$esc{'template_id'});	
			my $result = StorProc->insert_obj('escalation_tree_template',\@values);
			if ($result =~ /^Error/) { push @errors, $result }
			unless (@errors) {	
				$obj_view = 'assign_contactgroups';
				$hidden{'id'} = $esc{'template_id'};
			} else {
				$obj_view = 'detail';
			}
		} else {
			$obj_view = 'detail';
		}
	} elsif ($query->param('assign_contactgroups')) {
		my @contactgroups = $query->param('contactgroups');
		my $id = $query->param('id');
		if ($contactgroups[0]) {
			my %w = ('template_id' => $id,'tree_id' => $tree{'tree_id'});
			my $result = StorProc->delete_one_where('tree_template_contactgroup',\%w);
			if ($result =~ /^Error/) { push @errors, $result }
			foreach my $cg (@contactgroups) {
				my %c = StorProc->fetch_one('contactgroups','name',$cg);
				my @values = ($tree{'tree_id'},$id,$c{'contactgroup_id'});
				my $result = StorProc->insert_obj('tree_template_contactgroup',\@values);
				if ($result =~ /^Error/) { push @errors, $result }
			}
		} else {
			$required{'contactgroup'} = 1;
			push @errors, "Contact group required.";
		}
		unless (@errors) { 
			$obj_view = 'detail';
		} else {
			$obj_view = 'assign_contactgroups';
		}
	} elsif ($obj_view eq 'remove_escalation') {
		my %w = ('template_id' => $hidden{'id'},'tree_id' => $tree{'tree_id'});
		my $result = StorProc->delete_one_where('escalation_tree_template',\%w);
		if ($result =~ /^Error/) { push @errors, $result }
		%w = ('template_id' => $hidden{'id'},'tree_id' => $tree{'tree_id'});
		$result = StorProc->delete_one_where('tree_template_contactgroup',\%w);
		if ($result =~ /^Error/) { push @errors, $result }
		$obj_view = 'detail';
	}
	unless ($got_form) {
		my %docs = Doc->escalations();
		$page .= Forms->header($page_title,$session_id,$top_menu);
		if ($obj_view eq 'new') {
			my $validation_mini_profile = { name => { constraint => '[^/\\\\`~\+!\$\%\^\&\*\|\'\"<>\?,\)\(\'=\[\]\{\}\:\#;]+' } };
			$page .= Validation->dfv_profile_javascript($validation_mini_profile);
			$page .= Forms->form_top('Escalation Tree', Validation->dfv_onsubmit_javascript());
			if (@errors) { $page .= Forms->form_errors(\@errors) }
			$page .= Forms->text_box('Name:','name',$name,$textsize{'name'});
			$page .= Forms->display_hidden('Type:','type',$type);
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);		
		} elsif ($obj_view eq 'detail') {
			$page .= Forms->escalation_top($name,$session_id,$obj_view,$type,$nagios_ver);
			my %tree = StorProc->fetch_one('escalation_trees','name',$name);
			my ($order, $first_notify, $members) = StorProc->get_tree_templates($tree{'tree_id'});
			my %members = %{$members};
			my %w = ('type' => $tree{'type'});
			my @templates = StorProc->fetch_list_where('escalation_templates','name',\%w);
			my @nonmembers = ();
			my %mems = ();
			my %ids = ();
			my %contact_groups = ();
			my @members = ();
			foreach my $id (@{$order}) {
				my %cg = ();
				my $type = "$tree{'type'}_escalation_templates";
				my @cgs = StorProc->get_tree_template_contactgroup($tree{'tree_id'},$id);
				foreach (@cgs) { 
					$contact_groups{$id} .= "$_, ";
				}
				$contact_groups{$id} =~ s/,\s$//;
				push @members, $members{$id}[1];
				$mems{$members{$id}[1]} = 1;
				$ids{$members{$id}[1]} = $id;
			}
			foreach my $temp (@templates) {
				unless ($mems{$temp}) {push @nonmembers, $temp} 
			}
			if (@errors) { $page .= Forms->form_errors(\@errors) }
			$page .= Forms->wizard_doc('Managing Escalations',$docs{'escalation_tree'});
			$page .= Forms->manage_escalation_tree($session_id,$view,$type,$name,$tree{'tree_id'},\%ids,\@members,\@nonmembers,\%contact_groups, $first_notify);
			$page .= Forms->hidden(\%hidden);
			if ($auth_delete{'escalations'}) {
				$page .= Forms->form_bottom_buttons(\%delete,\%rename,\%close,$tab++);		
			} else {
				$page .= Forms->form_bottom_buttons(\%rename,\%close,$tab++);		
			}
		} elsif ($obj_view eq 'assign_contactgroups') {
			$page .= Forms->escalation_top($name,$session_id,$obj_view,$type,$nagios_ver);
			unless ($hidden{'id'}) { $hidden{'id'} = $query->param('id') }
			my %esc = StorProc->fetch_one('escalation_templates','template_id',$hidden{'id'});
			$hidden{'obj_view'} = 'assign_contactgroups';
			$hidden{'type'} = $type;
			if (@errors) { $page .= Forms->form_errors(\@errors) }
			$page .= Forms->display_hidden('Escalation:','escalation',$esc{'name'});
			my @contact_groups = StorProc->fetch_list('contactgroups','name');
			my @assigned = StorProc->get_tree_template_contactgroup($tree{'tree_id'},$esc{'template_id'});
			$page .= Forms->wizard_doc('Assign Contact Groups',$docs{'contactgroup'});
			$page .= Forms->members('Contact groups:','contactgroups',\@assigned,\@contact_groups,$required{'contactgroup'},'','');
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%assign_contactgroups,$tab++);
		} elsif ($obj_view eq 'assign_hostgroups') {
			my $doc = $docs{'host_hostgroup'};
			if ($type eq 'service') { $doc = $docs{'service_hostgroup'} }
			my @assigned = StorProc->get_escalation_assigned($tree{'tree_id'},$type,'hostgroups');
			my @unassigned = StorProc->fetch_list('hostgroups','name');
			$page .= Forms->escalation_top($name,$session_id,$obj_view,$type,$nagios_ver);
			$page .= Forms->wizard_doc('Assign Hostgroups',$doc);
			$page .= Forms->members('Host groups:','hostgroups',\@assigned,\@unassigned,'','','');
			$hidden{'save_hostgroups'} = 1;
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%save,\%cancel,$tab++);		
		} elsif ($obj_view eq 'assign_hosts') {
			my $doc = $docs{'host_host'};
			if ($type eq 'service') { $doc = $docs{'service_host'} }
			my @assigned = StorProc->get_escalation_assigned($tree{'tree_id'},$type,'hosts');
			my @unassigned = StorProc->fetch_list('hosts','name');
			$page .= Forms->escalation_top($name,$session_id,$obj_view,$type,$nagios_ver);
			$page .= Forms->wizard_doc('Assign Hosts',$doc);
			$page .= Forms->members('Hosts:','hosts',\@assigned,\@unassigned,'','','');
			$hidden{'save_hosts'} = 1;
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%save,\%cancel,$tab++);		
		} elsif ($obj_view eq 'assign_service_groups') {
			my @assigned = StorProc->get_escalation_assigned($tree{'tree_id'},'service','servicegroups');
			my @unassigned = StorProc->fetch_list('servicegroups','name');
			$page .= Forms->escalation_top($name,$session_id,$obj_view,$type,$nagios_ver);
			$page .= Forms->wizard_doc('Assign Service Groups',$docs{'servicegroup'});
			$page .= Forms->members('Service groups:','servicegroups',\@assigned,\@unassigned,'','','');
			$hidden{'save_service_groups'} = 1;
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%save,\%cancel,$tab++);		
		} elsif ($obj_view eq 'assign_services') {
			my @assigned = StorProc->get_escalation_assigned($tree{'tree_id'},'service','services');
			my @unassigned = StorProc->fetch_list('service_names','name');
			$page .= Forms->escalation_top($name,$session_id,$obj_view,$type,$nagios_ver);
			$page .= Forms->wizard_doc('Assign Services',$docs{'service'});
			$page .= Forms->checkbox_left('Apply to hosts','apply_hosts');
			$page .= Forms->members('Services:','service_names',\@assigned,\@unassigned,'','','');
			$hidden{'save_services'} = 1;
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%save,\%cancel,$tab++);		
		} elsif ($obj_view eq 'saved') {
			$page .= Forms->escalation_top($name,$session_id,$obj_view,$type,$nagios_ver);
			$page .= Forms->display_hidden('Saved','',$message);				
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%close,$tab++);		
		
		}
	}
	return $page;
}


#
############################################################################
# Profiles
#
############################################################################
# Host profile
#	

sub host_profile() {
	my $name = $query->param('name');
	unless ($obj_view) { $obj_view = 'host_detail' }
	$hidden{'obj_view'} = $obj_view;
	my %profile = StorProc->fetch_one('profiles_host','name',$name);
	my $form = undef;
	if ($query->param('add')) {
		$name =~ s/^\s+|\s+$//;
		%profile = StorProc->fetch_one('profiles_host','name',$name);
		my $description = $query->param('description');
		my $template = $query->param('template');
		unless ($profile{'name'} || $name eq '') {
			if ($template) {
				my $data = "<?xml version=\"1.0\" ?>\n<data>\n</data>";
				$profile{'description'} = $description;
				my %t = StorProc->fetch_one('host_templates','name',$template);
				$profile{'hosttemplate_id'} = $t{'hosttemplate_id'};
				my @values = ('',$name,$description,$t{'hosttemplate_id'},'','','',$data);
				my $id = StorProc->insert_obj_id('profiles_host',\@values,'hostprofile_id');
				if ($id =~ /^Error/) { 
					push @errors, $id;
					%profile = ();
				} else {
					$profile{'hostprofile_id'} = $id;
				}
			} else {
				push @errors, "Check required fields.";
				$required{'template'} = 1;
			}
		} else {
			push @errors, "Check name field. It's either blank or a record already exists";
		}
		unless (@errors) { $obj_view = 'host_detail' }
	} elsif ($query->param('close') || $query->param('cancel') || $query->param('continue')) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$obj_view = 'close';
	} elsif ($query->param('export')) {
		use MonarchProfileExport;
		my $results = ProfileExporter->host_profile($profile{'hostprofile_id'},"$doc_root/monarch/download");
		if ($results =~ /^Error/) { 
			push @errors, $results;
		} else {
			$obj_view = 'exported';
		}
	} elsif ($query->param('save')) {
		if ($obj_view eq 'host_detail') {
			my %data = parse_query('host_templates','host_overrides');
			my $host_template = $query->param('template');
			my $extinfo = $query->param('extended_info');
			if ($host_template) {
				my %values = ();
				$values{'description'} = $query->param('description');
				my %t = StorProc->fetch_one('host_templates','name',$host_template);
				$values{'host_template_id'} = $t{'hosttemplate_id'};
				my %e = StorProc->fetch_one('extended_host_info_templates','name',$extinfo);
				$values{'host_extinfo_id'} = $e{'hostextinfo_id'};
				my $result = StorProc->update_obj('profiles_host','hostprofile_id',$profile{'hostprofile_id'},\%values);
				if ($result =~ /^Error/) { push @errors, $result }
				my %where = ('hostprofile_id' => $profile{'hostprofile_id'});
				my $result = StorProc->delete_one_where('hostprofile_overrides',\%where);
				if ($result =~ /^Error/) { push @errors, $result }
				if ($data{'check_period'} || $data{'notification_period'}|| $data{'check_command'} || $data{'event_handler'} || $data{'data'}) {
					my @values = ($profile{'hostprofile_id'},$data{'check_period'},$data{'notification_period'},$data{'check_command'},$data{'event_handler'},$data{'data'});
					my $result = StorProc->insert_obj('hostprofile_overrides',\@values);
					if ($result =~ /^Error/) { push @errors, $result }
				}
				if ($query->param('contactgroup_override')) {
#					my %where = ('type' => 'host_profiles','object' => $profile{'hostprofile_id'});
#					my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
					my %where = ('hostprofile_id' => $profile{'hostprofile_id'});
					my $result = StorProc->delete_one_where('contactgroup_host_profile',\%where);
					if ($result =~ /^Error/) { push @errors, $result }
				} else {
#					my %where = ('type' => 'host_profiles','object' => $profile{'hostprofile_id'});
#					my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
					my %where = ('hostprofile_id' => $profile{'hostprofile_id'});
					my $result = StorProc->delete_one_where('contactgroup_host_profile',\%where);
					if ($result =~ /^Error/) { push @errors, $result }
					my @mems = $query->param('contactgroup');
					foreach (@mems) {
						my %cg = StorProc->fetch_one('contactgroups','name',$_);

#						my @vals = ($cg{'contactgroup_id'},'host_profiles',$profile{'hostprofile_id'});
#						$result = StorProc->insert_obj('contactgroup_assign',\@vals);
						my @vals = ($cg{'contactgroup_id'},$profile{'hostprofile_id'});
						$result = StorProc->insert_obj('contactgroup_host_profile',\@vals);

						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
			} else {
				push @errors, "Error: missing required fields.";
				$required{'template'} = 1;
			}
			unless (@errors) { $obj_view = 'saved' }
		} elsif ($obj_view eq 'parents') {
			my @parents = $query->param('parents');
			my $result = StorProc->delete_all('profile_parent','hostprofile_id',$profile{'hostprofile_id'});
			if ($result =~ /^Error/) { push @errors, $result }
			foreach my $p (@parents) {
				if (!$p) { next }
				my %h = StorProc->fetch_one('hosts','name',$p);
				my @vals = ($profile{'hostprofile_id'},$h{'host_id'});
				$result = StorProc->insert_obj('profile_parent',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { 
				$obj_view = 'saved';
				$hidden{'obj_view'} = 'parents';
				$hidden{'apply'} = 0;
			}

		} elsif ($obj_view eq 'hostgroups') {
			my @hostgroups = $query->param('hostgroups');
			my $result = StorProc->delete_all('profile_hostgroup','hostprofile_id',$profile{'hostprofile_id'});
			if ($result =~ /^Error/) { push @errors, $result }
				foreach my $hg (@hostgroups) {
				if (!$hg) { next }
				my %h = StorProc->fetch_one('hostgroups','name',$hg);
				my @vals = ($profile{'hostprofile_id'},$h{'hostgroup_id'});
				$result = StorProc->insert_obj('profile_hostgroup',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { 
				$obj_view = 'saved';
				$hidden{'obj_view'} = 'hostgroups';
				$hidden{'apply'} = 0;
			}

		} elsif ($obj_view eq 'escalations') {
			my %values = ();
			my $host_escalation = $query->param('host_escalation');
			my %w = ('name' => $host_escalation,'type' => 'host');
			my %t = StorProc->fetch_one_where('escalation_trees',\%w);
			$values{'host_escalation_id'} = $t{'tree_id'};
			my $service_escalation = $query->param('service_escalation');
			%w = ('name' => $service_escalation,'type' => 'service');
			%t = StorProc->fetch_one_where('escalation_trees',\%w);
			$values{'service_escalation_id'} = $t{'tree_id'};
			my $result = StorProc->update_obj('profiles_host','name',$name,\%values);
			if ($result =~ /^Error/) { 
				push @errors, $result;
			} else {
				$obj_view = 'saved';
			}
		} elsif ($obj_view eq 'externals') {
			my @externals = $query->param('externals');
			my $result = StorProc->delete_all('external_host_profile','hostprofile_id',$profile{'hostprofile_id'});
			if ($result =~ /^Error/) { push @errors, $result }
			foreach my $e (@externals) {
				my %e = StorProc->fetch_one('externals','name',$e);
				my @vals = ($e{'external_id'},$profile{'hostprofile_id'});
				$result = StorProc->insert_obj('external_host_profile',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { 
				$obj_view = 'saved';
				$hidden{'obj_view'} = 'externals';
				$hidden{'apply'} = 1;
			}

		} elsif ($obj_view eq 'service_profiles') {
			my @service_profile = $query->param('service_profiles');
			my $result = StorProc->delete_all('profile_host_profile_service','hostprofile_id',$profile{'hostprofile_id'});
			if ($result =~ /^Error/) { push @errors, $result }
			foreach my $p (@service_profile) {
				my %s = StorProc->fetch_one('profiles_service','name',$p);
				my @vals = ($profile{'hostprofile_id'},$s{'serviceprofile_id'});
				$result = StorProc->insert_obj('profile_host_profile_service',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { $obj_view = 'saved' }
		} elsif ($obj_view eq 'assign_hosts') {
			my @hosts = $query->param('hosts');
			my %values = ('hostprofile_id' => '0');
			my $result = StorProc->update_obj('hosts','hostprofile_id',$profile{'hostprofile_id'},\%values);
			foreach my $host (@hosts) {
				my %values = ('hostprofile_id' => $profile{'hostprofile_id'});
				my $result = StorProc->update_obj('hosts','name',$host,\%values);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { $obj_view = 'saved' }

		} elsif ($obj_view eq 'assign_hostgroups') {
			my @hostgroups = $query->param('hostgroups');
			my %values = ('hostprofile_id' => '0');
			my $result = StorProc->update_obj('hostgroups','hostprofile_id',$profile{'hostprofile_id'},\%values);
			foreach my $hostgroup (@hostgroups) {
				my %values = ('hostprofile_id' => $profile{'hostprofile_id'});
				my $result = StorProc->update_obj('hostgroups','name',$hostgroup,\%values);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { $obj_view = 'saved' }
		}
	} elsif ($query->param('apply')) {
		my $hostgroups_select = $query->param('hostgroups_select');
		my $hosts_select = $query->param('hosts_select');
		my $apply_parents = $query->param('apply_parents');
		my $apply_hostgroups = $query->param('apply_hostgroups');
		my $apply_contactgroups = $query->param('apply_contactgroups');
		my $apply_escalations = $query->param('apply_escalations');
		my $apply_detail = $query->param('apply_detail');
		my $apply_services = $query->param('apply_services');

		my $data = "<?xml version=\"1.0\" ?>\n<data>";
		if ($hostgroups_select) { 
			$data .= qq(
  <prop name="hostgroups_select"><![CDATA[checked]]>
  </prop>);
		}
		if ($hosts_select) { 
			$data .= qq(
  <prop name="hosts_select"><![CDATA[checked]]>
  </prop>);
		}

		my %where = ('hostprofile_id' => $profile{'hostprofile_id'});
		my @profiles = StorProc->fetch_list_where('profile_host_profile_service','serviceprofile_id',\%where);
		my @hosts = ();
		if ($hostgroups_select) {
		my %where = ('hostprofile_id' => $profile{'hostprofile_id'});
			my @hgs = StorProc->fetch_list_where('hostgroups','hostgroup_id',\%where);
			foreach my $hg (@hgs) {
				%where = ('hostgroup_id' => $hg);
				my @hs = StorProc->fetch_list_where('hostgroup_host','host_id',\%where);
				push (@hosts,@hs);
			}
		}
		if ($hosts_select) {
			my %where = ('hostprofile_id' => $profile{'hostprofile_id'});
			my @hs  = StorProc->fetch_list_where('hosts','host_id',\%where);
			push (@hosts,@hs);
		}
		my %host = ();
		foreach my $hid (@hosts) {
			unless ($host{$hid}) {
				$host{$hid} = 1;
				if ($apply_parents) { 
					my $result = StorProc->delete_all('host_parent','host_id',$hid);
					if ($result =~ /^Error/) { push @errors, $result }
					my %w = ('hostprofile_id' => $profile{'hostprofile_id'});
					my @parents = StorProc->fetch_list_where('profile_parent','host_id',\%w);
					foreach my $pid (@parents) {
						my @vals = ($hid,$pid);
						my $result = StorProc->insert_obj('host_parent',\@vals);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
				if ($apply_hostgroups) { 
					my $result = StorProc->delete_all('hostgroup_host','host_id',$hid);
					if ($result =~ /^Error/) { push @errors, $result }
					my %w = ('hostprofile_id' => $profile{'hostprofile_id'});
					my @hostgroups = StorProc->fetch_list_where('profile_hostgroup','hostgroup_id',\%w);
					foreach my $hgid (@hostgroups) {
						my @vals = ($hgid,$hid);
						my $result = StorProc->insert_obj('hostgroup_host',\@vals);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
				if ($apply_contactgroups) { 

#					my %w = ('type' => 'hosts','object' => $hid);
#					my $result = StorProc->delete_one_where('contactgroup_assign',\%w);
					my %w = ('host_id' => $hid);
					my $result = StorProc->delete_one_where('contactgroup_host',\%w);

					if ($result =~ /^Error/) { push @errors, $result }

#					%w = ('type' => 'host_profiles','object' => $profile{'hostprofile_id'});
#					my @contactgroups = StorProc->fetch_list_where('contactgroup_assign','contactgroup_id',\%w);
					%w = ('hostprofile_id' => $profile{'hostprofile_id'});
					my @contactgroups = StorProc->fetch_list_where('contactgroup_host_profile','contactgroup_id',\%w);

					foreach my $cgid (@contactgroups) {

#						my @vals = ($cgid,'hosts',$hid);
#						my $result = StorProc->insert_obj('contactgroup_assign',\@vals);
						my @vals = ($cgid,$hid);
						my $result = StorProc->insert_obj('contactgroup_host',\@vals);

						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
				if ($apply_services eq 'replace') {
					my $result = StorProc->delete_all('serviceprofile_host','host_id',$hid);							
					if ($result =~ /^Error/) { push @errors, $result }
					foreach my $spid (@profiles) {
						my @vals = ($spid,$hid);
						my $result = StorProc->insert_obj('serviceprofile_host',\@vals);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				} else {
					foreach my $spid (@profiles) {
						my %p = StorProc->fetch_one('serviceprofile_host','serviceprofile_id',$spid);
						unless ($p{'host_id'}) {
							my @vals = ($spid,$hid);
							my $result = StorProc->insert_obj('serviceprofile_host',\@vals);
							if ($result =~ /^Error/) { push @errors, $result }
						}
					}
				}			
			}
		}
		if ($apply_parents) { 
			$data .= qq(
  <prop name="apply_parents"><![CDATA[checked]]>
  </prop>);
		}
		if ($apply_hostgroups) { 
			$data .= qq(
  <prop name="apply_hostgroups"><![CDATA[checked]]>
  </prop>);
		}
		if ($apply_contactgroups) { 
			$data .= qq(
  <prop name="apply_contactgroups"><![CDATA[checked]]>
  </prop>);
		}
		if ($apply_escalations) { 
			$data .= qq(
  <prop name="apply_escalations"><![CDATA[checked]]>
  </prop>);
			my %vals = ('host_escalation_id' => $profile{'host_escalation_id'});
			my $result = StorProc->update_obj('hosts','hostprofile_id',$profile{'hostprofile_id'},\%vals);
			if ($result =~ /^Error/) { push @errors, $result }
			%vals = ('service_escalation_id' => $profile{'service_escalation_id'});
			$result = StorProc->update_obj('hosts','hostprofile_id',$profile{'hostprofile_id'},\%vals);
			if ($result =~ /^Error/) { push @errors, $result }
		}
		if ($apply_detail) { 
			$data .= qq(
  <prop name="apply_detail"><![CDATA[checked]]>
  </prop>);
			my %vals = ('hosttemplate_id' => $profile{'host_template_id'});
			my $result = StorProc->update_obj('hosts','hostprofile_id',$profile{'hostprofile_id'},\%vals);
			if ($result =~ /^Error/) { push @errors, $result }
			my @errs = StorProc->host_profile_apply($profile{'hostprofile_id'},\@hosts);
			if (@errs) { push (@errors,@errs) }
			my %vals = ('hostextinfo_id' => $profile{'host_extinfo_id'});
			my $result = StorProc->update_obj('hosts','hostprofile_id',$profile{'hostprofile_id'},\%vals);
			if ($result =~ /^Error/) { push @errors, $result }
		}
		$data .= qq(
  <prop name="apply_services"><![CDATA[$apply_services]]>
  </prop>);

		my ($cnt, $err) = StorProc->service_profile_apply(\@profiles,$apply_services,\@hosts);
		if ($err) { push (@errors, @{$err}) }

		$data .= "\n</data>\n";
		my %value = ('data' => $data);
		my $result = StorProc->update_obj('profiles_host','name',$name,\%value);
		if ($result =~ /^Error/) { push @errors, $result }
		if ($enable_externals) {
			my %where = ('hostprofile_id' => $profile{'hostprofile_id'});
			my @externals = StorProc->fetch_list_where('external_host_profile','external_id',\%where);
			foreach my $hid (@hosts) {
				my $result = StorProc->delete_all('external_host','host_id',$hid);
				if ($result =~ /^Error/) { push @errors, $result }
				foreach my $ext (@externals) {
					my %e = StorProc->fetch_one('externals','external_id',$ext);
					my @vals = ($ext,$hid,$e{'display'});
					$result = StorProc->insert_obj('external_host',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
		}
		unless (@errors) { $obj_view = 'applied' }
	} elsif ($query->param('rename')) {
		if ($query->param('new_name')) {
			my $new_name = $query->param('new_name');
			$new_name =~ s/^\s+|\s+$//;
			my %n = StorProc->fetch_one('profiles_host','name',$new_name);
			if ($n{'name'}) {
				push @errors, "A host profile $new_name already exists.";
			} else {
				my %values = ('name' => $new_name);
				my $result = StorProc->update_obj('profiles_host','name',$name,\%values);				
				if ($result =~ /error/i) {
					push @errors, $result;
				} else {
					$name = $new_name;
					$refresh_left = 1;
					$obj_view = 'host_detail';
				}
			}
		} else {
			$obj_view = 'rename';
		}
	} elsif ($query->param('delete') || $query->param('confirm_delete')) {
		my %w = ('hostprofile_id' => $profile{'hostprofile_id'});
		my @hids = StorProc->fetch_list_where('hosts','host_id',\%w);
		if ($query->param('confirm_delete')) {
			my %values = ('hostprofile_id' => '0');
			my $result = StorProc->update_obj('hosts','hostprofile_id',$profile{'hostprofile_id'},\%values);
			if ($result =~ /^Error/) { push @errors, $result }
			$result = StorProc->update_obj('hostgroups','hostprofile_id',$profile{'hostprofile_id'},\%values);
			if ($result =~ /^Error/) { push @errors, $result }
			$result = StorProc->delete_all('profiles_host','hostprofile_id',$profile{'hostprofile_id'});
			if ($result =~ /^Error/) { push @errors, $result }
			unless (@errors) { 
				$refresh_left = 1;
				$obj_view = 'deleted';
			}
		} elsif ($query->param('task') eq 'No') {
			$obj_view = 'host_detail';
		} else {
			foreach my $name ($query->param) {
				unless ($name eq 'nocache') { $hidden{$name} = $query->param($name) }
			}
			delete $hidden{'task'};
			$obj_view = 'delete';
		}
	}
	my %docs = Doc->host_profile();
	my %save = ('name' => 'save','value' => 'Save');
	my %apply = ('name' => 'apply','value' => 'Apply');
	my %export = ('name' => 'export','value' => 'Export');
	my %obj = ();
	$form .= Forms->header($page_title,$session_id,$top_menu,'',$refresh_left);
	if ($obj_view eq 'host_detail') {
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->text_box('Description:','description',$profile{'description'},$textsize{'description'},'',$docs{'description'});
		$form .= build_host_template($name);
		my @members = StorProc->fetch_list('extended_host_info_templates','name'); 
		my %w = ('hostextinfo_id' => $profile{'host_extinfo_id'});
		my %t = StorProc->fetch_one_where('extended_host_info_templates',\%w);
		$form .= Forms->list_box('Extended host info template:','extended_info',\@members,$t{'name'},'',$docs{'extended_host_info_template'});
		my $path = $query->param('path');
		$hidden{'obj_view'} = 'host_detail';
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,\%delete,\%rename,\%export,\%close,$tab++);
	} elsif ($obj_view eq 'parents') {
		my @parents = StorProc->get_profile_parent($profile{'hostprofile_id'});
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Parents',$docs{'parents'});
		my @nonmembers = StorProc->fetch_list('hosts','name');
		$form .= Forms->members('Parents:','parents',\@parents,\@nonmembers,'','',$docs{'parents'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'hostgroups') {
		my @hostgroups = StorProc->get_profile_hostgroup($profile{'hostprofile_id'});
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Hostgroups',$docs{'hostgroups'});
		my @nonmembers = StorProc->fetch_list('hostgroups','name'); 
		$form .= Forms->members('Hostgroups:','hostgroups',\@hostgroups,\@nonmembers,'','',$docs{'hostgroups'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'escalations') {
		my $host_escalation = $query->param('host_escalation');
		my $service_escalation = $query->param('service_escalation');
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Escalations',$docs{'escalations'});
		unless ($host_escalation) {
			my %w = ('tree_id' => $profile{'host_escalation_id'});
			my %t = StorProc->fetch_one_where('escalation_trees',\%w);
			$host_escalation = $t{'name'};
		}
		my %where = ('type' => 'host');
		my @members = StorProc->fetch_list_where('escalation_trees','name',\%where);
		$form .= Forms->list_box_submit('Host escalation:','host_escalation',\@members,$host_escalation,'',$docs{'host_escalation'});
		if ($host_escalation) {
			my ($ranks, $templates) = StorProc->get_tree_detail($host_escalation);
			my %ranks = %{$ranks};
			my %templates = %{$templates};
			$form .= Forms->escalation_tree(\%ranks,\%templates,'escalations');
		}
		unless ($service_escalation) {
			my %w = ('tree_id' => $profile{'service_escalation_id'});
			my %t = StorProc->fetch_one_where('escalation_trees',\%w);
			$service_escalation = $t{'name'};
		}
		my %where = ('type','service');
		@members = StorProc->fetch_list_where('escalation_trees','name',\%where);
		$form .= Forms->list_box_submit('Service escalation:','service_escalation',\@members,$service_escalation,'',$docs{'service_escalation'});
		if ($service_escalation) {
			my ($ranks, $templates) = StorProc->get_tree_detail($service_escalation);
			my %ranks = %{$ranks};
			my %templates = %{$templates};
			$form .= Forms->escalation_tree(\%ranks,\%templates,'escalations');
		}
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'externals') {
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		my @members = StorProc->get_profile_external($profile{'hostprofile_id'});
		my %where = ('type' => 'host');
		my @nonmembers = StorProc->fetch_list_where('externals','name',\%where);
		$form .= Forms->members('External:','externals',\@members,\@nonmembers);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'service_profiles') {
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Service Profiles',$docs{'service_profiles'});
		my @members = ();
		my %w = ('hostprofile_id' => $profile{'hostprofile_id'});
		my @sids = StorProc->fetch_list_where('profile_host_profile_service','serviceprofile_id',\%w);
		foreach (@sids) {
			my %s = StorProc->fetch_one('profiles_service','serviceprofile_id',$_);
			if ($s{'name'}) { push @members, $s{'name'} }
		}
		my @nonmembers = StorProc->fetch_list('profiles_service','name');
		$form .= Forms->members('Service profiles:','service_profiles',\@members,\@nonmembers,'','20',$docs{'services'});
		$hidden{'obj_view'} = 'service_profiles';
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'assign_hosts') {
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		my %w = ('hostprofile_id' => $profile{'hostprofile_id'});
		my @members = StorProc->fetch_list_where('hosts','name',\%w);
		my @nonmembers = StorProc->fetch_list('hosts','name');
		$form .= Forms->wizard_doc('Assign Hosts',$docs{'assign_hosts'});
		$form .= Forms->members('Hosts:','hosts',\@members,\@nonmembers,'','20',$docs{'hosts'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'assign_hostgroups') {
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		my %w = ('hostprofile_id' => $profile{'hostprofile_id'});
		my @members = StorProc->fetch_list_where('hostgroups','name',\%w);
		my @nonmembers = StorProc->fetch_list('hostgroups','name');
		$form .= Forms->wizard_doc('Assign Hostgroups',$docs{'assign_hostgroups'});
		$form .= Forms->members('Hostgroups:','hostgroups',\@members,\@nonmembers,'','20',$docs{'hostgroups'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'apply') {
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		$form .= Forms->wizard_doc('Apply',$docs{'apply'});
		$form .= Forms->apply_select($view,\%profile,$nagios_ver);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%apply,$tab++);
	} elsif ($obj_view eq 'applied') {
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		my @message = ("Changes to $name applied to hosts.");
		$form .= Forms->form_message('Updated:',\@message,'row1');					
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%continue,$tab++);

	} elsif ($obj_view eq 'exported') {
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		my @message = ("Host profile $name saved to /tmp/$name.xml.");
		$form .= Forms->form_message('Export:',\@message,'row1');					
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%continue,$tab++);
	} elsif ($obj_view eq 'saved') {
		my %apply = ('name' => 'apply','value' => 'Apply to Hosts');
		$form .= Forms->host_profile_top($name,$session_id,$obj_view,$auth_add{'externals'},\%obj);
		
		my $message = "Changes to profile accepted.";
		$form .= Forms->display_hidden('Saved','',$message);				

		$form .= Forms->hidden(\%hidden);
		if ($hidden{'apply'}) {
			$form .= Forms->form_bottom_buttons(\%apply,$tab++);
		} else {
			$form .= Forms->form_bottom_buttons();
		}
	} elsif ($obj_view eq 'rename') {
		$form .= Forms->form_top('Rename Host Profile','');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Name:','name',$name,$textsize{'name'},'',$docs{'name'});
		$form .= Forms->text_box('Rename:','new_name','',$textsize{'name'},'',$docs{'name'});
		$hidden{'obj_view'} = 'rename';
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%rename,\%cancel,$tab++);
	} elsif ($obj_view eq 'delete') {
		my $message = qq(Are you sure you want to remove $name?);
		$form .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden);
	} elsif ($obj_view eq 'deleted') {
		$form .= Forms->form_top('Service Profile','');
		$form .= Forms->display_hidden('Deleted:','deleted',"$name removed");
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%continue,$tab++);
	} elsif ($obj_view eq 'new') {
		my $description = $query->param('description');
		my $template = $query->param('template');
		$form .= Forms->form_top('New Host Profile','');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->text_box('Name:','name',$name,$textsize{'name'},'',$docs{'name'});
		$form .= Forms->text_box('Description:','description',$description,$textsize{'description'},'',$docs{'description'});
		my @templates = StorProc->fetch_list('host_templates','name');
		$form .= Forms->list_box('Host template:','template',\@templates,$template,$required{'template'},$docs{'template'});
		$hidden{'obj_view'} = 'new';
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);
	}
	return $form;
}


#
############################################################################
# Service profile
#		

sub service_profile() {
	my $form = undef;
	my %docs = Doc->service_profiles();
	@errors = ();
	my $obj_view = $query->param('obj_view');
	my $name = $query->param('name');
	my %profile = StorProc->fetch_one('profiles_service','name',$name);
	my @message = ();
	if ($query->param('add')) {
		$name =~ s/^\s+|\s+$//;
		my %p = StorProc->fetch_one('profiles_service','name',$name);
		my $description = $query->param('description');
		unless ($p{'name'} || $name eq '') {
			my $data = "<?xml version=\"1.0\" ?>\n<data>\n</data>";
			my @values = ('',$name,$description,$data);
			my $id = StorProc->insert_obj_id('profiles_service',\@values,'serviceprofile_id');
			unless ($id =~ /^Error/) { 
				$profile{'description'} = $description;
				my @services = $query->param('services');
				foreach my $service (@services) {
					if ($service =~ /^\s+$/) { next	}
					my %s = StorProc->fetch_one('service_names','name',$service);
					my @vals = ($s{'servicename_id'},$id);
					my $result = StorProc->insert_obj('serviceprofile',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }
				}
				unless (@errors) {
					$obj_view = 'services';
				}
			} else {
				push @errors, $id;
			}
		} else {
			push @errors, "Check name field. It's either blank or a record exists";
			$name = undef;
		}
	} elsif ($query->param('close') || $query->param('cancel') || $query->param('continue')) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$obj_view = 'close';
	} elsif ($query->param('export')) {
		use MonarchProfileExport;
		my $results = ProfileExporter->service_profile($profile{'serviceprofile_id'});
		if ($results =~ /^Error/) { 
			push @errors, $results;
		} else {
			$obj_view = 'exported';
		}
	} elsif ($query->param('apply')) {
		my $hostgroups_select = $query->param('hostgroups_select');
		my $hosts_select = $query->param('hosts_select');
		my $services = $query->param('apply_services');

		my $data = "<?xml version=\"1.0\" ?>\n<data>";
		if ($hostgroups_select) { 
			$data .= qq(
  <prop name="hostgroups_select"><![CDATA[checked]]>
  </prop>);
		}
		if ($hosts_select) { 
			$data .= qq(
  <prop name="hosts_select"><![CDATA[checked]]>
  </prop>);
		}
		if ($services) { 
			$data .= qq(
  <prop name="apply_services"><![CDATA[$services]]>
  </prop>);
		}
		my @hosts = ();
		if ($hostgroups_select) {
			my %where = ('serviceprofile_id' => $profile{'serviceprofile_id'});
			my @hgs = StorProc->fetch_list_where('serviceprofile_hostgroup','hostgroup_id',\%where);
			foreach my $hg (@hgs) {
				%where = ('hostgroup_id' => $hg);
				my @hs = StorProc->fetch_list_where('hostgroup_host','host_id',\%where);
				push (@hosts,@hs);
			}
		}
		if ($hosts_select) {
			my %where = ('serviceprofile_id' => $profile{'serviceprofile_id'});
			my @hs = StorProc->fetch_list_where('serviceprofile_host','host_id',\%where);
			push (@hosts,@hs);
		}
		my @profiles = ($profile{'serviceprofile_id'});
		my ($cnt, $err) = StorProc->service_profile_apply(\@profiles,$services,\@hosts);
		@errors = @{$err};
		@message = ("$cnt hosts updated.");
		$data .= "\n</data>\n";
		my %value = ('data' => $data);
		my $result = StorProc->update_obj('profiles_service','name',$name,\%value);
		if ($result =~ /^Error/) { push @errors, $result }
		unless (@errors) { $obj_view = 'applied' }
	} elsif ($query->param('save')) {
		if ($obj_view eq 'services') {
			my $description = $query->param('description');
			my %values = ();
			$values{'description'} = $description;
			my $result = StorProc->update_obj('profiles_service','name',$name,\%values);
			if ($result =~ /^Error/) { push @errors, $result}
			$result = StorProc->delete_all('serviceprofile','serviceprofile_id',$profile{'serviceprofile_id'});
			if ($result =~ /^Error/) { 
				push @errors, $result;
			} else {
				my @services = $query->param('services');
				my $cnt = 0;
				foreach my $service (@services) {
					if ($service =~ /^\s+$/) { next	}
					my %s = StorProc->fetch_one('service_names','name',$service);
					my @vals = ($s{'servicename_id'},$profile{'serviceprofile_id'});
					my $result = StorProc->insert_obj('serviceprofile',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }
					$cnt++;
				}
				@message = ("$name has $cnt servies assigned.");
			}
			unless (@errors) { $obj_view = 'saved' }
			@message = ("Changes to $name accepted");
		} elsif ($obj_view eq 'assign_hosts') {
			my @hosts = $query->param('hosts');
			my %w = ('serviceprofile_id' => $profile{'serviceprofile_id'});
			my $result = StorProc->delete_one_where('serviceprofile_host',\%w);
			if ($result =~ /Error/) {
				push @errors, $result;
			} else {
				my $cnt = 0;
				foreach my $host (@hosts) {
					if ($host =~ /^\s+$/) { next	}
					my %h = StorProc->fetch_one('hosts','name',$host);
					my @vals = ($profile{'serviceprofile_id'},$h{'host_id'});
					my $result = StorProc->insert_obj('serviceprofile_host',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }
					$cnt++;
				}
				@message = ("$name has $cnt hosts assigned.");
			}
			unless (@errors) { $obj_view = 'saved' }
		} elsif ($obj_view eq 'assign_hostgroups') {
			my @hostgroups = $query->param('hostgroups');
			my %w = ('serviceprofile_id' => $profile{'serviceprofile_id'});
			my $result = StorProc->delete_one_where('serviceprofile_hostgroup',\%w);
			if ($result =~ /Error/) {
				push @errors, $result;
			} else {
				my $cnt = 0;
				foreach my $hostgroup (@hostgroups) {
					if ($hostgroup =~ /^\s+$/) { next	}
					my %h = StorProc->fetch_one('hostgroups','name',$hostgroup);
					my @vals = ($profile{'serviceprofile_id'},$h{'hostgroup_id'});
					my $result = StorProc->insert_obj('serviceprofile_hostgroup',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }
					$cnt++;
				}
				@message = ("$name has $cnt hostgroups assigned.");
			}
			unless (@errors) { $obj_view = 'saved' }
		} elsif ($obj_view eq 'host_profiles') {
			my @profiles = $query->param('host_profiles');
			my %w = ('serviceprofile_id' => $profile{'serviceprofile_id'});
			my $result = StorProc->delete_one_where('profile_host_profile_service',\%w);
			if ($result =~ /Error/) {
				push @errors, $result;
			} else {
				my $cnt = 0;
				foreach my $profile (@profiles) {
					if ($profile =~ /^\s+$/) { next	}
					my %h = StorProc->fetch_one('profiles_host','name',$profile);
					my @vals = ($h{'hostprofile_id'},$profile{'serviceprofile_id'});
					my $result = StorProc->insert_obj('profile_host_profile_service',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }
					$cnt++;
				}
				@message = ("$name has $cnt host profiles assigned.");
			}
			unless (@errors) { $obj_view = 'saved' }
		}
	} elsif ($query->param('rename')) {
		if ($query->param('new_name')) {
			my $new_name = $query->param('new_name');
			$new_name =~ s/^\s+|\s+$//;
			if ($new_name eq $name) {
				$obj_view = 'services';
			} else {
				my %n = StorProc->fetch_one('profiles_host','name',$new_name);
				if ($n{'name'}) {
					push @errors, "A host profile $new_name already exists.";
				} else {
					my %values = ('name' => $new_name);
					my $result = StorProc->update_obj('profiles_service','name',$name,\%values);				
					if ($result =~ /error/i) {
						push @errors, $result;
					} else {
						$name = $new_name;
						$refresh_left = 1;
						$obj_view = 'services';
					}
				}
			}
		} else {
			$obj_view = 'rename';
		}
	} elsif ($query->param('delete') || $query->param('confirm_delete')) {
		my $id = $query->param('id');
		my %w = ('serviceprofile_id' => $id);
		my @hp = StorProc->fetch_list_where('profile_host_profile_service','hostprofile_id',\%w);
		my @hids = StorProc->fetch_list_where('serviceprofile_host','host_id',\%w);
		unless ($hids[0] || $hp[0]) {
			if ($query->param('confirm_delete')) {
				my $result = StorProc->delete_all('profiles_service','serviceprofile_id',$id);
				if ($result =~ /^Error/) { push @errors, $result }
				unless (@errors) { 
					$refresh_left = 1;
					$obj_view = 'deleted';
				}
			} elsif ($query->param('task') eq 'No') {
				$obj_view = 'services';
			} else {
				foreach my $name ($query->param) {
					unless ($name eq 'nocache') { $hidden{$name} = $query->param($name) }
				}
				$hidden{'delete'} = 1;
				$obj_view = 'delete';
			}
		} else {
			push @errors, "Cannot delete $name while it is in use.";
		}
	} elsif ($query->param('close')) {
		$obj_view = undef;
	}	
	my %save = ('name' => 'save','value' => 'Save');
	my %apply = ('name' => 'apply','value' => 'Apply');
	my %export = ('name' => 'export','value' => 'Export');
	my %objs = ();
	unless ($obj_view) { $obj_view = 'services' }
	$hidden{'obj_view'} = $obj_view;
	$form .= Forms->header($page_title,$session_id,$top_menu,'',$refresh_left);
	if ($obj_view eq 'services') {
		my @members = ();
		$form .= Forms->service_profile_top($name,$session_id,$obj_view,\%objs,$hidden{'selected'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$hidden{'id'} = $profile{'serviceprofile_id'};
		my %w = ('serviceprofile_id' => $profile{'serviceprofile_id'});
		my @sids = StorProc->fetch_list_where('serviceprofile','servicename_id',\%w);
		foreach (@sids) {
			my %s = StorProc->fetch_one('service_names','servicename_id',$_);
			if ($s{'name'}) { push @members, $s{'name'} }
		}
		my $description = $profile{'description'};
		$form .= Forms->text_box('Description:','description',$description,$textsize{'description'},'',$docs{'description'});
		my @nonmembers = StorProc->fetch_list('service_names','name'); 
		$form .= Forms->members('Services:','services',\@members,\@nonmembers,'','30',$docs{'services'});
		my $path = $query->param('path');
		$form .= Forms->hidden(\%hidden);
		if ($auth_delete{'profiles'}) {
			$form .= Forms->form_bottom_buttons(\%save,\%delete,\%rename,\%export,\%close,$tab++);
		} else {
			$form .= Forms->form_bottom_buttons(\%save,\%rename,\%export,\%close,$tab++);
		}
	} elsif ($obj_view eq 'assign_hosts') {
		$form .= Forms->service_profile_top($name,$session_id,$obj_view,\%objs,$hidden{'selected'});
		$form .= Forms->wizard_doc('Assign Hosts',$docs{'assign_hosts'});
		my @members = ();
		my %w = ('serviceprofile_id' => $profile{'serviceprofile_id'});
		my @hids = StorProc->fetch_list_where('serviceprofile_host','host_id',\%w);
		foreach (@hids) {
			my %h = StorProc->fetch_one('hosts','host_id',$_);
			if ($h{'name'}) { push @members, $h{'name'} }
		}
		my @nonmembers = StorProc->fetch_list('hosts','name'); 
		$form .= Forms->members('Hosts:','hosts',\@members,\@nonmembers,'','30',$docs{'hosts'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'assign_hostgroups') {
		$form .= Forms->service_profile_top($name,$session_id,$obj_view,\%objs,$hidden{'selected'});
		$form .= Forms->wizard_doc('Assign Hostgroups',$docs{'assign_hostgroups'});
		my @members = ();
		my %w = ('serviceprofile_id' => $profile{'serviceprofile_id'});
		my @hids = StorProc->fetch_list_where('serviceprofile_hostgroup','hostgroup_id',\%w);
		foreach (@hids) {
			my %h = StorProc->fetch_one('hostgroups','hostgroup_id',$_);
			if ($h{'name'}) { push @members, $h{'name'} }
		}
		my @nonmembers = StorProc->fetch_list('hostgroups','name'); 
		$form .= Forms->members('Hostgroups:','hostgroups',\@members,\@nonmembers,'','30',$docs{'hosts'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'host_profiles') {
		$form .= Forms->service_profile_top($name,$session_id,$obj_view,\%objs,$hidden{'selected'});
		$form .= Forms->wizard_doc('Host Profiles',$docs{'host_profiles'});
		my @members = ();
		my %w = ('serviceprofile_id' => $profile{'serviceprofile_id'});
		my @hids = StorProc->fetch_list_where('profile_host_profile_service','hostprofile_id',\%w);
		foreach (@hids) {
			my %h = StorProc->fetch_one('profiles_host','hostprofile_id',$_);
			if ($h{'name'}) { push @members, $h{'name'} }
		}
		my @nonmembers = StorProc->fetch_list('profiles_host','name'); 
		$form .= Forms->members('Host profiles:','host_profiles',\@members,\@nonmembers,'','30',$docs{'host_profiles'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);

	} elsif ($obj_view eq 'apply') {
		my %doc = ();
		$form .= Forms->service_profile_top($name,$session_id,$obj_view,\%objs,$hidden{'selected'});
		$form .= Forms->wizard_doc('Apply',$docs{'apply'});
		$form .= Forms->apply_select($view,\%profile,$nagios_ver);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%apply,$tab++);
	} elsif ($obj_view eq 'applied') {
		$form .= Forms->service_profile_top($name,$session_id,$obj_view,\%objs,$hidden{'selected'});
		my @message = ("Changes to $name applied to hosts.");
		$form .= Forms->form_message('Updated:',\@message,'row1');					
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%continue,$tab++);
	} elsif ($obj_view eq 'exported') {
		$form .= Forms->service_profile_top($name,$session_id,$obj_view,\%objs,$hidden{'selected'});
		my @message = ("Service profile $name saved to /tmp/service-profile-$name.xml.");
		$form .= Forms->form_message('Export:',\@message,'row1');					
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%continue,$tab++);
	} elsif ($obj_view eq 'saved') {
		$form .= Forms->service_profile_top($name,$session_id,$obj_view,\%objs,$hidden{'selected'});
		$form .= Forms->form_message('Updated:',\@message,'row1');					
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%close);
	} elsif ($obj_view eq 'rename') {
		$form .= Forms->form_top('Rename Service Profile','');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Name:','name',$name,$textsize{'name'},'',$docs{'name'});
		$form .= Forms->text_box('Rename:','new_name','',$textsize{'name'},'',$docs{'name'});
		$hidden{'obj_view'} = 'rename';
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%rename,\%cancel,$tab++);
	} elsif ($obj_view eq 'delete') {
		my $message = qq(Are you sure you want to remove $name?);
		delete $hidden{'task'};
		$form .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden);
	} elsif ($obj_view eq 'deleted') {
		$form .= Forms->form_top('Service Profile','');
		$form .= Forms->display_hidden('Deleted:','deleted',"$name removed");
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%continue,$tab++);
	} elsif ($obj_view eq 'new') {
		my $description = $query->param('description');
		$form .= Forms->form_top('New Service Profile','');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->text_box('Name:','name',$name,$textsize{'name'},'',$docs{'name'});
		$form .= Forms->text_box('Description:','description',$description,$textsize{'description'},'',$docs{'description'});
		$hidden{'obj_view'} = 'new';
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);
	}
	return $form;
}

############################################################################
# Services
#		

sub service() {
	my $host_id = $query->param('host_id');
	my $form = undef;
	my $obj_view = $query->param('obj_view');
	my $name = $query->param('name');
	$name =~ s/^\s+|\s+$//;
	my %service = StorProc->fetch_one('service_names','name',$name);
	my $host = $query->param('host');
	my $test_results = undef;
	my $message_applied = undef;
	if ($query->param('add')) {
		if ($name) {
			$name =~ s/^\s+|\s+$//;
			my %p = StorProc->fetch_one('service_names','name',$name);
			unless ($p{'name'}) {
				my $template = $query->param('template');
				if ($template) {
					my %s = StorProc->fetch_one('service_templates','name',$template);
					my @values = ('',$name,'',$s{'servicetemplate_id'},'','','','','');
					my $id = StorProc->insert_obj_id('service_names',\@values,'servicename_id');
					if ($id =~ /^Error/) { 
						push @errors, $id;
						$obj_view = 'new';
					} else {
						$obj_view = 'service_detail';
					}	
				} else {
					push @errors, "Template required";
					$obj_view = 'new';
					$required{'template'} = 1;
				}
			} else {
				push @errors, "Service name $name already exists";
				$obj_view = 'new';
					$required{'name'} = 1;
					$required{'template'} = 1;
			}
		} else {					
			push @errors, "Service name required";
			$obj_view = 'new';
		}
	} elsif ($query->param('close') || $query->param('continue') || $query->param('cancel')) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$obj_view = undef;
	} elsif ($query->param('next')) {
		if ($name) {
			if ($service{'servicename_id'}) {
				push @errors, "A service with name $name already exists.";
			} else {
				my $clone_service = $query->param('clone_service');
				my $apply_profile = $query->param('apply_profile');
				@errors = StorProc->clone_service($name,$clone_service,$apply_profile);
				unless (@errors) {
					%service = StorProc->fetch_one('service_names','name',$name);
					$obj_view = 'service_detail';
				}
			}

		}
	} elsif ($query->param('apply')) {
		my $apply_check = $query->param('apply_check');
		my $apply_escalation_service = $query->param('apply_escalation_service');
		my $apply_contact_service = $query->param('apply_contact_service');
		my $apply_extinfo_service = $query->param('apply_extinfo_service');
		my $apply_dependencies = $query->param('apply_dependencies');
		my $services = $query->param('apply_services');
		my $data = "<?xml version=\"1.0\" ?>\n<data>";
		if ($services eq 'replace') { 
			$data .= qq(
  <prop name="apply_services"><![CDATA[replace]]>
  </prop>);
			my %values = ('servicetemplate_id' => $service{'template'});
			my $result = StorProc->update_obj('services','servicename_id',$service{'servicename_id'},\%values);
			if ($result =~ /Error/) { push @errors, $result }
			my @errs = StorProc->service_replace(\%service);
			if ($errs[0] =~ /applied/) {
				$message_applied = $errs[0];
			} else {
				push (@errors,@errs);
			}
		}
		if ($services eq 'merge') { 
			$data .= qq(
  <prop name="apply_services"><![CDATA[merge]]>
  </prop>);
			my %values = ('servicetemplate_id' => $service{'template'});
			my $result = StorProc->update_obj('services','servicename_id',$service{'servicename_id'},\%values);
			if ($result =~ /Error/) { push @errors, $result }
			my @errs = StorProc->service_merge(\%service);
			if ($errs[0] =~ /applied/) {
				$message_applied = $errs[0];
			} else {
				push (@errors,@errs);
			}
		}
		if ($apply_extinfo_service) { 
			$data .= qq(
  <prop name="apply_extinfo_service"><![CDATA[checked]]>
  </prop>);
			my %values = ('serviceextinfo_id' => $service{'extinfo'});
			my $result = StorProc->update_obj('services','servicename_id',$service{'servicename_id'},\%values);
			if ($result =~ /^Error/) { push @errors, $result }
		}
		if ($apply_contact_service) { 
			$data .= qq(
  <prop name="apply_contact_service"><![CDATA[checked]]>
  </prop>);
			my %where = ('servicename_id' => $service{'servicename_id'});
			my @sids = StorProc->fetch_list_where('services','service_id',\%where);

#			%where = ('type' => 'service_names','object' => $service{'servicename_id'});
#			my @cgids = StorProc->fetch_list_where('contactgroup_assign','contactgroup_id',\%where);
			%where = ('servicename_id' => $service{'servicename_id'});
			my @cgids = StorProc->fetch_list_where('contactgroup_service_name','contactgroup_id',\%where);

			foreach my $sid (@sids) {
#				%where = ('object' => $sid,'type' => 'services');
#				my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
				%where = ('service_id' => $sid);
				my $result = StorProc->delete_one_where('contactgroup_service',\%where);
				if ($result =~ /^Error/) { push @errors, $result }
				foreach my $cgid (@cgids) {

#					my @vals = ($cgid,'services',$sid);
#					my $result = StorProc->insert_obj('contactgroup_assign',\@vals);
					my @vals = ($cgid,$sid);
					my $result = StorProc->insert_obj('contactgroup_service',\@vals);

					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
		}
		if ($apply_escalation_service) { 
			$data .= qq(
  <prop name="apply_escalation_service"><![CDATA[checked]]>
  </prop>);
			my %values = ('escalation_id' => $service{'escalation'});
			my $result = StorProc->update_obj('services','servicename_id',$service{'servicename_id'},\%values);
			if ($result =~ /^Error/) { push @errors, $result }
		}
		if ($apply_check) { 
			$data .= qq(
  <prop name="apply_check"><![CDATA[checked]]>
  </prop>);
			my %values = ('check_command' => $service{'check_command'},'command_line' => $service{'command_line'});
			my $result = StorProc->update_obj('services','servicename_id',$service{'servicename_id'},\%values);
			if ($result =~ /^Error/) { push @errors, $result }
		}
		if ($apply_dependencies) { 
			$data .= qq(
  <prop name="apply_dependencies"><![CDATA[checked]]>
  </prop>);
			my @result = StorProc->update_dependencies($service{'servicename_id'});
			if (@result) { push (@errors,@result) }
		}
		$data .= "\n</data>\n";
		my %value = ('data' => $data);
		my $result = StorProc->update_obj('service_names','name',$name,\%value);
		if ($result =~ /^Error/) { push @errors, $result }
		if ($enable_externals) {
			my %w = ('servicename_id' => $service{'servicename_id'});
			my @externals = StorProc->fetch_list_where('external_service_names','external_id',\%w);
			my %services = StorProc->fetch_list_hash_array('services',\%w);
			foreach my $sid (keys %services) {
				my $result = StorProc->delete_all('external_service','service_id',$sid);
				foreach my $ext (@externals) {
					my %external = StorProc->fetch_one('externals','external_id',$ext);	
					my @vals = ($ext,$services{$sid}[1],$sid,$external{'display'});
					my $result = StorProc->insert_obj('external_service',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
		}
		unless (@errors) { $obj_view = 'applied' }
	} elsif ($query->param('test_command')) {	
		my $arg_string = $query->param('command_line');
		my $command = $query->param('command');
		my %cmd = StorProc->fetch_one('commands','name',$command);
		$test_results .= StorProc->test_command($command,$cmd{'command_line'},$host,$arg_string,$monarch_home,$name);	
	} elsif ($query->param('save')) {
		if ($obj_view eq 'service_detail') {
			my %values = ();
			$hidden{'servicename_id'} = $service{'servicename_id'};
			my $ext_info = $query->param('ext_info');
			my %x = StorProc->fetch_one('extended_service_info_templates','name',$ext_info);
			my $escalation = $query->param('escalation');
			my %e = StorProc->fetch_one('escalation_trees','name',$escalation);
			my $template = $query->param('template');
			my %t = StorProc->fetch_one('service_templates','name',$template);
			if ($host_id) {
				my %values = ();
				my $service_id = $query->param('service_id');
				$hidden{'service_id'} = $service_id;
				my %s = StorProc->fetch_one('service_names','name',$name);
				my $ext_info = $query->param('ext_info');
				my %x = StorProc->fetch_one('extended_service_info_templates','name',$ext_info);
				my $escalation = $query->param('escalation');
				my %e = StorProc->fetch_one('escalation_trees','name',$escalation);
				my $template = $query->param('template');
				my %t = StorProc->fetch_one('service_templates','name',$template);
				my %data = parse_query('service_overrides','service_overrides');
				my %vals = ('serviceextinfo_id' => $x{'serviceextinfo_id'},'escalation_id' => $s{'tree_id'},'servicetemplate_id' => $t{'servicetemplate_id'});
				my $result = StorProc->update_obj('services','service_id',$service_id,\%vals);
				if ($result =~ /^Error/) { push @errors, $result }
				my %where = ('service_id' => $properties{'service_id'});
				my $result = StorProc->delete_one_where('service_overrides',\%where);
				if ($result =~ /^Error/) { push @errors, $result }
				if ($data{'check_period'} || $data{'notification_period'} || $data{'event_handler'} || $data{'data'}) {
					my @values = ($service_id,$data{'check_period'},$data{'notification_period'},$data{'event_handler'},$data{'data'});
					my $result = StorProc->insert_obj('service_overrides',\@values);
					if ($result =~ /^Error/) { push @errors, $result }
				}

#				my %where = ('type' => 'services','object' => $service_id);
#				my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
				my %where = ('service_id' => $service_id);
				my $result = StorProc->delete_one_where('contactgroup_service',\%where);

				if ($result =~ /^Error/) { push @errors, $result }
				unless ($query->param('contactgroup_override')) {
					my @mems = $query->param('contactgroup');
					foreach (@mems) {
						my %cg = StorProc->fetch_one('contactgroups','name',$_);

#						my @vals = ($cg{'contactgroup_id'},'services',$service_id);
#						$result = StorProc->insert_obj('contactgroup_assign',\@vals);
						my @vals = ($cg{'contactgroup_id'},$service_id);
						$result = StorProc->insert_obj('contactgroup_service',\@vals);

						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
			} else {
				my %data = parse_query('service_overrides','service_overrides');
				my %vals = ('extinfo' => $x{'serviceextinfo_id'},'escalation' => $e{'tree_id'},'template' => $t{'servicetemplate_id'});
				my $result = StorProc->update_obj('service_names','servicename_id',$service{'servicename_id'},\%vals);
				if ($result =~ /^Error/) { push @errors, $result }
				my %where = ('servicename_id' => $service{'servicename_id'});
				my $result = StorProc->delete_one_where('servicename_overrides',\%where);
				if ($result =~ /^Error/) { push @errors, $result }
				if ($data{'check_period'} || $data{'notification_period'} || $data{'event_handler'} || $data{'data'}) {
					my @values = ($service{'servicename_id'},$data{'check_period'},$data{'notification_period'},$data{'event_handler'},$data{'data'});
					my $result = StorProc->insert_obj('servicename_overrides',\@values);
					if ($result =~ /^Error/) { push @errors, $result }
				}

#				my %where = ('type' => 'service_names','object' => $service{'servicename_id'});
#				my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
				%where = ('servicename_id' => $service{'servicename_id'});
				my $result = StorProc->delete_one_where('contactgroup_service_name',\%where);

				if ($result =~ /^Error/) { push @errors, $result }
				unless ($query->param('contactgroup_override')) {
					my @mems = $query->param('contactgroup');
					foreach (@mems) {
						my %cg = StorProc->fetch_one('contactgroups','name',$_);

#						my @vals = ($cg{'contactgroup_id'},'service_names',$service{'servicename_id'});
#						$result = StorProc->insert_obj('contactgroup_assign',\@vals);
						my @vals = ($cg{'contactgroup_id'},$service{'servicename_id'});
						$result = StorProc->insert_obj('contactgroup_service_name',\@vals);

						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
			}
			unless (@errors) { 
				$obj_view = 'saved';
			}
		} elsif ($obj_view eq 'service_check') {
			my $service_name = $query->param('service_name');
			my $service_id = $query->param('service_id');
			$hidden{'service_name'} = $service_name;
			$hidden{'service_id'} = $service_id;
			my $check_command = $query->param('command');
			my $command_line = $query->param('command_line');
			if ($host_id) {
				my $service_id = $query->param('service_id');
				my $check_command = $query->param('command');
				my $command_line = $query->param('command_line');
				if ($query->param('inherit')) {
					my $required = $query->param('required');
					unless ($required) {
						my %vals = ('check_command' => '','command_line' => '');
						my $result = StorProc->update_obj('services','service_id',$service_id,\%vals);
						if ($result =~ /^Error/) { push @errors, $result }
					} else {
						push @errors, "The service check is not defined on a template so it must be defined here.";
					}
				} else {
					my %check = StorProc->fetch_one('commands','name',$check_command);
					my %vals = ('check_command' => $check{'command_id'},'command_line' => $command_line);
					my $result = StorProc->update_obj('services','service_id',$service_id,\%vals);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			} else {
				if ($query->param('inherit')) {
					my $required = $query->param('required');
					unless ($required) {
						my %vals = ('check_command' => '','command_line' => '');
						my $result = StorProc->update_obj('service_names','servicename_id',$service{'servicename_id'},\%vals);
						if ($result =~ /^Error/) { push @errors, $result }
					} else {
						push @errors, "The service check is not defined on a template so it must be defined here.";
					}
				} else {
					my %check = StorProc->fetch_one('commands','name',$check_command);
					my %vals = ('check_command' => $check{'command_id'},'command_line' => $command_line);
					my $result = StorProc->update_obj('service_names','servicename_id',$service{'servicename_id'},\%vals);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}	
			
			unless (@errors) { 
				$obj_view = 'saved';
				$hidden{'selected'} = 'service_check';
			}
		} elsif ($obj_view eq 'service_profiles') {
			my @profiles = $query->param('profiles');
			my $result = StorProc->delete_all('serviceprofile','servicename_id',$service{'servicename_id'});
			if ($result =~ /^Error/) { push @errors, $result }						
			foreach my $prof (@profiles) {
				my %p = StorProc->fetch_one('profiles_service','name',$prof);
				my @values = ($service{'servicename_id'},$p{'serviceprofile_id'});
				$result = StorProc->insert_obj('serviceprofile',\@values);
				if ($result =~ /^Error/) { push @errors, $result }						
			}
			unless (@errors) { 
				$obj_view = 'saved';
			}
		}
	} elsif ($query->param('external_add')) {
		my @externals = $query->param('external');
		my $result = StorProc->delete_all('external_service_names','servicename_id',$hidden{'service_id'});
		if ($result =~ /^Error/) { push @errors, $result }						
		foreach my $ext (@externals) {
			my %e = StorProc->fetch_one('externals','name',$ext);
			my @values = ($e{'external_id'},$service{'servicename_id'});
			$result = StorProc->insert_obj('external_service_names',\@values);
			if ($result =~ /^Error/) { push @errors, $result }						
		}
 	} elsif ($query->param('remove_dependency')) {
 		my $dep_id = $query->param('dependency_id');
		if ($host_id) {
			my $dep_id = $query->param('dependency_id');
			my $result = StorProc->delete_all('service_dependency','id',$dep_id);
			if ($result =~ /^Error/) { push @errors, $result }
		} else {
			my $result = StorProc->delete_all('servicename_dependency','id',$dep_id);
			if ($result =~ /^Error/) { push @errors, $result }	
		}
	} elsif ($query->param('add_dependency')) {
		my $dependency = $query->param('dep_template');
		my $parent = $query->param('depend_on_host');
		if ($parent && $dependency) {
			if ($host_id) {
				my $dep_template = $query->param('dep_template');
				my $service_name = $query->param('service_name');
				my $service_id = $query->param('service_id');
				$hidden{'service_name'} = $service_name;
				$hidden{'service_id'} = $service_id;
				my $parent = $query->param('depend_on_host');
				my %p = StorProc->fetch_one('hosts','name',$parent);
				my %d = StorProc->fetch_one('service_dependency_templates','name',$dep_template);
				my %w = ('service_id' => $service_id,'host_id' => $properties{'host_id'},'depend_on_host_id' => $p{'host_id'},'template' => $d{'id'});
				my %check_dep = StorProc->fetch_one_where('service_dependency',\%w);	
				if ($dep_template && $service_id && $parent) {
					unless ($check_dep{'id'}) {
						my @values = ('',$service_id,$properties{'host_id'},$p{'host_id'},$d{'id'},'');
						my $result = StorProc->insert_obj('service_dependency',\@values);
						if ($result =~ /^Error/) { push @errors, $result }	
					} else {
						push @errors, "Already defined. Check existing dependencies";
					}
				}
			} else {
				my %dependency = StorProc->fetch_one('service_dependency_templates','name',$dependency);
				unless ($parent eq 'same host') {
					my %p = StorProc->fetch_one('hosts','name',$parent);
					$parent = $p{'host_id'};
				}
				my $check_dep = StorProc->check_dependency($service{'servicename_id'},$parent,$dependency{'id'});	
				unless ($check_dep) {
					my $result = StorProc->insert_dependency($service{'servicename_id'},$parent,$dependency{'id'});
					if ($result =~ /^Error/) { push @errors, $result }	
				} else {
					push @errors, "Already defined. Check existing dependencies";
				}
			}
		}
 	} elsif ($query->param('rename')) {
		if ($query->param('new_name')) {
			my $new_name = $query->param('new_name');
			$new_name =~ s/^\s+|\s+$//;
			if ($new_name eq $name) {
				$obj_view = 'service_detail';
			} else {
				my %n = StorProc->fetch_one('service_names','name',$new_name);
				if ($n{'name'} && $n{'name'} != /$new_name/i) {
					push @errors, "A Service $new_name already exists.";
				} else {
					my %values = ('name' => $new_name);
					my $result = StorProc->update_obj('service_names','name',$name,\%values);				
					if ($result =~ /error/i) {
						push @errors, $result;
					} else {
						$result = StorProc->delete_all('host_service','service',$name);
						if ($result =~ /^Error/) { push @errors, $result }
						$name = $new_name;
						$obj_view = 'service_detail';
						$refresh_left = 1;
					}
				}
			}	
		} else {
			$obj_view = 'rename';
		}
	} elsif ($query->param('delete') || $query->param('confirm_delete')) {
		my %sn = StorProc->fetch_one('service_names','name',$name);
		my %where = ('servicename_id' => $sn{'servicename_id'});
		if ($query->param('confirm_delete')) {
			my $result = StorProc->delete_all('service_names','name',$name);
			if ($result =~ /^Error/) { push @errors, $result }
			unless (@errors) {
				$result = StorProc->delete_one_where('services',\%where); 
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) {
				$result = StorProc->delete_one_where('serviceprofile',\%where); 
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) {
				$result = StorProc->delete_one_where('service_dependency_templates',\%where); 
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { 
				$result = StorProc->delete_all('host_service','service',$name);
				if ($result =~ /^Error/) { push @errors, $result }
				$form .= Forms->header($page_title,$session_id,$top_menu,'','1');
				$form .= Forms->form_top('Deleted','');
				my @message = ("$name");
				$form .= Forms->form_message('Removed:',\@message,'row1');			
				$form .= Forms->hidden(\%hidden);
				$form .= Forms->form_bottom_buttons(\%continue,$tab++);
				$name = undef;
				$obj_view = undef;
				$hidden{'name'} = undef;
			}
		} elsif ($query->param('task') eq 'No') {
			$obj_view = 'service_detail';
		} else {
			foreach my $name ($query->param) {
				unless ($name eq 'nocache') { $hidden{$name} = $query->param($name) }
			}
			$obj_view = 'delete';
		}
	} else {
		foreach my $param ($query->param) {
			if ($param =~ /remove_external_(\d+)/) {
				my $eid = $1;
				my %where = ('servicename_id' => $service{'servicename_id'},'external_id' => $eid);
				my $result = StorProc->delete_one_where('external_service_names',\%where);
				if ($result =~ /^Error/) { push @errors, $result }						
			}
		}
	}
	my %save = ('name' => 'save','value' => 'Save');
	my %apply = ('name' => 'apply','value' => 'Apply');
	my %objs = ('servicename_id' => $hidden{'servicename_id'});
	my %docs = Doc->services();
	$hidden{'name'} = $name;
	$hidden{'obj_view'} = $obj_view;
	$hidden{'servicename_id'} = $query->param('servicename_id');
	unless ($hidden{'servicename_id'}) { $hidden{'servicename_id'} = $service{'servicename_id'}	}
	$objs{'servicename_id'} = $hidden{'servicename_id'};
	$form .= Forms->header($page_title,$session_id,$top_menu,'',$refresh_left);
	if ($obj_view eq 'service_detail') {
		my $ext_info = $query->param('ext_info');
		my $escalation = $query->param('escalation');
		unless ($ext_info) {
			my %w = ('serviceextinfo_id' => $service{'extinfo'});
			my %e = StorProc->fetch_one_where('extended_service_info_templates',\%w);
			$ext_info = $e{'name'};
		}
		unless ($escalation) {
			my %w = ('tree_id' => $service{'escalation'});
			my %esc = StorProc->fetch_one_where('escalation_trees',\%w);
			$escalation = $esc{'name'};
		}
		$form .= Forms->service_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= build_service_detail($hidden{'servicename_id'});
		my @members = StorProc->fetch_list('extended_service_info_templates','name'); 
		$form .= Forms->list_box('Extended info template:','ext_info',\@members,$ext_info,'',$docs{'extinfo'});
		my %where = ('type' => 'service');
		@members = ('-no-escalation-');
		push (@members, StorProc->fetch_list_where('escalation_trees','name',\%where)); 
		$form .= Forms->list_box_submit('Escalation tree:','escalation',\@members,$escalation,'',$docs{'escalation'});
		if ($escalation) {
			my ($ranks, $templates) = StorProc->get_tree_detail($escalation);
			my %ranks = %{$ranks};
			my %templates = %{$templates};
			$form .= Forms->escalation_tree(\%ranks,\%templates,'service_detail');
		}
		$form .= Forms->hidden(\%hidden);
		if ($auth_delete{'services'}) {
			if ($host_id) {
				$form .= Forms->form_bottom_buttons(\%save,\%delete,\%close,$tab++);
			} else {
				$form .= Forms->form_bottom_buttons(\%save,\%delete,\%rename,\%close,$tab++);
			}
		} else {
			if ($host_id) {
				$form .= Forms->form_bottom_buttons(\%save,\%close,$tab++);
			} else {
				$form .= Forms->form_bottom_buttons(\%save,\%rename,\%close,$tab++);
			}
		}
	} elsif ($obj_view eq 'service_check') {
		my %template = StorProc->fetch_one('service_templates','servicetemplate_id',$service{'template'});
		my $message = undef;
		my $inherit = 0;
		$inherit = $query->param('inherit');
		my %cmd = StorProc->fetch_one('commands','command_id', $service{'check_command'});
		my $command = $cmd{'name'};
		my $command_save = $cmd{'name'};
		my $command_line = $service{'command_line'};
		if ($query->param('command')) { $command = $query->param('command') }
		if ($query->param('command_save')) { $command_save = $query->param('command_save') }
		if ($query->param('command_line')) { $command_line = $query->param('command_line') }
		unless ($command eq $command_save) {
			%cmd = StorProc->fetch_one('commands','name',$command);
			$command_line = undef;
		}
		if ($inherit or !$command) {
			%cmd = StorProc->fetch_one('commands','command_id',$template{'check_command'});
			if ($cmd{'name'}) {
				$command = $cmd{'name'};
				$command_line = $template{'command_line'};
				$inherit = 1;
			} else {
				my $got_command = 0;
				my $stid = $template{'parent_id'};
				until ($got_command) {
					my %t = StorProc->fetch_one('service_templates','servicetemplate_id',$stid);
					if ($t{'check_command'}) {
						$got_command = 1;
						%cmd = StorProc->fetch_one('commands','command_id',$t{'check_command'});
						$command = $cmd{'name'};
						$command_line = $t{'command_line'};
						$got_command = 1;
					} else {
						if ($t{'parent_id'}) {
							$stid = $t{'parent_id'};
						} else {
							$got_command = 1;
							$message = ('Note: a parent template does not have a check command defined.');
							$command = undef;
							$command_line = undef;
						}
					}
				}
			}
		}
		%cmd = StorProc->fetch_one('commands','name',$command);
		my $arg_string = $command_line;
		$arg_string =~ s/$command!//;
		my $usage = $command;
		my @args = split(/ARG/i,$cmd{'command_line'});
		my $args = undef;
		if ($args[1]) {
			$usage .= "!";
			my $cnt = 1;
			pop @args;
			foreach (@args) { 
				if ($cmd{'command_line'} =~ /ARG$cnt/i) { $args .= "ARG$cnt!" }
				$cnt++;
			}
			chop $args;
			$usage .= $args;
			unless ($command_line =~ /$command/) {
				$command_line = "$command!$args";
				$arg_string = $args;
			}
		}
		$form .= Forms->service_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Service Check',$docs{'service_check'});
		$form .= Forms->display_hidden('Service template:','',$template{'name'});
		$form .= Forms->checkbox_override('Inherit check from template','inherit',$inherit,$docs{'override'});
		my %where = ('type' => 'check');
		my @commands = StorProc->fetch_list_where('commands','name',\%where);
		$form .= Forms->list_box_submit('Check command:','command',\@commands,$command,$required{'check_command'});
		$form .= Forms->display_hidden('Command definition:','',$cmd{'command_line'});
		$form .= Forms->display_hidden('Usage:','',$usage);
		$form .= Forms->text_area('Command line:','command_line',$command_line,'3','80','',$docs{'command_line'});
		$form .= Forms->test_service_check($test_results,$host);
		$hidden{'command_save'} = $command;
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'service_dependencies') {
		my $dep_template = $query->param('dep_template');
		my %dep = StorProc->fetch_one('service_dependency_templates','name',$dep_template);
		my @dep_hosts = ();
		my ($host,$hosts) = StorProc->get_dep_on_hosts($dep{'servicename_id'},'0');
		my @hosts = @{$hosts};
		if ($dep_template) {
			@dep_hosts = ('same host');
			push (@dep_hosts,@hosts);
		}
		$form .= Forms->service_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Service Dependencies',$docs{'dependencies'});
		my %dependencies = StorProc->get_servicename_dependencies($service{'servicename_id'});
		$form .= Forms->dependency_list($name,'services',$service{'servicename_id'},$session_id,\%dependencies);
		my @dep_templates = StorProc->fetch_list('service_dependency_templates','name');
		$form .= Forms->dependency_add($dep_template,\@dep_templates,\@dep_hosts,\%docs);
		$hidden{'name'} = $name;
		$form .= Forms->hidden(\%hidden);
		my %add_dependency = ('name' => 'add_dependency','value' => 'Add Dependency');
		$form .= Forms->form_bottom_buttons(\%add_dependency,$tab++);
	} elsif ($obj_view eq 'service_externals') {
		$hidden{'service_id'} = $query->param('service_id');
		$hidden{'service_name'} = $query->param('service_name');
		my %objs = ('service_id' => $hidden{'service_id'},'service_name' => $hidden{'service_name'});
		$form .= Forms->service_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		my %externals = ();
		my %where = ('servicename_id' => $service{'servicename_id'});
		my @externals = StorProc->fetch_list_where('external_service_names','external_id',\%where);
		foreach my $eid (@externals) {
			my %e = StorProc->fetch_one('externals','external_id',$eid);
			$externals{$e{'name'}} = $eid;
		}
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		if (@messages) { $form .= Forms->form_message('Status:',\@messages,'msg') }
		my %w = ('type' => 'service');
		my @external_names = StorProc->fetch_list_where('externals','name',\%w);
		my @external_list = ();
		foreach my $s (@external_names) { unless ($externals{$s}) { push @external_list, $s } }
		$form .= Forms->external_list($session_id,$name,\%externals,\@external_list,'service_name',$hidden{'service_id'},$hidden{'service_name'});
		$hidden{'type'} = 'service';
		$hidden{'id'} = $properties{'host_id'};
		$hidden{'name'} = $name;
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons();
	} elsif ($obj_view eq 'service_profiles') {
		$form .= Forms->service_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Service Profiles',$docs{'service_profiles'});
		my @members = ();
		my %w = ('servicename_id' => $service{'servicename_id'});
		my @sids = StorProc->fetch_list_where('serviceprofile','serviceprofile_id',\%w);
		foreach (@sids) {
			my %s = StorProc->fetch_one('profiles_service','serviceprofile_id',$_);
			push @members, $s{'name'};
		}
		my @nonmembers = StorProc->fetch_list('profiles_service','name');
		$form .= Forms->members('Service profiles:','profiles',\@members,\@nonmembers,'','20',$docs{'services'});
		$hidden{'obj_view'} = 'service_profiles';
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'apply_hosts') {
		$form .= Forms->service_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Apply Hosts',$docs{'apply'});
		my %where = ('servicename_id' => $service{'servicename_id'});
		my @hosts = StorProc->fetch_list_where('services','host_id',\%where);
		my @host_list = ();
		my %host_name = StorProc->get_table_objects('hosts');
		foreach my $hn (sort keys %host_name) {
			foreach my $hid (@hosts) {
				if ($hid eq $host_name{$hn}) { push @host_list, $hn	}
			}
		}
		$form .= Forms->form_message('Hosts:',\@host_list,'row1');
		$form .= Forms->apply_select($view,\%service,$nagios_ver);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%apply,$tab++);

	} elsif ($obj_view eq 'delete') {
		my $message = qq(Are you sure you want to remove service $name from all hosts and profiles?);
		$form .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden);

	} elsif ($obj_view eq 'applied') {
		my %objs = ('service_id' => $service{'servicename_id'},'name' => $name);
		$form .= Forms->service_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		$form .= Forms->display_hidden('Applied:','',$message_applied);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons();
	
	} elsif ($obj_view eq 'saved') {
		my %objs = ('service_id' => $service{'servicename_id'},'name' => $name);
		$form .= Forms->service_top($name,$session_id,$obj_view,\%objs,$auth_add{'externals'},$hidden{'selected'});
		$form .= Forms->display_hidden('Saved:','',$name);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%close);
	} elsif ($obj_view eq 'rename') {
		$form .= Forms->form_top('Rename Service', Validation->dfv_onsubmit_javascript());
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Name:','name',$name,$textsize{'name'},'');
		$form .= Forms->text_box('Rename:','new_name','',$textsize{'name'},'');
		$hidden{'obj_view'} = 'rename';
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%rename,\%cancel,$tab++);
	} elsif ($obj_view eq 'new') {
		my $template = $query->param('template');
		$form .= Validation->dfv_profile_javascript();
		$form .= &$Instrument::show_trace_as_html_comment();
		$form .= Forms->form_top('New Service', Validation->dfv_onsubmit_javascript());
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->text_box('Name:','name',$name,$textsize{'name'},'',$docs{'name'});
		my @members = StorProc->fetch_list('service_templates','name');
		$form .= Forms->list_box('Service template:','template',\@members,$template,'',$docs{'extinfo'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);
	} elsif ($obj_view eq 'clone') {
		my $clone_service = $query->param('clone_service');
		my $apply_profile = $query->param('apply_profile');
		$form .= Forms->form_top('Clone Service','');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		if ($query->param('clone_service')) {
			$hidden{'clone_service'} = $clone_service;
			$form .= Forms->text_box('Name:','name',"$clone_service-copy",$textsize{'name'},'',$docs{'name'});
			$form .= Forms->checkbox('Apply to profiles:','apply_profile',$apply_profile);
		} else {
			my @members = StorProc->fetch_list('service_names','name');
			$form .= Forms->list_box('Select service:','clone_service',\@members,$clone_service,'','');
		}
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%next,\%cancel,$tab++);
	}
	return $form;
}

sub profile_importer() {
	my @files = $query->param('file');
	my $folder = $query->param('folder');
	my $overwrite = $query->param('overwrite');
	my $form = undef;
	my @messages = ();
	if ($query->param('close')) { $obj_view = 'close' }
	if ($query->param('remove')) {
		foreach my $file (@files) {
			unless ($file) { next }
			my $result = StorProc->delete_file($folder,$file);
			unless ($result =~ /error/i) { push @messages, $result }
		}
		@files = ();
	}
	if ($query->param('upload')) {
		@files = ();
		my $file = $query->param('file');
		my $result = StorProc->upload($folder,$file);
		if ($result =~ /error/i) {
			push @errors, $result;
		} else {
			push @files, $file;
		}
	}
	if ($query->param('import')) {
		if (@files) {
			use MonarchProfileImport;
			foreach my $file (@files) {
				unless ($file) { next }
				push @messages, "Importing $file";
				my @msgs = ProfileImporter->import_profile($folder,$file,$overwrite);
				push (@messages, @msgs);
				push @messages, "-----------------------------------------------------";
			}
			$obj_view = 'status';
		}
	}
	unless ($obj_view) { $obj_view = 'get_file'	}
	if ($query->param('close')) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
	} elsif ($obj_view eq 'get_file') {
		my %docs = Doc->profile_importer();
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Forms->form_top_file("Profile Importer",'');
		$folder = '/tmp';
		if (-e "/usr/local/groundwork/profiles") {
			$folder = "/usr/local/groundwork/profiles";
		}
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Import Profiles',$docs{'profile_importer'});
		my @all_files = StorProc->get_dir($folder);
		my @files = ();
		foreach (@all_files) { if ($_ =~ /xml$/ && $_ !~ /perfconfig/) { push @files, $_ } }
		$form .= Forms->form_files($folder,\@files);
		$form .= Forms->display_hidden('Import folder:','folder',$folder,$docs{'import_folder'});
		$form .= Forms->checkbox('Overwrite existing objects.','overwrite','');
		$form .= Forms->form_file();
		$form .= Forms->hidden(\%hidden);
		my %remove = ('name' => 'remove','value' => 'Remove');
		my %import = ('name' => 'import','value' => 'Import');
		if (@files) {
			$form .= Forms->form_bottom_buttons(\%import,\%remove,\%upload,\%close,$tab++);
		} else {
			$form .= Forms->form_bottom_buttons(\%upload,\%close,$tab++);
		}
	} elsif ($obj_view eq 'status') {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Forms->form_top("Profile Importer",'');
		if ($messages[0] =~ /error/i) {
			push @messages, "Please make the necessary corrections and try again.";
			$form .= Forms->form_errors(\@messages)
		} else {
			$form .= Forms->profile_import_status(\@messages);
		}
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%close,$tab++);
	}
	return $form;
}

#
############################################################################
# Manage Host
#

sub manage_host() {
	my @views = ('host_detail','profile','parents','hostgroups','escalations','host_externals','host_external_detail','services','service_detail','service_check','service_dependencies','service_externals','service_external_detail');
	foreach my $v (@views) {
		if ($query->param($v)) { $obj_view = $v }
	}
	my $by = 'name';
	my $name = $query->param('name');
	my $address = $query->param('address');
	my $host = $query->param('host');
	unless ($name) { $by = 'address' }
	my $form = undef;
	my $message = undef;
	my $required = undef;
	my $results = undef;
	my $test_results = undef;
	$hidden{'form_service'} = $query->param('form_service');
	%properties = StorProc->fetch_host($name,$by);
	if ($query->param('close') || $query->param('continue')) {
		$obj_view = 'close';
	} elsif ($query->param('apply')) {
		if ($obj_view eq 'profile') {
			my $host_profile = $query->param('host_profile');
			if ($host_profile eq 'no profile') {
				$hidden{'hostprofile_id'} = '';
				my %values = ('hostprofile_id' => '');
				my $result = StorProc->update_obj('hosts','host_id',$properties{'host_id'},\%values);
				if ($result =~ /^Error/) { push @errors, $result }	
			} else {
				my %w = ('name' => $host_profile);
				my %h = StorProc->fetch_one_where('profiles_host',\%w);
				my %values = ('hostprofile_id' => $h{'hostprofile_id'});
				$hidden{'hostprofile_id'} = $h{'hostprofile_id'};
				my $result = StorProc->update_obj('hosts','host_id',$properties{'host_id'},\%values);
				if ($result =~ /^Error/) { push @errors, $result }	
			}
			my @service_profiles = $query->param('service_profiles');
			my @profiles = ();
			my $result = StorProc->delete_all('serviceprofile_host','host_id',$properties{'host_id'});
			if ($result =~ /^Error/) { push @errors, $result }	
			foreach my $sp (@service_profiles) {
				my %s = StorProc->fetch_one('profiles_service','name',$sp);
				push @profiles, $s{'serviceprofile_id'};
				my @vals = ($s{'serviceprofile_id'},$properties{'host_id'});
				my $result = StorProc->insert_obj('serviceprofile_host',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }	
			}
			my @hosts = ($properties{'host_id'});
			my $services = $query->param('apply_services');
			my ($cnt, $err) = StorProc->service_profile_apply(\@profiles,$services,\@hosts);
			if ($err) { push (@errors, @{$err}) }
			unless (@errors) {
				$obj_view = 'saved_apply';
				$hidden{'host_id'} = $properties{'host_id'};
				$hidden{'name'} = $name;
				$message = "Changes to $name accepted, $cnt services applied.";
			}	
		} else {
			my $host_id = $query->param('host_id');
			my $hostprofile_id = $query->param('hostprofile_id');
			my $serviceprofile_id = $query->param('serviceprofile_id');
			my %sp = StorProc->fetch_one('profiles_service','serviceprofile_id',$serviceprofile_id);
			my %w = ('hostprofile_id' => $hostprofile_id);
			my @externals = StorProc->fetch_list_where('external_host_profile','external_id',\%w);
			my $result = StorProc->delete_all('external_host','host_id',$host_id);
			if ($result =~ /^Error/) { push @errors, $result }
			foreach my $ext (@externals) {
				my %e = StorProc->fetch_one('externals','external_id',$ext);
				my @vals = ($ext,$host_id,$e{'display'});
				$result = StorProc->insert_obj('external_host',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			my %w = ('serviceprofile_id' => $serviceprofile_id);
			my @services = StorProc->fetch_list_where('serviceprofile','servicename_id',\%w);
			my $result = StorProc->delete_all('services','host_id',$host_id);
			if ($result =~ /^Error/) { push @errors, $result }
			foreach my $sid (@services) {
				my %sn = StorProc->fetch_one('service_names','servicename_id',$sid);
				%w = ('servicename_id' => $sid);
				@externals = StorProc->fetch_list_where('external_service_names','external_id',\%w);
				my @vals = ('',$host_id,$sid,$sn{'template'},$sn{'extinfo'},$sn{'escalation'},'1',$sn{'check_comand'},$sn{'command_line'},'');
				my $service_id = StorProc->insert_obj_id('services',\@vals,'service_id');
				if ($service_id =~ /^Error/) { push @errors, $service_id }
				if ($sn{'dependency'}) {
					@vals = ('',$service_id,$host_id,$host_id,$sn{'template'},'');
					$result = StorProc->insert_obj('service_dependency',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }
				}
				foreach my $ext (@externals) {
					my %e = StorProc->fetch_one('externals','external_id',$ext);
					@vals = ($ext,$host_id,$service_id,$e{'display'});
					$result = StorProc->insert_obj('external_service',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
		}
	} elsif ($query->param('test_command')) {	
		my $arg_string = $query->param('command_line');
		my $command = $query->param('command');
		my $service_name = $query->param('service_name');		
		my %cmd = StorProc->fetch_one('commands','name',$command);
		$test_results .= StorProc->test_command($command,$cmd{'command_line'},$host,$arg_string,$monarch_home,$service_name);	
	} elsif ($query->param('add_instance')) {
		my $check_command = $query->param('command');
		my $args = $query->param('command_line');
		$args =~ s/^$check_command//;
		my $service_id = $query->param('service_id');
		my $inst = $query->param('inst');
		my $range_from = $query->param('range_from');
		my $range_to = $query->param('range_to');
		my %instances = StorProc->get_service_instances($service_id);
		if ($range_to =~ /\d+/ && $range_from =~ /\d+/ && $range_from < $range_to) {
			for (my $i=$range_from; $i <= $range_to; $i++) {
				unless ($instances{"_$i"}) {
					my $inst = "_$i";
					my @vals = ('',$service_id,$inst,'1',$args);
					my $result = StorProc->insert_obj('service_instance',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
		} elsif ($inst) {
			$inst =~ s/^\s+|\s+$//;
			if ($instances{$inst}) {
				@errors = ("Instance $inst already exists. Instance names must be unique.");
			} else {
				my @vals = ('',$service_id,$inst,'1',$args);
				my $result = StorProc->insert_obj('service_instance',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
		} elsif ($range_to) {
			@errors = ('Check values. The range of values must be numeric');
		}
	} elsif ($query->param('remove_instance')) {	
		my @rem_instances = $query->param('rem_inst');
		foreach my $inst (@rem_instances) {
			my $result = StorProc->delete_all('service_instance','instance_id',$inst);
			if ($result =~ /^Error/) { push @errors, $result }
			my $service_name = $query->param('service_name');
			my $inst_name = $query->param("instance_$inst");
			my $service_inst = "$service_name$inst_name";
			my %where = ('host' => $name,'service' => $service_inst);
			$result = StorProc->delete_one_where('host_service',\%where);
			if ($result =~ /^Error/) { push @errors, $result }

		}
	
	} elsif ($query->param('external_add')) {	
		my $external_name = $query->param('external');
		my $service_id = $query->param('service_id');
		my $host_id = $query->param('id');
		my $type = $query->param('type');
		my %w = ('name' => $external_name,'type' => $type);
		my %e = StorProc->fetch_one_where('externals',\%w);
		if ($type eq 'service') {
			my @vals = ($e{'external_id'},$host_id,$service_id,$e{'display'});
			my $result = StorProc->insert_obj('external_service',\@vals);
			if ($result =~ /^Error/) { push @errors, $result }
		} else {
			my @vals = ($e{'external_id'},$host_id,$e{'display'});
			my $result = StorProc->insert_obj('external_host',\@vals);
			if ($result =~ /^Error/) { push @errors, $result }
		}
	} elsif ($query->param('save')) {	
		if ($obj_view eq 'host_detail') {
			my %data = parse_query('host_templates','host_overrides');
			my $alias = $query->param('alias');
			my $address = $query->param('address');
			my $host_template = $query->param('template');
			my $extinfo = $query->param('extended_info');
			my $checks_enabled = $query->param('checks_enabled');
			my $coords2d = $query->param('coords2d');
			my $coords3d = $query->param('coords3d');
			if ($alias && $address && $host_template) {
				my %values = ('alias' => $alias,'address' => $address);
				my %t = StorProc->fetch_one('host_templates','name',$host_template);
				$values{'hosttemplate_id'} = $t{'hosttemplate_id'};
				my %e = StorProc->fetch_one('extended_host_info_templates','name',$extinfo);
				$values{'hostextinfo_id'} = $e{'hostextinfo_id'};
				my $result = StorProc->update_obj('hosts','host_id',$properties{'host_id'},\%values);
				if ($result =~ /^Error/) { push @errors, $result }
				if ($coords2d || $coords3d) { 
 					my $data = "<?xml version=\"1.0\" ?>\n<data>";
					if ($coords2d) { $data .= "\n  <prop name=\"2d_coords\"><![CDATA[$coords2d]]>\n  </prop>" }
					if ($coords3d) { $data .= "\n  <prop name=\"3d_coords\"><![CDATA[$coords3d]]>\n  </prop>" }
					$data .= "\n</data>";
					my %w = ('host_id' => $properties{'host_id'});
					my $result = StorProc->delete_one_where('extended_info_coords',\%w);
					if ($result =~ /^Error/) { push @errors, $result }
					my @vals = ($properties{'host_id'},$data);
					$result = StorProc->insert_obj('extended_info_coords',\@vals);
					if ($result =~ /^Error/) { push @errors, $result }	
				}
				my %where = ('host_id' => $properties{'host_id'});
				my $result = StorProc->delete_one_where('host_overrides',\%where);
				if ($result =~ /^Error/) { push @errors, $result }
				if ($data{'check_period'} || $data{'notification_period'}|| $data{'check_command'} || $data{'event_handler'} || $data{'data'}) {
					my @values = ($properties{'host_id'},$data{'check_period'},$data{'notification_period'},$data{'check_command'},$data{'event_handler'},$data{'data'});
					my $result = StorProc->insert_obj('host_overrides',\@values);
					if ($result =~ /^Error/) { push @errors, $result }
				}
				if ($query->param('contactgroup_override')) {

#					my %where = ('type' => 'hosts','object' => $properties{'host_id'});
#					my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
					my %where = ('host_id' => $properties{'host_id'});
					my $result = StorProc->delete_one_where('contactgroup_host',\%where);

					if ($result =~ /^Error/) { push @errors, $result }
				} else {

#					my %where = ('type' => 'hosts','object' => $properties{'host_id'});
#					my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
					my %where = ('host_id' => $properties{'host_id'});
					my $result = StorProc->delete_one_where('contactgroup_host',\%where);

					if ($result =~ /^Error/) { push @errors, $result }
					my @mems = $query->param('contactgroup');
					foreach (@mems) {
						my %cg = StorProc->fetch_one('contactgroups','name',$_);

#						my @vals = ($cg{'contactgroup_id'},'hosts',$properties{'host_id'});
#						$result = StorProc->insert_obj('contactgroup_assign',\@vals);
						my @vals = ($cg{'contactgroup_id'},$properties{'host_id'});
						$result = StorProc->insert_obj('contactgroup_host',\@vals);

						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
				unless (@errors) {
					$obj_view = 'saved';
					$message = "Changes to $name accepted";
				}
			} else {
				push @errors, "Required: alias, address, and host template";
				$required = 1;
			}
		} elsif ($obj_view eq 'escalations') {
			my $host_escalation = $query->param('host_escalation');
			my $service_escalation = $query->param('service_escalation');
			my %w = ('name' => $host_escalation,'type' => 'host');
			my %he = StorProc->fetch_one_where('escalation_trees',\%w);
			%w = ('name' => $service_escalation,'type' => 'service');
			my %se = StorProc->fetch_one_where('escalation_trees',\%w);
			my %values = ('host_escalation_id' => $he{'tree_id'},'service_escalation_id' => $se{'tree_id'});
			my $result = StorProc->update_obj('hosts','host_id',$properties{'host_id'},\%values);
			if ($result =~ /^Error/) { push @errors, $result }	
			unless (@errors) {
				$obj_view = 'saved';
				$message = "Changes to $name accepted";
			}
		} elsif ($obj_view eq 'parents') {
			my @parents = $query->param('parents');
			my %w = ('host_id' => $properties{'host_id'});
			my $result = StorProc->delete_one_where('host_parent',\%w);
			if ($result =~ /^Error/) { push @errors, $result }
			my @parents = $query->param('parents');
			foreach my $parent (@parents) {
				if (!$parent) { next }
				my %h = StorProc->fetch_one('hosts','name',$parent);
				my @vals = ($properties{'host_id'},$h{'host_id'});
				my $result = StorProc->insert_obj('host_parent',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { 
				$obj_view = 'saved';
				$message = "Changes to parent accepted";
			}
		} elsif ($obj_view eq 'hostgroups') {
			my %w = ('host_id' => $properties{'host_id'});
			my $result = StorProc->delete_one_where('hostgroup_host',\%w);
			if ($result =~ /^Error/) { push @errors, $result }
			my @hostgroups = $query->param('members');
			foreach my $hg (@hostgroups) {
				if (!$hg) { next }
				my %h = StorProc->fetch_one('hostgroups','name',$hg);
				my @vals = ($h{'hostgroup_id'},$properties{'host_id'});
				my $result = StorProc->insert_obj('hostgroup_host',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }
			}
			unless (@errors) { 
				$obj_view = 'saved';
				$message = "Changes to $name hostgroups accepted";
			}
		} elsif ($obj_view eq 'host_external_detail') {
			my $data = $query->param('detail');
			my $external_id = $query->param('external_id');
			my %where = ('host_id' => $properties{'host_id'},'external_id' => $external_id);
			my %values = ('data' => $data);
			my $result = StorProc->update_obj_where('external_host',\%values,\%where);
			if ($result =~ /^Error/) { push @errors, $result }	
			unless (@errors) { 
				$obj_view = 'saved';
				$message = "Changes to $name external accepted";
			}
		} elsif ($obj_view eq 'service_external_detail') {
			my $data = $query->param('detail');
			my $external_id = $query->param('external_id');
			my $service_name = $query->param('service_name');
			my $service_id = $query->param('service_id');
			$hidden{'service_name'} = $service_name;
			$hidden{'service_id'} = $service_id;
			my %values = ('data' => $data);
			my %where = ('service_id' => $service_id,'external_id' => $external_id);
			my $result = StorProc->update_obj_where('external_service',\%values,\%where);
			if ($result =~ /^Error/) { push @errors, $result }	
			unless (@errors) { 
				$obj_view = 'saved';
				$message = "Changes to $name external accepted";
			}
		} elsif ($obj_view eq 'service_detail') {
			my %values = ();
			my $service_name = $query->param('service_name');
			my $service_id = $query->param('service_id');
			$hidden{'service_name'} = $service_name;
			$hidden{'service_id'} = $service_id;
			my %s = StorProc->fetch_one('service_names','name',$service_name);
			my $ext_info = $query->param('ext_info');
			my %x = StorProc->fetch_one('extended_service_info_templates','name',$ext_info);
			my $escalation = $query->param('escalation');
			my %e = StorProc->fetch_one('escalation_trees','name',$escalation);
			my $template = $query->param('template');
			my %t = StorProc->fetch_one('service_templates','name',$template);
			my %data = parse_query('service_overrides','service_overrides');
			my %vals = ('serviceextinfo_id' => $x{'serviceextinfo_id'},'escalation_id' => $e{'tree_id'},'servicetemplate_id' => $t{'servicetemplate_id'});
			my $result = StorProc->update_obj('services','service_id',$service_id,\%vals);
			if ($result =~ /^Error/) { push @errors, $result }
			my %where = ('service_id' => $properties{'service_id'});
			my $result = StorProc->delete_one_where('service_overrides',\%where);
			if ($result =~ /^Error/) { push @errors, $result }
			if ($data{'check_period'} || $data{'notification_period'} || $data{'event_handler'} || $data{'data'}) {
				my @values = ($service_id,$data{'check_period'},$data{'notification_period'},$data{'event_handler'},$data{'data'});
				my $result = StorProc->insert_obj('service_overrides',\@values);
				if ($result =~ /^Error/) { push @errors, $result }
			}

#			my %where = ('type' => 'services','object' => $service_id);
#			my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
			%where = ('service_id' => $service_id);
			$result = StorProc->delete_one_where('contactgroup_service',\%where);

			if ($result =~ /^Error/) { push @errors, $result }
			unless ($query->param('contactgroup_override')) {
				my @mems = $query->param('contactgroup');
				foreach (@mems) {
					my %cg = StorProc->fetch_one('contactgroups','name',$_);

#					my @vals = ($cg{'contactgroup_id'},'services',$service_id);
#					$result = StorProc->insert_obj('contactgroup_assign',\@vals);
					my @vals = ($cg{'contactgroup_id'},$service_id);
					$result = StorProc->insert_obj('contactgroup_service',\@vals);

					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
			unless (@errors) {
				$obj_view = 'saved';
				$message = "Changes to $service_name accepted";
			}
		} elsif ($obj_view eq 'service_check') {
			my $service_name = $query->param('service_name');
			my $service_id = $query->param('service_id');
			$hidden{'service_name'} = $service_name;
			$hidden{'service_id'} = $service_id;
			my $check_command = $query->param('command');
			my $command_line = $query->param('command_line');
			my %instances_org = StorProc->get_service_instances_names($hidden{'service_id'});
			my %instances = ();
			foreach my $qname ($query->param) {
				if ($qname =~ /args_(\d+)/) {
					$instances{$1}{'args'} = $query->param($qname);
				} elsif ($qname =~ /status_(\d+)/) {
					$instances{$1}{'status'} = 1;
				} elsif ($qname =~ /instance_(\d+)/) {
					$instances{$1}{'instance'} = $query->param($qname);
				}
			}
			my %duplicates = ();
			foreach my $inst (keys %instances) {
				if ($duplicates{$instances{$inst}{'instance'}}) {
					push @errors, "Instance $duplicates{$instances{$inst}{'instance'}} already exists. Instance names must be unique."
				} else {
					$duplicates{$instances{$inst}{'instance'}} = $instances{$inst}{'instance'}; 
				}
			}
			unless (@errors) {
				foreach my $inst (keys %instances) {
					if ($instances{$inst}{'instance'}) {
						my %vals = ('name' => $instances{$inst}{'instance'},'status' => $instances{$inst}{'status'},'arguments' => $instances{$inst}{'args'});
						my $result = StorProc->update_obj('service_instance','instance_id',$inst,\%vals);
						if ($result =~ /^Error/) { push @errors, $result }
						unless ($instances_org{$inst}{'name'} eq $instances{$inst}{'instance'}) {
							my $service_name = $query->param('service_name');
							my $inst_name = $query->param("instance_$inst");
							my $service_inst = "$service_name$instances_org{$inst}{'name'}";
							my %where = ('host' => $name,'service' => $service_inst);
							$result = StorProc->delete_one_where('host_service',\%where);
							if ($result =~ /^Error/) { push @errors, $result }
						}
					} 
				}
			}
			unless (@errors) {
				if ($query->param('inherit')) {
					my $required = $query->param('required');
					unless ($required) {
						my %vals = ('check_command' => '','command_line' => '');
						my $result = StorProc->update_obj('services','service_id',$service_id,\%vals);
						if ($result =~ /^Error/) { push @errors, $result }
					} else {
						push @errors, "The service check is not defined on a template so it must be defined here.";
					}
				} else {
					my %check = StorProc->fetch_one('commands','name',$check_command);
					my %vals = ('check_command' => $check{'command_id'},'command_line' => $command_line);
					my $result = StorProc->update_obj('services','service_id',$service_id,\%vals);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
			unless (@errors) {
				$obj_view = 'saved';
				$message = "Changes to $service_name accepted";
			}
		}	
	} elsif ($query->param('add_dependency')) {
		my $dep_template = $query->param('dep_template');
		my $service_name = $query->param('service_name');
		my $service_id = $query->param('service_id');
		$hidden{'service_name'} = $service_name;
		$hidden{'service_id'} = $service_id;
		my $parent = $query->param('depend_on_host');
		my %p = StorProc->fetch_one('hosts','name',$parent);
		my %d = StorProc->fetch_one('service_dependency_templates','name',$dep_template);
		my %w = ('service_id' => $service_id,'host_id' => $properties{'host_id'},'depend_on_host_id' => $p{'host_id'},'template' => $d{'id'});
		my %check_dep = StorProc->fetch_one_where('service_dependency',\%w);	
		if ($dep_template && $service_id && $parent) {
			unless ($check_dep{'id'}) {
				my @values = ('',$service_id,$properties{'host_id'},$p{'host_id'},$d{'id'},'');
				my $result = StorProc->insert_obj('service_dependency',\@values);
				if ($result =~ /^Error/) { push @errors, $result }	
			} else {
				push @errors, "Already defined. Check existing dependencies";
			}
		}
	} elsif ($query->param('remove_dependency')) {
		my $dep_id = $query->param('dependency_id');
		my $result = StorProc->delete_all('service_dependency','id',$dep_id);
		if ($result =~ /^Error/) { push @errors, $result }
	} elsif ($submit eq 'remove_service') {
		$refresh_left = 1;
		my $service_id = $query->param('service_id');
		my %s = StorProc->fetch_one('services','service_id',$service_id);
		my %sn = StorProc->fetch_one('service_names','servicename_id',$s{'servicename_id'});
		my $result = StorProc->delete_all('services','service_id',$service_id);
		if ($result =~ /^Error/) { push @errors, $result }
		my %where = ('service' => $sn{'name'},'host' => $name);
		$result = StorProc->delete_one_where('host_service',\%where);
		if ($result =~ /^Error/) { push @errors, $result }
		$obj_view = 'services';
	} elsif ($query->param('rename')) {
		my $new_name = $query->param('new_name');
		if ($new_name) {
			$new_name =~ s/^\s+|\s+$//;
			my %n = StorProc->fetch_one('hosts','name',$new_name);
			if ($name =~ /$new_name/i) { delete $n{'name'} }
			if ($n{'name'}) {
				$obj_view = 'rename';
				push @errors, "Cannot rename. Another host has name $new_name.";
			} else {
				my %values = ('name' => $new_name);
				my $result = StorProc->update_obj('hosts','name',$name,\%values);
				if ($result =~ /^Error/) { 
					push @errors, $result;
					$obj_view = 'rename';
				} else {
					$result = StorProc->delete_all('host_service','host',$name);
					if ($result =~ /^Error/) { push @errors, $result }
					$name = $new_name;
					%properties = StorProc->fetch_host($name);
					$refresh_left = 1;
					$obj_view = 'host_detail';
					$refresh_left = 1;
				}
			}
		} else {
			$obj_view = 'rename';
		}
	} elsif ($submit eq 'Add Service(s)') {
		my @services = $query->param('add_service');
		my %where = ();
		my %service_names = ();
		my %service_name_hash = StorProc->fetch_list_hash_array('service_names',\%where);
		foreach my $service_id (keys %service_name_hash) {
			$service_names{$service_name_hash{$service_id}[1]}{'id'} = $service_id;
			$service_names{$service_name_hash{$service_id}[1]}{'template'} = $service_name_hash{$service_id}[3];
			$service_names{$service_name_hash{$service_id}[1]}{'check_command'} = $service_name_hash{$service_id}[4];
			$service_names{$service_name_hash{$service_id}[1]}{'command_line'} = $service_name_hash{$service_id}[5];
			$service_names{$service_name_hash{$service_id}[1]}{'escalation'} = $service_name_hash{$service_id}[6];
			$service_names{$service_name_hash{$service_id}[1]}{'extinfo'} = $service_name_hash{$service_id}[7];
		}
		my %service_name_overrides = ();
		my %service_name_override_hash = StorProc->fetch_list_hash_array('servicename_overrides',\%where);
		foreach my $service_id (keys %service_name_hash) {
			$service_name_overrides{$service_id}{'check_period'} = $service_name_override_hash{$service_id}[1];
			$service_name_overrides{$service_id}{'notification_period'} = $service_name_override_hash{$service_id}[2];
			$service_name_overrides{$service_id}{'event_handler'} = $service_name_override_hash{$service_id}[3];
			if ($service_name_override_hash{$service_id}[4]) {
				$service_name_overrides{$service_id}{'data'} = $service_name_override_hash{$service_id}[4];
			} else {
				$service_name_overrides{$service_id}{'data'} = qq(<?xml version="1.0" ?>
<data>
</data>);      
			}
		}
		my %service_name_dependency = ();
		my %service_name_dependency_hash = StorProc->fetch_list_hash_array('servicename_dependency',\%where);
		foreach my $id (keys %service_name_dependency_hash) {
			$service_name_dependency{$service_name_dependency_hash{$id}[1]}{$id}{'host'} = $service_name_dependency_hash{$id}[2];
			$service_name_dependency{$service_name_dependency_hash{$id}[1]}{$id}{'template'} = $service_name_dependency_hash{$id}[3];
		}

		my %externals = ();
		my %externals_hash = StorProc->fetch_list_hash_array('externals',\%where);
		foreach my $id (keys %externals_hash) {
			$externals{$id} = $externals_hash{$id}[4];
		}
		my %service_name_externals = ();
		my %service_name_externals_hash = StorProc->fetch_list_hash_array('external_service_names',\%where);
		foreach my $id (keys %service_name_externals_hash) {
			$service_name_externals{$service_name_externals_hash{$id}[1]}{$id} = $id;
		}
		foreach my $service_name (@services) {
			if ($service_name) {
				my @values = ('',$properties{'host_id'},$service_names{$service_name}{'id'},$service_names{$service_name}{'template'},$service_names{$service_name}{'extinfo'},$service_names{$service_name}{'escalation'},'1',$service_names{$service_name}{'check_command'},$service_names{$service_name}{'command_line'},'');
				my $id = StorProc->insert_obj_id('services',\@values,'service_id');
				if ($id =~ /^Error/) { 
					push @errors, $id;
				} else {	
					@values = ($id,$service_name_overrides{$service_names{$service_name}{'id'}}{'check_period'},$service_name_overrides{$service_names{$service_name}{'id'}}{'notification_period'},$service_name_overrides{$service_names{$service_name}{'id'}}{'event_handler'},$service_name_overrides{$service_names{$service_name}{'id'}}{'data'});
					my $result = StorProc->insert_obj('service_overrides',\@values);
					if ($result =~ /^Error/) { push @errors, $result }	
					foreach my $dependency_id (keys %{$service_name_dependency{$service_names{$service_name}{'id'}}}) {
						my $depend_on_host = $properties{'host_id'};
						if ($service_name_dependency{$service_names{$service_name}{'id'}}{$dependency_id}{'host'}) { $depend_on_host = $service_name_dependency{$service_names{$service_name}{'id'}}{$dependency_id}{'host'} }
						@values = ('',$id,$properties{'host_id'},$depend_on_host,$service_name_dependency{$service_names{$service_name}{'id'}}{$dependency_id}{'template'},'');
						$result = StorProc->insert_obj('service_dependency',\@values);
						if ($result =~ /^Error/) { push @errors, $result }	
					}
					foreach my $external_id (keys %{$service_name_externals{$service_names{$service_name}{'id'}}}) {
						@values = ($external_id,$properties{'host_id'},$id,$externals{$external_id});
						$result = StorProc->insert_obj('external_service',\@values);
						if ($result =~ /^Error/) { push @errors, $result }	
					}
				}
			}
		}	
	} elsif ($query->param('delete') || $query->param('confirm_delete_host') || $query->param('task') eq 'No') {
		if ($query->param('confirm_delete_host')) {

#			my %where = ('type' => 'hosts','object' => $properties{'host_id'});
#			my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
			my %where = ('host_id' => $properties{'host_id'});
			my $result = StorProc->delete_one_where('contactgroup_host',\%where);

			if ($result =~ /^Error/) { push @errors, $result }
			my $result = StorProc->delete_all('hosts','name',$name);
			if ($result =~ /^Error/) { 
				push @errors, $result;
				$obj_view = 'host_detail';
			} else {
				$result = StorProc->delete_all('host_service','host',$name);
				if ($result =~ /^Error/) { push @errors, $result }
				$refresh_left = 1;
				$obj_view = 'deleted';
			}
		} elsif ($query->param('task') eq 'No') {
			$obj_view = 'host_detail';		
		} else {
			$obj_view = 'delete_host';
		}
	} elsif ($query->param('delete') || $query->param('confirm_delete_service')) {
		my $service_name = $query->param('service_name');
		if ($query->param('confirm_delete_service')) {
			my %where = ('name' => $service_name, 'host_name' => $name);
			my %sid = StorProc->fetch_one_where('services',\%where);

#			%where = ('type' => 'services','object' => $sid{'service_id'});
#			my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
#			if ($result =~ /^Error/) { push @errors, $result }
# changed to following (but still not used)
#			%where = ('service_id' => $sid{'service_id'});
#			my $result = StorProc->delete_one_where('contactgroup_service',\%where);
#			if ($result =~ /^Error/) { push @errors, $result }

			my $result = StorProc->delete_all('services','service_id',$sid{'service_id'});
			if ($result =~ /^Error/) { push @errors, $result }
			$obj_view = 'Service List';
		} elsif ($query->param('task') eq 'No') {
			$obj_view = 'Service List';		
		} else {
			$hidden{'name'} = $name; 
			$hidden{'obj_view'} = $obj_view;
			$hidden{'submit'} = 'service_delete';
			$hidden{'service_name'} = $service_name;
			my $message = qq(Are you sure you want to remove service $service_name from host $name?);
			$form .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete_service',\%hidden);
		}
	} else {
		my $got_obj = 0;
		foreach my $param ($query->param) {
			if ($param =~ /remove_external_(\d+)/) {
				my $eid = $1;
				if ($obj_view eq 'host_externals') {
					my %where = ('host_id' => $properties{'host_id'},'external_id' => $eid);
					my $result = StorProc->delete_one_where('external_host',\%where);
					if ($result =~ /^Error/) { push @errors, $result }						
				} else {
					my $service_id = $query->param('service_id');
					my %where = ('service_id' => $service_id,'external_id' => $eid);
					my $result = StorProc->delete_one_where('external_service',\%where);
					if ($result =~ /^Error/) { push @errors, $result }						
				}
			} elsif ($param eq 'select_external') {
				if ($obj_view eq 'host_externals') {
					$properties{'external'} = $query->param('select_external');
					my %e = StorProc->fetch_one('externals','name',$properties{'external'});
					$properties{'external_id'} = $e{'external_id'};
					$obj_view = 'host_external_detail';
					$got_obj = 1;
				} else {
					$properties{'external'} = $query->param('select_external');
					my %e = StorProc->fetch_one('externals','name',$properties{'external'});
					$properties{'external_id'} = $e{'external_id'};
					$obj_view = 'service_external_detail';
					$got_obj = 1;
				}
			}
		}
	}
	delete $hidden{'task'};
	delete $hidden{'obj_view'};
	%save = ('name' => 'save','value' => 'Save');
	unless ($obj_view) { $obj_view = 'host_detail' }
	$hidden{'obj_view'} = $obj_view;
	$form .= Forms->header($page_title,$session_id,$top_menu,'',$refresh_left);
	if ($obj_view eq 'host_detail') {
		my %docs = Doc->manage_hosts_vitals();
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->text_box('Alias:','alias',$properties{'alias'},$textsize{'alias'},$required,$docs{'alias'},'','1');
		$form .= Forms->text_box('Address:','address',$properties{'address'},$textsize{'address'},$required,$docs{'address'},'','2');
		$form .= build_host_template($name);
		my @members = StorProc->fetch_list('extended_host_info_templates','name'); 
		push @members, 'remove_extended_info';
		$form .= Forms->list_box('Extended host info template:','extended_info',\@members,$properties{'ext_info'},'',$docs{'extinfo'});
		$form .= Forms->text_box('2d status coords:','coords2d',$properties{'coords2d'},'10','',$docs{'coords2d'});
		$form .= Forms->text_box('3d status coords:','coords3d',$properties{'coords3d'},'15','',$docs{'coords3d'});
		$hidden{'name'} = $name;
		$form .= Forms->hidden(\%hidden);		
		if ($auth_delete{$obj}) {
			$form .= Forms->form_bottom_buttons(\%save,\%delete,\%rename,$tab++);
		} else {
			$form .= Forms->form_bottom_buttons(\%save,\%rename,$tab++);
		}
	} elsif ($obj_view eq 'profile') {
		my %docs = Doc->manage_hosts_profile();
		my @service_ids = ();
		my $host_profile = $query->param('host_profile');
		my @service_profiles = $query->param('service_profiles');
		my $host_profile_save = undef;
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Profile',$docs{'profile'});
		my $host_profile_id = undef;
		if ($host_profile) {
			my %h = StorProc->fetch_one('profiles_host','name',$host_profile);
			$host_profile_id = $h{'hostprofile_id'};
		} else {
			my %h = StorProc->fetch_one('profiles_host','hostprofile_id',$properties{'hostprofile_id'});
			$host_profile_id = $properties{'hostprofile_id'};
			$host_profile = $h{'name'};
			$host_profile_save = $host_profile;
		}
		unless ($host_profile) { $host_profile = 'no profile' }
		$hidden{'host_profile_save'} = $host_profile;
		my @host_profiles = ('no profile');
		my @profiles = StorProc->fetch_list('profiles_host','name');
		push (@host_profiles,@profiles);
		$form .= Forms->list_box('Host profile:','host_profile',\@host_profiles,$host_profile,'',$docs{'host_profile'});
		if ($host_profile eq 'no profile') {
			if (@service_profiles) {
				foreach my $sp (@service_profiles) {
					my %s = StorProc->fetch_one('profiles_service','name',$sp);
					my %w = ('serviceprofile_id' => $s{'serviceprofile_id'});
					my @sids = StorProc->fetch_list_where('serviceprofile','servicename_id',\%w);
					push (@service_ids,@sids);
				} 
			} else {
				my %w = ('host_id' => $properties{'host_id'});
				my @sids = StorProc->fetch_list_where('serviceprofile_host','serviceprofile_id',\%w);
				my %s = ();
				foreach my $sid (@sids) {
					unless ($s{$sid}) {
						my %s = StorProc->fetch_one('profiles_service','serviceprofile_id',$sid);
						push @service_profiles, $s{'name'};
						my %w = ('serviceprofile_id' => $sid);
						my @sids = StorProc->fetch_list_where('serviceprofile','servicename_id',\%w);
						push (@service_ids,@sids);
					}
				}
			}
		} elsif ($host_profile_save ne $host_profile) {
			$host_profile_save = undef;
			@service_profiles = ();
			my %w = ('hostprofile_id' => $host_profile_id);
			my @sids = StorProc->fetch_list_where('profile_host_profile_service','serviceprofile_id',\%w);
			my %s = ();
			foreach my $sid (@sids) {
				$s{$sid} =  1;
				my %s = StorProc->fetch_one('profiles_service','serviceprofile_id',$sid);
				push @service_profiles, $s{'name'};
				my %w = ('serviceprofile_id' => $sid);
				my @sids = StorProc->fetch_list_where('serviceprofile','servicename_id',\%w);
				push (@service_ids,@sids);
			}
		} elsif (@service_profiles) {
			foreach my $sp (@service_profiles) {
				my %s = StorProc->fetch_one('profiles_service','name',$sp);
				my %w = ('serviceprofile_id' => $s{'serviceprofile_id'});
				my @sids = StorProc->fetch_list_where('serviceprofile','servicename_id',\%w);
				push (@service_ids,@sids);
			}
		} else {
			my %w = ('host_id' => $properties{'host_id'});
			my @sids = StorProc->fetch_list_where('serviceprofile_host','serviceprofile_id',\%w);
			my %s = ();
			foreach my $sid (@sids) {
				unless ($s{$sid}) {
					my %s = StorProc->fetch_one('profiles_service','serviceprofile_id',$sid);
					push @service_profiles, $s{'name'};
					my %w = ('serviceprofile_id' => $sid);
					my @sids = StorProc->fetch_list_where('serviceprofile','servicename_id',\%w);
					push (@service_ids,@sids);
				}
			}
		}
		my @nonmembers = StorProc->fetch_list('profiles_service','name');
		$form .= Forms->members('Service profiles:','service_profiles',\@service_profiles,\@nonmembers,'','5',$docs{'services'});
		my @services = ();
		my %s = ();
		foreach my $sid (@service_ids) {
			unless ($s{$sid}) {
				$s{$sid} =  1;
				my %s = StorProc->fetch_one('service_names','servicename_id',$sid);
				if ($s{'name'}) { push @services, $s{'name'} }
			}
		}
		$form .= Forms->form_message('Services:',\@services,'row1');
		my %selected = ();
		$selected{'merge'} = 'checked';
		$form .= Forms->apply_select($view,\%selected,$nagios_ver);
		$hidden{'name'} = $name;
		$hidden{'host_profile_save'} = $host_profile_save;
		my %save = ('name' => 'save','value' => 'Save');
		$form .= Forms->hidden(\%hidden);
		my %refresh = ('name' => 'refresh','value' => 'Refresh');
		my %apply = ('name' => 'apply','value' => 'Apply');
		$form .= Forms->form_bottom_buttons(\%apply,\%refresh,$tab++);
	} elsif ($obj_view eq 'parents') {
		my %docs = Doc->manage_hosts_parents();
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		my @members = @{$properties{'parents'}};
		# my @nonmembers = StorProc->get_parents();
		my @nonmembers = StorProc->fetch_list('hosts','name');
		$form .= Forms->members('Parents:','parents',\@members,\@nonmembers,'','',$docs{'parents'});
		$hidden{'name'} = $name;
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'escalations') {
		my %docs = Doc->manage_hosts_escalations();
		my $host_escalation = $query->param('host_escalation');
		my $service_escalation = $query->param('service_escalation');
		unless ($host_escalation) {
			my %w = ('tree_id' => $properties{'host_escalation_id'} );
			my %t = StorProc->fetch_one_where('escalation_trees',\%w);
			$host_escalation = $t{'name'};
		}
		unless ($service_escalation) {
			my %w = ('tree_id' => $properties{'service_escalation_id'} );
			my %t = StorProc->fetch_one_where('escalation_trees',\%w);
			$service_escalation = $t{'name'};
		}
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Escalations',$docs{'escalations'});
		my %where = ('type','host');
		my @members = ('-remove-escalation-');
		my @mems = StorProc->fetch_list_where('escalation_trees','name',\%where);
		push (@members,(@mems));
		$form .= Forms->list_box_submit('Host escalation:','host_escalation',\@members,$host_escalation,'',$docs{'host_escalation_tree'});
		if ($host_escalation) {
			my ($ranks, $templates) = StorProc->get_tree_detail($host_escalation);
			my %ranks = %{$ranks};
			my %templates = %{$templates};
			$form .= Forms->escalation_tree(\%ranks,\%templates,'escalations');
		}
		@members = ('-remove-escalation-');
		my %where = ('type','service');
		@mems = StorProc->fetch_list_where('escalation_trees','name',\%where);
		push (@members,(@mems));
		$form .= Forms->list_box_submit('Service escalation:','service_escalation',\@members,$service_escalation,'',$docs{'service_escalation_tree'});
		if ($service_escalation) {
			my ($ranks, $templates) = StorProc->get_tree_detail($service_escalation);
			my %ranks = %{$ranks};
			my %templates = %{$templates};
			$form .= Forms->escalation_tree(\%ranks,\%templates,'escalations');
		}
		$hidden{'name'} = $name;
		my %save = ('name' => 'save','value' => 'Save');
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'hostgroups') { # xxx
		my %docs = Doc->manage_hosts_hostgroups();
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		my @members = StorProc->get_hostgroup_host($name);
		my @nonmembers = StorProc->fetch_list('hostgroups','name'); 
		$form .= Forms->members('Hostgroups:','members',\@members,\@nonmembers,'','',$docs{'hostgroups'}); 
		$hidden{'name'} = $name;
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'services') {
		my %docs = Doc->manage_hosts_services();
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		my %services = ();
		my %where = ('host_id' => $properties{'host_id'});
		my @services = StorProc->fetch_list_where('services','service_id',\%where);
		my $fsid = undef;
		foreach my $sid (@services) {
			my $service_name = StorProc->get_service_name($sid);
			$service_name =~ s/\s/+/g;
			$services{$service_name} = $sid;
			$fsid = $sid;
		}
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Services',$docs{'services'});
		if (@messages) { $form .= Forms->form_message('Status:',\@messages,'msg') }
		my @service_names = StorProc->fetch_list('service_names','name');
		my @service_list = ();
		foreach my $s (@service_names) { $s =~ s/\s/+/g; unless ($services{$s}) { $s =~ s/\+/ /g; push @service_list, $s } }
		@service_list = sort { $a <=> $b } @service_list;
		$form .= Forms->service_list($session_id,$name,\%services,\@service_list,$hidden{'selected'});
		$hidden{'name'} = $name;
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons();
	} elsif ($obj_view eq 'host_externals') {
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		my %externals = ();
		my %where = ('host_id' => $properties{'host_id'});
		my @externals = StorProc->fetch_list_where('external_host','external_id',\%where);
		foreach my $eid (@externals) {
			my %e = StorProc->fetch_one('externals','external_id',$eid);
			$externals{$e{'name'}} = $eid;
		}
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		if (@messages) { $form .= Forms->form_message('Status:',\@messages,'msg') }
		my %w = ('type' => 'host');
		my @external_names = StorProc->fetch_list_where('externals','name',\%w);
		my @external_list = ();
		foreach my $s (@external_names) { unless ($externals{$s}) { push @external_list, $s } }
		@external_list = sort { $a <=> $b } @external_list;
		$form .= Forms->external_list($session_id,$name,\%externals,\@external_list,'host');
		$hidden{'type'} = 'host';
		$hidden{'name'} = $name;
		$hidden{'id'} = $properties{'host_id'};
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons();
	} elsif ($obj_view eq 'host_external_detail') {
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		my $detail = $query->param('detail');
		my $host_external = $query->param('host_external');
		unless ($host_external) { $host_external = $properties{'external'} }
		my %where = ('external_id' => $properties{'external_id'},'host_id' => $properties{'host_id'});
		my %external = StorProc->fetch_one_where('external_host',\%where);
		unless ($detail) { $detail = $external{'data'} }
		$form .= Forms->display_hidden('External:','host_external',$host_external);
		$form .= Forms->text_area('Detail:','detail',$detail,'30','140');
		$hidden{'external_id'} = $external{'external_id'};
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'service_detail') {
		my %docs = Doc->manage_hosts_service_detail();
		$hidden{'service_id'} = $query->param('service_id');
		my $service_name = $query->param('service_name');
		my $ext_info = $query->param('ext_info');
		my $escalation = $query->param('escalation');
		unless ($hidden{'service_name'}) { $hidden{'service_name'} = $query->param('service_name') }
		unless ($hidden{'service_id'}) { 
			my %snid =  StorProc->fetch_one('service_names','name',$hidden{'service_name'});
			my %where = ('host_id' => $properties{'host_id'},'servicename_id' => $snid{'servicename_id'});
			my %sid = StorProc->fetch_one_where('services',\%where);	
			$hidden{'service_id'} = $sid{'service_id'};
		}	
		my %p = StorProc->fetch_one('services','service_id',$hidden{'service_id'});
		my %w = ('serviceextinfo_id' => $p{'serviceextinfo_id'});
		my %e = StorProc->fetch_one_where('extended_service_info_templates',\%w);
		$ext_info = $e{'name'};
		%w = ('tree_id' => $p{'escalation_id'});
		unless ($escalation) {
			my %esc = StorProc->fetch_one_where('escalation_trees',\%w);
			$escalation = $esc{'name'};
		}
		my %objs = ('service_id' => $hidden{'service_id'},'service_name' => $service_name);
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Service name:','service_name',$service_name);
		$form .= build_service_detail($hidden{'service_id'});
		my @members = StorProc->fetch_list('extended_service_info_templates','name'); 
		$form .= Forms->list_box('Extended info template:','ext_info',\@members,$ext_info,'',$docs{'extinfo'});
		@members = ('None');
		my %where = ('type' => 'service');
		my @mems = StorProc->fetch_list_where('escalation_trees','name',\%where); 
		push (@members, @mems);
		$form .= Forms->list_box_submit('Escalation tree:','escalation',\@members,$escalation,'',$docs{'escalation'});
		if ($escalation) {
			my ($ranks, $templates) = StorProc->get_tree_detail($escalation);
			my %ranks = %{$ranks};
			my %templates = %{$templates};
			$form .= Forms->escalation_tree(\%ranks,\%templates,'service_detail');
		}
		$hidden{'name'} = $name;
		$form .= Forms->hidden(\%hidden);
		my %save = ('name' => 'save','value' => 'Save');
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'service_check') {
		my %docs = Doc->manage_hosts_service_check();
		$hidden{'service_id'} = $query->param('service_id');
		my %service = StorProc->fetch_one('services','service_id',$hidden{'service_id'});
		my $service_name = $query->param('service_name');
		my %template = StorProc->fetch_one('service_templates','servicetemplate_id',$service{'servicetemplate_id'});
		my $message = undef;
		my $inherit = 0;
		$inherit = $query->param('inherit');
		my %cmd = StorProc->fetch_one('commands','command_id', $service{'check_command'});
		my $command = $cmd{'name'};
		my $command_save = $cmd{'name'};
		my $command_line = $service{'command_line'};
		if ($query->param('command')) { $command = $query->param('command') }
		if ($query->param('command_save')) { $command_save = $query->param('command_save') }
		if ($query->param('command_line')) { $command_line = $query->param('command_line') }
		unless ($command eq $command_save) {
			%cmd = StorProc->fetch_one('commands','name',$command);
			$command_line = undef;
		}
		if ($inherit or !$command) {
			%cmd = StorProc->fetch_one('commands','command_id',$template{'check_command'});
			if ($cmd{'name'}) {
				$command = $cmd{'name'};
				$command_line = $template{'command_line'};
				$inherit = 1;
			} else {
				my $got_command = 0;
				my $stid = $template{'parent_id'};
				until ($got_command) {
					my %t = StorProc->fetch_one('service_templates','servicetemplate_id',$stid);
					if ($t{'check_command'}) {
						$got_command = 1;
						%cmd = StorProc->fetch_one('commands','command_id',$t{'check_command'});
						$command = $cmd{'name'};
						$command_line = $t{'command_line'};
						$got_command = 1;
					} else {
						if ($t{'parent_id'}) {
							$stid = $t{'parent_id'};
						} else {
							$got_command = 1;
							$message = ('Note: a parent template does not have a check command defined.');
							$required{'check_command'} = 1;
							$command = undef;
							$command_line = undef;
						}
					}
				}
			}
		}
		%cmd = StorProc->fetch_one('commands','name',$command);
		my $arg_string = $command_line;
		$arg_string =~ s/$command!//;
		my $usage = $command;
		my @args = split(/ARG/i,$cmd{'command_line'});
		my $args = undef;
		if ($args[1]) {
			$usage .= "!";
			my $cnt = 1;
			pop @args;
			foreach (@args) { 
				if ($cmd{'command_line'} =~ /ARG$cnt/i) { $args .= "ARG$cnt!" }
				$cnt++;
			}
			chop $args;
			$usage .= $args;
			unless ($command_line =~ /$command/) {
				$command_line = "$command!$args";
			}
		}
		my %objs = ('service_id' => $hidden{'service_id'},'service_name' => $service_name);
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Service Check',$docs{'service_check'});
		$form .= Forms->display_hidden('Service name:','service_name',$service_name);
		$form .= Forms->checkbox_override('Inherit check from template','inherit',$inherit,$docs{'override'});
		my %where = ('type' => 'check');
		my @commands = StorProc->fetch_list_where('commands','name',\%where);
		$form .= Forms->list_box_submit('Check command:','command',\@commands,$command,$required{'check_command'});
		$form .= Forms->display_hidden('Command definition:','',$cmd{'command_line'});
		$form .= Forms->display_hidden('Usage:','',$usage);
		$form .= Forms->text_area('Command line:','command_line',$command_line,'3','80','',$docs{'command_line'});
		unless ($host) { $host = $name }
		$form .= Forms->test_service_check($test_results,$host);
		$hidden{'command_save'} = $command;
		$hidden{'name'} = $name;
		my %instances = StorProc->get_service_instances($hidden{'service_id'});
		my %inst = ();
		foreach my $qname ($query->param) {
			if ($qname =~ /args_(\d+)/) {
				$inst{$1}{'args'} = $query->param($qname);
			} elsif ($qname =~ /status_(\d+)/) {
				$inst{$1}{'status'} = 1;
			} elsif ($qname =~ /instance_(\d+)/) {
				$inst{$1}{'instance'} = $query->param($qname);
				my $iname = $query->param($qname);
				$instances{$iname}{'id'} = $1;
			}
		}
		foreach my $i (keys %instances) {
			if ($inst{$instances{$i}{'id'}}) {
				$instances{$i}{'status'} = $inst{$instances{$i}{'id'}}{'status'};
				$instances{$i}{'args'} = $inst{$instances{$i}{'id'}}{'args'};
			}
		}
		my @rem_instances = $query->param('rem_inst');
		foreach my $id (@rem_instances) {
			foreach my $i (keys %instances) {
				if ($instances{$i}{'id'} eq $id) { delete $instances{$i} }
			}
		}
		$form .= Forms->service_instances(\%instances,$docs{'service_instance'});
		$form .= Forms->hidden(\%hidden);
		my %save = ('name' => 'save','value' => 'Save');
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'service_dependencies') {
		my %docs = Doc->manage_hosts_service_dependencies();
		$hidden{'service_id'} = $query->param('service_id');
		my $service_name = $query->param('service_name');
		my %objs = ('service_id' => $hidden{'service_id'},'service_name' => $service_name);
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		$form .= Forms->display_hidden('Service name:','service_name',$service_name);
		$form .= Forms->wizard_doc('Service Dependencies',$docs{'dependencies'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		my $dep_template = $query->param('dep_template');
		my %dep = StorProc->fetch_one('service_dependency_templates','name',$dep_template);
		my @dep_hosts = ();
		my ($host,$hosts) = StorProc->get_dep_on_hosts($dep{'servicename_id'},$properties{'host_id'});
		my @hosts = @{$hosts};
		if ($dep_template) {
			@dep_hosts = ($name);
			push (@dep_hosts,@hosts);
		}
		my %dependencies = StorProc->get_dependencies($hidden{'service_id'});
		$form .= Forms->dependency_list($name,'hosts',$hidden{'service_id'},$session_id,\%dependencies);
		my @dep_templates = StorProc->fetch_list('service_dependency_templates','name');
		$form .= Forms->dependency_add($dep_template,\@dep_templates,\@dep_hosts,\%docs);
		$hidden{'name'} = $name;
		$form .= Forms->hidden(\%hidden);
		my %add_dependency = ('name' => 'add_dependency','value' => 'Add Dependency');
		$form .= Forms->form_bottom_buttons(\%add_dependency,$tab++);
	} elsif ($obj_view eq 'service_externals') {
		$hidden{'service_id'} = $query->param('service_id');
		$hidden{'service_name'} = $query->param('service_name');
		my %objs = ('service_id' => $hidden{'service_id'},'service_name' => $hidden{'service_name'});
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		$form .= Forms->display_hidden('Service name:','service_name',$hidden{'service_name'});
		my %externals = ();
		my %where = ('service_id' => $hidden{'service_id'});
		my @externals = StorProc->fetch_list_where('external_service','external_id',\%where);
		foreach my $eid (@externals) {
			my %e = StorProc->fetch_one('externals','external_id',$eid);
			$externals{$e{'name'}} = $eid;
		}
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		if (@messages) { $form .= Forms->form_message('Status:',\@messages,'msg') }
		my %w = ('type' => 'service');
		my @external_names = StorProc->fetch_list_where('externals','name',\%w);
		my @external_list = ();
		foreach my $s (@external_names) { unless ($externals{$s}) { push @external_list, $s } }
		@external_list = sort { $a <=> $b } @external_list;
		$form .= Forms->external_list($session_id,$name,\%externals,\@external_list,'service',$hidden{'service_id'},$hidden{'service_name'});
		$hidden{'type'} = 'service';
		$hidden{'id'} = $properties{'host_id'};
		$hidden{'name'} = $name;
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons();
	} elsif ($obj_view eq 'service_external_detail') {
		my $service_name = $query->param('service_name');
		$hidden{'service_id'} = $query->param('service_id');
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		my $detail = $query->param('detail');
		my $service_external = $query->param('service_external');
		unless ($service_external) { $service_external = $properties{'external'} }
		my %where = ('external_id' => $properties{'external_id'},'service_id' => $hidden{'service_id'});
		my %external = StorProc->fetch_one_where('external_service',\%where);
		unless ($detail) { $detail = $external{'data'} }
		$form .= Forms->display_hidden('External:','service_external',$service_external);
		$form .= Forms->text_area('Detail:','detail',$detail,'30','140');
		$hidden{'external_id'} = $external{'external_id'};
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,$tab++);
	} elsif ($obj_view eq 'saved') {
		if ($hidden{'service_name'}) { $obj_view = 'service_detail' }
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		$form .= Forms->display_hidden('Saved:','',$message);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%close);
	} elsif ($obj_view eq 'saved_apply') {
		$obj_view = 'profiles';
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		$form .= Forms->display_hidden('Saved:','',$message);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons();
	} elsif ($obj_view eq 'rename') {
		$form .= Forms->host_top($properties{'name'},$session_id,$obj_view,$auth_add{'externals'},$hidden{'selected'},$hidden{'form_service'});
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->text_box('Rename to:','new_name','',$textsize{'name'},$required);
		$hidden{'name'} = $name;
		$hidden{'rename'} = $name;
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%rename,$tab++);
	} elsif ($obj_view eq 'delete_host') {
		$hidden{'name'} = $name; 
		my $message = qq(Are you sure you want to remove host $name?);
		$form .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete_host',\%hidden);
	} elsif ($obj_view eq 'deleted') {
		$form .= Forms->form_top('Status','');
		my @message = ("Host $name.");
		$form .= Forms->form_message("Removed:",\@message ,'row1');
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%continue,$tab++);		
	}
	return $form;
}



#
############################################################################
# Sub Delete Object
#

sub delete_object($$) {
	my $id = shift;
	my $name = shift;
	my $form = undef;
	my $title = undef;
	my @t_parse = split(/_/, $obj);
	foreach (@t_parse) { $_ =~ s/ies/y/g; $title .= "\u$_ "; }
	$title =~ s/s\s$//;
	my %dep_templates = ();
	$dep_templates{'time_periods'}{'host_templates'} = [ ('notification_period') ];
	$dep_templates{'time_periods'}{'service_templates'} = [ ('notification_period','check_period') ];
	$dep_templates{'time_periods'}{'contact_templates'} = [ ('host_notification_period','service_notification_period') ];	
	$dep_templates{'commands'}{'host_templates'} = [ ('check_command','event_handler') ];
	$dep_templates{'commands'}{'service_templates'} = [ ('check_command','event_handler') ];
	$dep_templates{'commands'}{'services'} = [ ('check_command') ];
	$dep_templates{'host_templates'}{'hosts'} = [ ('hosttemplate_id') ];
	$dep_templates{'host_templates'}{'profiles_host'} = [ ('host_template_id') ];
	$dep_templates{'service_templates'}{'service_templates'} = [ ('parent_id') ];
	$dep_templates{'service_templates'}{'service_names'} = [ ('template') ];
	$dep_templates{'service_templates'}{'services'} = [ ('servicetemplate_id') ];
	$dep_templates{'contact_templates'}{'contacts'} = [ ('contacttemplate_id') ];
	$dep_templates{'service_dependency_templates'}{'service_dependency'} = [ ('template') ];

#	$dep_templates{'contactgroups'}{'contactgroup_assign'} = [ ('contactgroup_id') ];

	$dep_templates{'contactgroups'}{'tree_template_contactgroup'} = [ ('contactgroup_id') ];
	$dep_templates{'escalation_templates'}{'escalation_tree_template'} = [ ('template_id') ];
	$dep_templates{'extended_service_info_templates'}{'services'} = [ ('serviceextinfo_id') ];
	$dep_templates{'extended_service_info_templates'}{'service_names'} = [ ('extinfo') ];
	$dep_templates{'extended_host_info_templates'}{'hosts'} = [ ('hostextinfo_id') ];
	$dep_templates{'extended_host_info_templates'}{'profiles_host'} = [ ('host_extinfo_id') ];
	unless ($id) {
		my $otable = $obj;
		if ($otable =~ /escalation_template/) { $otable = 'escalation_templates' }
		if ($otable eq 'escalations') { $otable = 'escalation_trees' }
		my %id = StorProc->fetch_one($otable,'name',$name);
		$id = $id{$obj_id{$otable}};
	}
	$hidden{'id'} = $id;
	my $all_clear = 1;
	my %dependencies = ();
	foreach my $table (keys %{$dep_templates{$obj}}) {
		foreach my $column (@{$dep_templates{$obj}{$table}}) {
			my @dep = ();
			if ($table =~ /services|service_dependency$/) {
				my @names = StorProc->get_hostname_servicename($table,$column,$id);
				for my $i ( 0 .. $#names ) {
					for my $name ( keys %{ $names[$i] } ) {
						push @dep, "$name - $names[$i]{$name}";
					}
				}
				$dependencies{'Host - Service'} = [ @dep ];

# another special case
#			} elsif ($table eq 'contactgroup_assign') {
#				my @names = StorProc->get_contactgroup_object($id,\%obj_id);
#				for my $i ( 0 .. $#names ) {
#					for my $name ( keys %{ $names[$i] } ) {
#						push @dep, "$name - $names[$i]{$name}";
#					}
#				}
#				$dependencies{'Templates/Hostgroups'} = [ @dep ];

			} elsif ($table eq 'tree_template_contactgroup') {
				@dep = StorProc->get_tree_contactgroup($id);
				$dependencies{'Escalation trees'} = [ @dep ];
			} elsif ($table eq 'contactgroup_contact') {
				@dep = StorProc->get_contact_contactgroup($id);
				$dependencies{'Contacts'} = [ @dep ];
			} else {
				my %where = ($column => $id);
				@dep = StorProc->fetch_list_where($table,'name',\%where);
				$dependencies{$table} = [ @dep ];
			}
			if ($dep[0]) { $all_clear = 0 }
		}
	}		
	if ($all_clear) {
		if ($query->param('confirm_delete')) {
			my $otable = $obj;
			if ($otable =~ /escalation_template/) { 
				$otable = 'escalation_templates';
				$obj = 'escalation_templates';
			}
			if ($otable eq 'escalations') { 
				$otable = 'escalation_trees';
				$obj = 'escalation_trees';
			}
			my $result = StorProc->delete_all($otable,$obj_id{$obj},$id);
			if ($result =~ /^Error/) { 
				push @errors, "Unable to process request $result";
				$form .= Forms->header($page_title,$session_id,$top_menu);
				$form .= Forms->form_top("Delete $title",'');
				$form .= Forms->form_errors(\@errors);
			} else {
				my @message = ("$name");
				$form .= Forms->header($page_title,$session_id,$top_menu,'','1');
				$form .= Forms->form_top("Delete $title",'');
				$form .= Forms->form_message('Removed:',\@message,'row1');			
			}
			$form .= Forms->hidden(\%hidden);
			$form .= Forms->form_bottom_buttons(\%continue,$tab++);
		} else {
			foreach my $name ($query->param) {
				unless ($name eq 'nocache') { $hidden{$name} = $query->param($name) }
			}
			delete $hidden{'task'};
			delete $hidden{'submit'};
			if ($obj =~ /escalation_template/) {
				$hidden{'task'} = 'escalation_template';		
			} elsif ($obj =~ /escalation_trees/) {
				$hidden{'task'} = 'escalation_trees';		
			} else {
				$hidden{'task'} = 'modify';
			}
			my $message = qq(Are you sure you want to remove $name?);
			$form .= Forms->header($page_title,$session_id,$top_menu);
			$form .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden,'bail');
			$task = 'delete';
		}
	} else {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Forms->form_top("Delete $title",'');
		$form .= Forms->display_hidden('Name:','name',$name);
		my @message = ("Cannot delete until all dependencies are removed/reassigned.");
		$form .= Forms->form_errors(\@message);	
		foreach my $dep (keys %dependencies) {
			@message = ($dep);
			$form .= Forms->form_message('Object type:',\@message,'row1');	
			$form .= Forms->form_message('&nbsp;',\@{$dependencies{$dep}},'row1');		
		}
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%close,$tab++);
	}
	return $form;
}

sub rename_object($$) {
	my $id = shift;
	my $name = shift;
	my $form = undef;
	my $title = undef;
	my $ltitle = undef;
	my @t_parse = split(/_/, $obj);
	foreach (@t_parse) { $_ =~ s/ies/y/g; $title .= "\u$_ "; $ltitle = "$_ " }
	$title =~ s/s\s$//;
	my $new_name = $query->param('new_name');
	if ($name eq $new_name) { $new_name = undef }
	my $saved = 0;
	$table = $obj;
	if ($table =~ /service_groups/) { $table = 'servicegroups'}
	if ($table =~ /escalation_template/) { $table = 'escalation_templates'}
	if ($table =~ /escalation_tree/) { $table = 'escalation_trees'}
	if ($new_name) {
		$new_name =~ s/^\s+|\s+$//;
		my %n = StorProc->fetch_one($table,'name',$new_name);
		if ($name =~ /^$new_name$/i) { delete $n{'name'} }
		if ($n{'name'}) {
			$obj_view = 'rename';
			$ltitle =~ s/s\s$//;
			push @errors, "Cannot rename. Another $ltitle has name $new_name.";
		} else {
			if ($table eq 'commands') {
				my %command = StorProc->fetch_one('commands','name',$name);
				my $results = StorProc->rename_command(\%command,$new_name);
				$name = $new_name;
				$saved = 1;
				$refresh_left = 1;
			} else {
				my %values = ('name' => $new_name);
				my $result = StorProc->update_obj($table,'name',$name,\%values);
				if ($result =~ /^Error/) { 
					push @errors, $result;
				} else {
					$name = $new_name;
					$saved = 1;
					$refresh_left = 1;
				}
			}
		}
	}
	$form .= Forms->header($page_title,$session_id,$top_menu,'',$refresh_left);
	if ($saved) {
		$form .= Forms->form_top("Rename $title", Validation->dfv_onsubmit_javascript());
		my @message = ("$name");
		$form .= Forms->form_message('Renamed:',\@message,'row1');			
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%continue,$tab++);
	} else {
		$form .= Forms->form_top("Rename $title", Validation->dfv_onsubmit_javascript());
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden("Name:",'name',$name);
		$form .= Forms->text_box('Rename to:','new_name','',$textsize{'name'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%rename,\%cancel,$tab++);
	}
	return $form;
}

#
############################################################################
# Manage
#

sub manage() {
	my $page = undef;
	my $name = $query->param('name');
	my $title = undef;
	my $validation_mini_profile = '';
	my @t_parse = split(/_/, $obj);

	foreach (@t_parse) { $title .= "\u$_ " }
	if ($query->param('cancel') || $query->param('close') || $query->param('continue')) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
	} else {
		my $task = $query->param('submit');
#
# Contacts
#
		if ($obj eq 'contacts') {
			my $name = $query->param('name');
			$hidden{'name'} = $name;
			my $got_form = undef;
			if ($query->param('delete') || $query->param('confirm_delete')) {
				unless ($query->param('bail')) {
					$page .= Forms->header($page_title,$session_id,$top_menu);
 					$page .= delete_object('',$name);
					$got_form = 1;
				}
			} elsif ($query->param('rename')) {
				$page .= rename_object('',$name);
				$got_form = 1;
			} elsif ($query->param('save')) {
				my %contact = StorProc->fetch_one('contacts','name',$name);
				my %data = parse_query('contacts','contacts');
				$properties{'template'} = $query->param('template');
				my $field_ck = check_fields();
				if ($field_ck == 0) {
					my %t = StorProc->fetch_one('contact_templates','name',$properties{'template'});
					my %vals = ('contacttemplate_id' => $t{'contacttemplate_id'},'alias' => $data{'alias'},'email' => $data{'email'},'pager' => $data{'pager'});
					my $result = StorProc->update_obj('contacts','name',$name,\%vals);
					if ($result =~ /^Error/) { push @errors, $result }
					my %where = ('contact_id' => $contact{'contact_id'});
					my $result = StorProc->delete_one_where('contactgroup_contact',\%where);
					if ($result =~ /^Error/) { push @errors, $result }
					my @mems = $query->param('contactgroup');
					foreach (@mems) {
						my %cg = StorProc->fetch_one('contactgroups','name',$_);
						my @vals = ($cg{'contactgroup_id'},$contact{'contact_id'});
						$result = StorProc->insert_obj('contactgroup_contact',\@vals);
						if ($result =~ /^Error/) { push @errors, $result }
					}
					unless (@errors) {
						my %where = ('contact_id' => $contact{'contact_id'});
						my $result = StorProc->delete_one_where('contact_overrides',\%where);
						my %values = ();
						my $got_override = undef;
						unless ($query->param('host_notification_period_override')) {
							my $np = $query->param('host_notification_period');
							my %np = StorProc->fetch_one('time_periods','name',$np);
							$values{'host_notification_period'} = $np{'timeperiod_id'};
							$got_override = 1;
						}
						unless ($query->param('service_notification_period_override')) {
							my $np = $query->param('service_notification_period');
							my %np = StorProc->fetch_one('time_periods','name',$np);
							my %np = StorProc->fetch_one('time_periods','name',$np);
							$values{'service_notification_period'} = $np{'timeperiod_id'};
							$got_override = 1;
						}
						my $data = undef;
						unless ($query->param('host_notification_options_override')) {
							my @no = $query->param('host_notification_options');
							my $str = undef;
							foreach (@no) { $str .= "$_," }
							chop $str;
							$data .= "\n  <prop name=\"host_notification_options\"><![CDATA[$str]]>\n  </prop>";
							$got_override = 1;
						}
						unless ($query->param('service_notification_options_override')) {
							my @no = $query->param('service_notification_options');
							my $str = undef;
							foreach (@no) { $str .= "$_," }
							chop $str;
							$data .= "\n  <prop name=\"service_notification_options\"><![CDATA[$str]]>\n  </prop>";
							$got_override = 1;
						}
						if ($data) {
							$values{'data'} = "<?xml version=\"1.0\" ?>\n<data>".$data."\n</data>";
						}
						if ($got_override) {
							my @vals = ($contact{'contact_id'},$values{'host_notification_period'},$values{'service_notification_period'},$values{'data'});
							$result = StorProc->insert_obj('contact_overrides',\@vals);
							if ($result =~ /^Error/) { push @errors, $result }
						}
						my %where = ('contact_id' => $contact{'contact_id'});
						my $result = StorProc->delete_one_where('contact_command_overrides',\%where);
						if ($result =~ /^Error/) { push @errors, $result }
						unless ($query->param('host_notification_commands_override')) {
							my @mems = $query->param('host_notification_commands');
							foreach my $cmd (@mems) {
								if ($cmd) {
									my %c = StorProc->fetch_one('commands','name',$cmd);
									my @vals = ($contact{'contact_id'},'host',$c{'command_id'});
									$result = StorProc->insert_obj('contact_command_overrides',\@vals);
									if ($result =~ /^Error/) { push @errors, $result }					
								}
							}
						}
						unless ($query->param('service_notification_commands_override')) {
							my @mems = $query->param('service_notification_commands');
							foreach my $cmd (@mems) {
								if ($cmd) {
									my %c = StorProc->fetch_one('commands','name',$cmd);
									my @vals = ($contact{'contact_id'},'service',$c{'command_id'});
									$result = StorProc->insert_obj('contact_command_overrides',\@vals);
									if ($result =~ /^Error/) { push @errors, $result }		
								}
							}
						}
						unless (@errors) {
							$page .= Forms->header($page_title,$session_id,$top_menu);
							my $message = "Change to contact $name accepted.";
							$page .= Forms->success('Saved',$message,'continue',\%hidden);
							$got_form = 1;
						}
					}
				}
			}
			unless ($got_form) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Contact Properties','onsubmit="selIt();"');
				$page .= build_contact();
				$page .= Forms->hidden(\%hidden);
				%save = ('name' => 'save','value' => 'Save');
				$page .= Forms->form_bottom_buttons(\%save,\%delete,\%rename,\%cancel,$tab++);
			}


		} elsif ($query->param('bail')) {
			my $title = undef;
			my @t_parse = split(/_/, $obj);
			foreach (@t_parse) { $title .= "\u$_ " }
			$title =~ s/s$//;
			$page .= Forms->header($page_title,$session_id,$top_menu);
			$page .= build_form('');
		} elsif ($query->param('delete') or $query->param('confirm_delete')) {
			if ($obj =~ /escalation/) { $hidden{'type'} = $query->param('type')	}
			$page .= Forms->header($page_title,$session_id,$top_menu);
			$page .= delete_object('',$name);
		} elsif ($query->param('save')) {
			my %values = ();
			my %data = parse_query($table,$obj);
			my $field_ck = check_fields();
			if ($field_ck == 0) {
				foreach my $key (keys %data) {
					unless ($key =~ /HASH|^name$|members|^contact$|^contactgroup$|^parents$|notification_commands/) {
						$values{$key} = $data{$key};					
					}
				}
				my $result = StorProc->update_obj($table,'name',$data{'name'},\%values);
				if ($result =~ /^Error/) { push @errors, $result }
				if ($obj eq 'contact_templates') {
					my %o = StorProc->fetch_one('contact_templates','name',$name);
					my %w = ('contacttemplate_id' => $o{'contacttemplate_id'},'type' => 'host');
					my $result = StorProc->delete_one_where('contact_command',\%w);
					if ($result =~ /^Error/) { push @errors, $result }	
					if ($data{'host_notification_commands'}) {
						my @c = split(/,/, $data{'host_notification_commands'});		
						foreach (@c) {
							my @vals = ($o{'contacttemplate_id'},'host',$_);
							my $result = StorProc->insert_obj('contact_command',\@vals);
							if ($result =~ /Error/) { push @errors, $result }
						}	
					}
					my %w = ('contacttemplate_id' => $o{'contacttemplate_id'},'type' => 'service');
					my $result = StorProc->delete_one_where('contact_command',\%w);
					if ($result =~ /^Error/) { push @errors, $result }
					if ($data{'service_notification_commands'}) {
						my @c = split(/,/, $data{'service_notification_commands'});		
						foreach (@c) {
							my @vals = ($o{'contacttemplate_id'},'service',$_);
							my $result = StorProc->insert_obj('contact_command',\@vals);
							if ($result =~ /Error/) { push @errors, $result }
						}	
					}
				} elsif ($obj eq 'contactgroups') {
					my %cg = StorProc->fetch_one('contactgroups','name',$data{'name'});
					my $result = StorProc->delete_all('contactgroup_contact','contactgroup_id',$cg{'contactgroup_id'});
					if ($result =~ /^Error/) { push @errors, $result }
					if ($data{'contact'}) {
						my @mems = split(/,/, $data{'contact'});
						foreach (@mems) {
							my %c = StorProc->fetch_one('contacts','name',$_);
							my @vals = ($cg{'contactgroup_id'},$c{'contact_id'});
							$result = StorProc->insert_obj('contactgroup_contact',\@vals);
							if ($result =~ /^Error/) { push @errors, $result }
						}
					}
				} elsif ($obj eq 'hostgroups') {
					my %n = StorProc->fetch_one('hostgroups','name',$name);
					my $result = StorProc->delete_all('hostgroup_host','hostgroup_id',$n{'hostgroup_id'});
					if ($result =~ /^Error/) { push @errors, $result }
					if ($data{'members'}) {
						my @mems = split(/,/, $data{'members'});
						foreach (@mems) {
							my %m = StorProc->fetch_one('hosts','name',$_);
							my @vals = ($n{'hostgroup_id'},$m{'host_id'});
							$result = StorProc->insert_obj('hostgroup_host',\@vals);
							if ($result =~ /^Error/) { push @errors, $result }
						}
					}
					my %hostgroup = StorProc->fetch_one($table,'name',$name);
					my %w = ( 'hostgroup_id' => $hostgroup{'hostgroup_id'});
					my $result = StorProc->delete_one_where('contactgroup_hostgroup',\%w);
					if ($result =~ /^Error/) { push @errors, $result }
					if ($data{'contactgroup'}) {
						my @mems = split(/,/, $data{'contactgroup'});
						foreach (@mems) {
							my %cg = StorProc->fetch_one('contactgroups','name',$_);
							my $table_name = $table_by_object{$obj};
							my @vals = ($cg{'contactgroup_id'},$hostgroup{'hostgroup_id'});
							$result = StorProc->insert_obj('contactgroup_hostgroup',\@vals);
							if ($result =~ /^Error/) { push @errors, $result }
						}
					}
				}
				elsif ($obj eq 'host_templates') { # GWMON-4694, GWMON-5062
					my %o = StorProc->fetch_one('host_templates','name',$name);
					my %w = ('hosttemplate_id' => $o{'hosttemplate_id'});
					my $result = StorProc->delete_one_where('contactgroup_host_template',\%w);
					if ($result =~ /^Error/) { push @errors, $result }	
					if ($data{'contactgroup'}) {
						my @cg = split(/,/, $data{'contactgroup'});		
						foreach (@cg) {
							my %cg_obj = StorProc->fetch_one('contactgroups','name',$_);
							my @vals = ($cg_obj{'contactgroup_id'},$o{'hosttemplate_id'});
							my $result = StorProc->insert_obj('contactgroup_host_template',\@vals);
							if ($result =~ /Error/) { push @errors, $result }
						}
					}
				}
				unless (@errors) {
					my $message = "Changes to $name have been saved.";
					$hidden{'name'} = undef;
					$page .= Forms->header($page_title,$session_id,$top_menu);
					$page .= Forms->success('Updated',$message,'continue',\%hidden);
				} else {
					foreach (@errors) { error_out("errors $_") }
				}
			} elsif ($field_ck == 1) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= build_form('');
			}
		} elsif ($query->param('rename')) {
			$page .= rename_object('',$name);
		} elsif ($name) {
			my $title = undef;
			my @t_parse = split(/_/, $obj);
			foreach (@t_parse) { $title .= "\u$_ " }
			$title =~ s/s$//;
			$page .= Forms->header($page_title,$session_id,$top_menu);
			$page .= build_form($validation_mini_profile);
		}
	}
	return $page;
}


#
############################################################################
# Tools
#

sub tools() {
	my $page = undef;
	if ($query->param('close') || $query->param('continue')) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$obj = 'close';
	} elsif ($obj eq 'host_delete_tool' && $query->param('remove_host')) {
		my @hosts = $query->param('delete_host');
		my %host_name = StorProc->get_table_objects('hosts');
		foreach my $host (@hosts) {
			$host = uri_unescape($host);
#			my %where = ('type' => 'hosts','object' => $host_name{$host});
#			my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
#			if ($result =~ /^Error/) { push @errors, $result }
			my $result = StorProc->delete_all('hosts','name',$host);
			if ($result =~ /^Error/) { push @errors, $result }
		}
	} elsif ($obj eq 'service_delete_tool' && $query->param('delete_host')) {
		my $service = $query->param('service');
		my @hosts = $query->param('delete_host');
		my %host_name = StorProc->get_table_objects('hosts');
		my %service_name = StorProc->get_table_objects('service_names');		
		my %host_service = StorProc->get_host_service($service_name{$service});
		foreach my $host (@hosts) {
			$host = uri_unescape($host);
#			my %where = ('type' => 'services','object' => $host_service{$host_name{$host}});
#			my $result = StorProc->delete_one_where('contactgroup_assign',\%where);
#			if ($result =~ /^Error/) { push @errors, $result }
			my %where = ('servicename_id' => $service_name{$service},'host_id' => $host_name{$host});
			my $result = StorProc->delete_one_where('services',\%where);
			if ($result =~ /^Error/) { push @errors, $result }
		}
	}
	if ($obj eq 'export') {
		use MonarchFile;
		my @results = ();
		my ($files, $errors) = Files->build_files($user_acct,'','','1',$nagios_ver,$nagios_etc,"$doc_root/monarch/download",'1');
		my @errors = @{$errors};
		my @files = @{$files};
		if (@errors) { 
			$page .= Forms->form_top('Export Errors','','');
			$page .= Forms->form_errors(\@errors);
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%continue,$tab++);
		} else {
			my $tarball = pop @files;
			my @list = ($tarball);
			@files = sort @files;
			push (@list, @files);
			my $server = $ENV{'SERVER_NAME'};
			$page .= Forms->header($page_title,$session_id,$top_menu);
			$page .= Forms->table_download_links("$doc_root/monarch/download",\@list,$server);
		}
	} elsif ($obj eq 'host_delete_tool') {
		my $search = $query->param('search');
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top('Delete Hosts','');
		my @host_search = StorProc->get_host_search_matrix();
		$page .= Forms->list_box_submit('Select hosts:','search',\@host_search,$search);
		$hidden{'view'} = 'tools';
		$page .= Forms->hidden(\%hidden);
		my %hosts = ();
		if ($search) {
			my $searstr = $search;
			chop $searstr;
			%hosts = StorProc->search($searstr, -1); # -1 means do not limit number of results
			if (%hosts) {
				$page .= Forms->mas_delete(\%hosts);
				$page .= Forms->toggle_delete();
			}
		} 
		unless (%hosts) { $page .= Forms->form_bottom_buttons(\%close,$tab++) }
	} elsif ($obj eq 'service_delete_tool') {
		my $service = $query->param('service');
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top('Delete Services','');
		my @services = StorProc->fetch_list('service_names','name');
		$page .= Forms->list_box_submit('Select service:','service',\@services,$service);
		$hidden{'view'} = 'tools';
		$page .= Forms->hidden(\%hidden);
		my @hosts = ();
		if ($service) {
			my %svc = StorProc->fetch_one('service_names','name',$service);
			@hosts = StorProc->get_service_hosts($svc{'servicename_id'});
			if (@hosts) {
				my %host_srv = ();
				foreach my $host (sort @hosts) { $host_srv{$host} = $service }
				$page .= Forms->mas_delete(\%host_srv);
				$page .= Forms->toggle_delete();
			}
		} 
		unless (@hosts) { $page .= Forms->form_bottom_buttons(\%close,$tab++) }
	}
	return $page;
}

#
############################################################################
# Groups
#

sub groups() {
	my $obj_view = $query->param('obj_view');
	my @views = ('detail','macros','hosts','sub_groups','rename');
	foreach my $v (@views) {
		if ($query->param($v)) { $obj_view = $v }
	}
	my %save_macros = ();
	my @remove_macros = ();
	my $form = undef;
	@errors = ();
	my $name = $query->param('name');
	$name =~ s/^\s+|\s+$//;
	my %group = StorProc->fetch_one('monarch_groups','name',$name);
	my $message = undef;
	if ($query->param('add')) {
		unless ($group{'name'} || $name eq '' || $name =~ /\/|\?|\<|\>|\\|\:|\*|\||\"|\'|\^/) {
			my $data .= qq(<?xml version="1.0" ?>
<data>
 <prop name="label_enabled"><![CDATA[]]>
 </prop>
 <prop name="label"><![CDATA[]]>
 </prop>
 <prop name="use_hosts"><![CDATA[]]>
 </prop>
 <prop name="nagios_etc"><![CDATA[]]>
 </prop>
 <prop name="checks_enabled"><![CDATA[]]>
 </prop>
 <prop name="passive_checks_enabled"><![CDATA[]]>
 </prop>
 <prop name="active_checks_enabled"><![CDATA[]]>
 </prop>
</data>);
			my @values = ('',$name,'','','',$data);
			my $id = StorProc->insert_obj_id('monarch_groups',\@values,'group_id');
			unless ($id =~ /^Error/) { 
				unless ($is_portal) {
					my %super_user = StorProc->fetch_one('user_groups','name','super_users');
					my @values = ($id,'group_macro',$super_user{'usergroup_id'},$name);
					my $result = StorProc->insert_obj('access_list',\@values);
					if ($result =~ /^Error/) { push @errors, $result }
					unless ($user_acct eq 'super_user') {
						my %where = ('user_id' => $userid);
						my @user_groups = StorProc->fetch_list_where('user_group','usergroup_id',\%where);
						foreach my $ugid (@user_groups) {
							if ($super_user{'usergroup_id'} eq $ugid) { next }
							my @values = ($id,'group_macro',$ugid,$name);
							my $result = StorProc->insert_obj('access_list',\@values);
							if ($result =~ /^Error/) { push @errors, $result }
						}
					}
				}
				$obj_view = 'detail';
			} else {
				push @errors, $id;
				$obj_view = 'new';
			}
		} else {
			push @errors, "Check name field. It's either blank, contains illegal characters or a record exists.";
			$obj_view = 'new';
		}
	} elsif ($query->param('cancel')) {
		$obj_view = '';
	} elsif ($query->param('close') || $query->param('continue')) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$obj_view = 'close';
	} elsif ($query->param('export')) {
		my $results = undef;
		if ($results =~ /^Error/) { 
			push @errors, $results;
		} else {
			$obj_view = 'exported';
		}
	} elsif ($query->param('rename') && $query->param('new_name')) {
		my $new_name = $query->param('new_name');
		$new_name =~ s/^\s+|\s+$//;
		my %group_exists =  StorProc->fetch_one('monarch_groups','name',$new_name);
		if ($new_name =~ /\s|\$|!/) {
			push @errors, "Check name (name = $new_name). Names can not contain illegal characters.";
		} elsif ($new_name && !$group_exists{'name'}) {
			my %values = ('name' => $new_name);
			my $result = StorProc->update_obj('monarch_groups','name',$name,\%values);				
			if ($result =~ /^Error/) { 
				push @errors, $result;
			} else {
				$name = $new_name;
				$refresh_left = 1;
			}
		} else {
			push @errors, "Check name (name = '$new_name'). It is either blank or a record already exixts.";
		}
		unless (@errors) { $obj_view = 'detail' }
	} elsif ($query->param('save')) {
		my $checks_enabled = $query->param('checks_enabled');
		my $active_checks_enabled = $query->param('active_checks_enabled');
		my $passive_checks_enabled = $query->param('passive_checks_enabled');
		unless ($active_checks_enabled) { $active_checks_enabled = '-zero-' }
		unless ($passive_checks_enabled) { $passive_checks_enabled = '-zero-' }
		my $use_hosts = $query->param('use_hosts');
		my $nagios_etc = $query->param('nagios_etc');
		my $location = $query->param('location');
		my $description = $query->param('description');
		my $inactive = $query->param('inactive');
		my $data .= qq(<?xml version="1.0" ?>
<data>
 <prop name="label_enabled"><![CDATA[$group{'label_enabled'}]]>
 </prop>
 <prop name="label"><![CDATA[$group{'label'}]]>
 </prop>
 <prop name="nagios_etc"><![CDATA[$nagios_etc]]>
 </prop>
 <prop name="use_hosts"><![CDATA[$use_hosts]]>
 </prop>
 <prop name="checks_enabled"><![CDATA[$checks_enabled]]>
 </prop>
 <prop name="passive_checks_enabled"><![CDATA[$passive_checks_enabled]]>
 </prop>
 <prop name="active_checks_enabled"><![CDATA[$active_checks_enabled]]>
 </prop>
</data>);
		my %values = ('location' => $location,'description' => $description,'status' => $inactive,'data' => $data);
		my $result = StorProc->update_obj('monarch_groups','name',$name,\%values);
		if ($result =~ /^Error/) { push @errors, $result }				
		my @contactgroups = $query->param('contactgroups');
		my %contactgroup_name = StorProc->get_table_objects('contactgroups');
#		my %where = ('object' => $group{'group_id'},'type' => 'monarch_group');
#		$result = StorProc->delete_one_where('contactgroup_assign',\%where);
#		if ($result =~ /^Error/) { push @errors, $result }
		foreach my $cg (@contactgroups) {

#			my @values = ($contactgroup_name{$cg},'monarch_group',$group{'group_id'});
#			my $result = StorProc->insert_obj('contactgroup_assign',\@values);
			my @values = ($contactgroup_name{$cg},$group{'group_id'});
			my $result = StorProc->insert_obj('contactgroup_group',\@values);
			
			if ($result =~ /^Error/) { push @errors, $result }
		}
		unless (@errors) { $obj_view = 'saved' }
	} elsif ($query->param('set_values')) {
		my %monarch_macros = StorProc->get_table_objects('monarch_macros');
		my $label_enabled = 0;
		foreach my $qname ($query->param) {
			if ($qname =~ /label_enabled/) { $label_enabled = 1 }
			if ($qname =~ /value_(\S+)/) {
				my %where = ('macro_id' => $monarch_macros{$1},'group_id' => $group{'group_id'});
				my $val = $query->param($qname);
				my %values = ('value' => $val);
				my $result = StorProc->update_obj_where('monarch_group_macro',\%values,\%where);
				if ($result =~ /^Error/) { push @errors, $result }				
			}
		}
		my $label = $query->param('label');
		my $data .= qq(<?xml version="1.0" ?>
<data>
 <prop name="label_enabled"><![CDATA[$label_enabled]]>
 </prop>
 <prop name="label"><![CDATA[$label]]>
 </prop>
 <prop name="nagios_etc"><![CDATA[$group{'nagios_etc'}]]>
 </prop>
 <prop name="use_hosts"><![CDATA[$group{'use_hosts'}]]>
 </prop>
 <prop name="checks_enabled"><![CDATA[$group{'checks_enabled'}]]>
 </prop>
 <prop name="passive_checks_enabled"><![CDATA[$group{'passive_checks_enabled'}]]>
 </prop>
 <prop name="active_checks_enabled"><![CDATA[$group{'active_checks_enabled'}]]>
 </prop>
</data>);
		my %values = ('data' => $data);
		my $result = StorProc->update_obj('monarch_groups','name',$name,\%values);
		if ($result =~ /^Error/) { push @errors, $result }				
		unless (@errors) { 
			$obj_view = 'saved';
			$message = "Macro values and settings updated.";
		}
	} elsif ($query->param('add_macro')) {
		my %macros = StorProc->get_macros();
		my %monarch_macros = StorProc->get_table_objects('monarch_macros');
		my @macros = $query->param('add_macro_checked');
		foreach my $macro (@macros) {
			my @values = ($group{'group_id'},$macros{$macro}{'id'},$macros{$macro}{'value'});
			my $result = StorProc->insert_obj('monarch_group_macro',\@values);
			if ($result =~ /^Error/) { push @errors, $result }				
		}
	} elsif ($query->param('remove_macro')) {
		my %monarch_macros = StorProc->get_table_objects('monarch_macros');
		my @macros = $query->param('rem_macro_checked');
		foreach my $macro (@macros) {
			my %where = ('group_id' => $group{'group_id'},'macro_id' => $monarch_macros{$macro});
			my $result = StorProc->delete_one_where('monarch_group_macro',\%where);
			if ($result =~ /^Error/) { push @errors, $result }				
		}
	} elsif ($query->param('add_group')) {
		my %monarch_groups = StorProc->get_table_objects('monarch_groups');
		my @groups = $query->param('add_group_checked');
		my %group_hosts = ();
		my %host_group = ();
		my @order = ();
		my %group_child = ();
		my %parents_all = StorProc->get_group_parents_all();
		my %group_names = StorProc->get_table_objects('monarch_groups');
		foreach my $group (@groups) {
			my ($group_hosts, $order) = StorProc->get_group_hosts($group,\%parents_all,\%group_names,\%group_hosts,\@order,\%group_child);
			@order = @{ $order };
			foreach my $group (@order) {
				my %where = ('group_id' => $group{'group_id'},'child_id' => $monarch_groups{$group});
				my $result = StorProc->delete_one_where('monarch_group_child',\%where);
				if ($result =~ /^Error/) { push @errors, $result }				
			}
			my @values = ($group{'group_id'},$monarch_groups{$group});
			my $result = StorProc->insert_obj('monarch_group_child',\@values);
			if ($result =~ /^Error/) { push @errors, $result }				
		}
	} elsif ($query->param('remove_group')) {
		my %monarch_groups = StorProc->get_table_objects('monarch_groups');
		my @children = $query->param('rem_group_checked');
		foreach my $child (@children) {
			my %where = ('group_id' => $group{'group_id'},'child_id' => $monarch_groups{$child});
			my $result = StorProc->delete_one_where('monarch_group_child',\%where);
			if ($result =~ /^Error/) { push @errors, $result }				
		}	
	} elsif ($query->param('add_host')) {
		my %hosts = StorProc->get_table_objects('hosts');
		my @hosts = $query->param('add_host_checked');
		foreach my $host (@hosts) {
			my @values = ($group{'group_id'},$hosts{$host});
			my $result = StorProc->insert_obj('monarch_group_host',\@values);
			if ($result =~ /^Error/) { push @errors, $result }				
		}
	} elsif ($query->param('add_hostgroup')) {
		my %hostgroups = StorProc->get_table_objects('hostgroups');
		my @hostgroups = $query->param('add_hostgroup_checked');
		foreach my $hostgroup (@hostgroups) {
			my @values = ($group{'group_id'},$hostgroups{$hostgroup});
			my $result = StorProc->insert_obj('monarch_group_hostgroup',\@values);
			if ($result =~ /^Error/) { push @errors, $result }				
		}
	} elsif ($query->param('remove_host')) {
		my %hosts = StorProc->get_table_objects('hosts');
		my @hosts = $query->param('rem_host_checked');
		foreach my $host (@hosts) {
			my %where = ('group_id' => $group{'group_id'},'host_id' => $hosts{$host});
			my $result = StorProc->delete_one_where('monarch_group_host',\%where);
			if ($result =~ /^Error/) { push @errors, $result }				
		}	
		my %hostgroups = StorProc->get_table_objects('hostgroups');
		my @hostgroups = $query->param('rem_hostgroup_checked');
		foreach my $hostgroup (@hostgroups) {
			my %where = ('group_id' => $group{'group_id'},'hostgroup_id' => $hostgroups{$hostgroup});
			my $result = StorProc->delete_one_where('monarch_group_hostgroup',\%where);
			if ($result =~ /^Error/) { push @errors, $result }				
		}	
	} elsif ($query->param('delete') || $query->param('confirm_delete')) {
		if ($query->param('yes')) {
			my $result = StorProc->delete_all('monarch_groups','group_id',$group{'group_id'});
			if ($result =~ /^Error/) { push @errors, $result }
			unless (@errors) { 
				unless ($is_portal) {
					my %where = ('object' => $group{'group_id'},'type' => 'group_macro');
					my $result = StorProc->delete_one_where('access_list',\%where);
					if ($result =~ /^Error/) { push @errors, $result }
				}
				$refresh_left = 1;
				$obj_view = 'deleted';
			}
		} elsif ($query->param('no')) {
			$obj_view = 'detail';
		} else {
			foreach my $name ($query->param) {
				unless ($name eq 'nocache') { $hidden{$name} = $query->param($name) }
			}
			$obj_view = 'delete';
		}
	}
	my %docs = Doc->monarch_groups();
	my %save = ('name' => 'save','value' => 'Save');
	my %apply = ('name' => 'apply','value' => 'Apply');
	my %export = ('name' => 'export','value' => 'Export');
	my %obj = ();
	$form .= Forms->header($page_title,$session_id,$top_menu,'',$refresh_left);
	if ($obj_view eq 'detail') {
		$hidden{'obj_view'} = 'detail';
		$form .= Forms->group_top($name,'detail');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->text_box('Description:','description',$group{'description'},$textsize{'description'},'',$docs{'description'});
		my @members = StorProc->get_contactgroups('monarch_group',$group{'group_id'});
		my @nonmembers = StorProc->fetch_list('contactgroups','name');
		$form .= Forms->group_main(\%group,\%docs,\@members,\@nonmembers);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,\%delete,\%rename,\%close,$tab++);
	} elsif ($obj_view eq 'macros') {
		$hidden{'obj_view'} = 'macros';
		$form .= Forms->group_top($name,'macros');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Group macros',$docs{'macros'});
		my %macros = StorProc->get_macros();
		my %group_macros = StorProc->get_group_macros($group{'group_id'});
		foreach my $macro (keys %macros) {
			if ($group_macros{$macro}) { delete $macros{$macro} }
		}
		$form .= Forms->group_macros(\%macros,\%group_macros,$group{'label_enabled'},$group{'label'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons();
	} elsif ($obj_view eq 'hosts') {
		$hidden{'obj_view'} = 'hosts';
		$form .= Forms->group_top($name,'hosts');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Host Assignment',$docs{'assign_hosts'});
		my ($nonmembers,$members) = StorProc->get_group_hosts_old($group{'group_id'});
		my %nonmembers = %{ $nonmembers };
		my %members = %{ $members };
		my ($hostgroup_nonmembers,$hostgroup_members) = StorProc->get_hostgroups_hosts($group{'group_id'});
		my %hostgroup_nonmembers = %{ $hostgroup_nonmembers };
		my %hostgroup_members = %{ $hostgroup_members };
		$form .= Forms->group_hosts(\%members,\%nonmembers,\%hostgroup_members,\%hostgroup_nonmembers);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons();
	} elsif ($obj_view eq 'sub_groups') {
		$hidden{'obj_view'} = 'sub_groups';
		$form .= Forms->group_top($name,'sub_groups');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Sub Groups',$docs{'sub_groups'});
		my %parents_all = StorProc->get_group_parents_all();
		my %group_names = StorProc->get_table_objects('monarch_groups');
		my %group_hosts = ();
		my @order = ();
		my %group_child = ();
		my %nonmembers = StorProc->get_possible_groups($group{'name'});
		my ($group_hosts, $order, $group_child) = StorProc->get_group_hosts($group{'name'},\%parents_all,\%group_names,\%group_hosts,\@order,\%group_child);
		%group_hosts = %{ $group_hosts };
		@order = @{ $order };
		%group_child = %{ $group_child  };
		$form .= Forms->group_children(\%group_hosts,\@order,\%group_child,\%nonmembers);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons();
	} elsif ($obj_view eq 'new') {
		$form .= Forms->form_top('New Monarch Group', Validation->dfv_onsubmit_javascript(),'');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->text_box('Name:','name',$name,$textsize{'name'},'',$docs{'name'});
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);
	} elsif ($obj_view eq 'nagios_cgi') {
		$hidden{'obj_view'} = 'nagios_cgi';
		$hidden{'name'} = $name;
		my $step = $query->param('step');
		if ($query->param('next')) { $step++ }
		if ($query->param('back')) { $step-- }
		$form .= nagios_cgi($group{'group_id'},$name);
	} elsif ($obj_view eq 'nagios_cfg') {
		$hidden{'obj_view'} = 'nagios_cfg';
		$hidden{'name'} = $name;
		my $step = $query->param('step');
		if ($query->param('next')) { $step++ }
		if ($query->param('back')) { $step-- }
		$form .= nagios_cfg($group{'group_id'},$name);
	} elsif ($obj_view eq 'resource_cfg') {
		$hidden{'obj_view'} = 'resource_cfg';
		$hidden{'name'} = $name;
		$form .= resource_cfg($group{'group_id'},$name);
	} elsif ($obj_view eq 'pre_flight_test') {
		$hidden{'obj_view'} = 'pre_flight_test';
		$form .= pre_flight($name);
	} elsif ($obj_view eq 'build_instance') {
		my ($files, $errors) = Files->build_files($user_acct,$name,'2','',$nagios_ver,$nagios_etc,'','1','1');
		my @errors = @{$errors};
		my @files = @{$files};
		if (@errors) { 
			$form .= Forms->form_top('Build Instance','','');
			$form .= Forms->display_hidden('Name:','name',$name);				
			$form .= Forms->form_errors(\@errors);
			$form .= Forms->hidden(\%hidden);
			$form .= Forms->form_bottom_buttons(\%continue,$tab++);
		} else {
			my @results = ("Files for build generated in $group{'location'}.");
			use MonarchDeploy;
			push (@results, Deploy->deploy($name,$group{'location'},$group{'nagios_etc'},$monarch_home));
			$form .= Forms->form_top('Build Instance','','');
			$form .= Forms->display_hidden('Name:','name',$name);				
			$form .= Forms->form_message('Status',\@results);
			$form .= Forms->hidden(\%hidden);
			$form .= Forms->form_bottom_buttons(\%continue,$tab++);
		}
	} elsif ($obj_view eq 'export') {
		use MonarchFile;
		my ($files, $errors) = Files->build_files($user_acct,$name,'2','1',$nagios_ver,$nagios_etc,"$doc_root/monarch/download",'1');
		my @errors = @{$errors};
		my @files = @{$files};
		if (@errors) { 
			$form .= Forms->form_top('Export Instance','','');
			$form .= Forms->display_hidden('Name:','name',$name);				
			$form .= Forms->form_errors(\@errors);
			$form .= Forms->hidden(\%hidden);
			$form .= Forms->form_bottom_buttons(\%continue,$tab++);
		} else {
			my $tarball = pop @files;
			my @list = ($tarball);
			@files = sort @files;
			push (@list, @files);
			my $server = $ENV{'SERVER_NAME'};
			$form .= Forms->header($page_title,$session_id,$top_menu);
			$form .= Forms->table_download_links("$doc_root/monarch/download",\@list,$server);
		}
	} elsif ($obj_view eq 'delete') {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Forms->form_top('Groups','','');
		$form .= Forms->wizard_doc('Remove group?',$name);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%yes,\%no,$tab++);
	} elsif ($obj_view eq 'rename') {
		$form .= Forms->form_top('Rename Group', Validation->dfv_onsubmit_javascript(),'');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Name:','name',$name);
		$form .= Forms->text_box('Rename:','new_name','',$textsize{'name'},'');
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%rename,\%cancel,$tab++);
	} elsif ($obj_view eq 'saved') {
		$form .= Forms->group_top($name,'');
		$form .= Forms->display_hidden('Saved','',$message);				
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%close,$tab++);		
	}
	return $form;
}

#
############################################################################
# Macros
#

sub macros() {
	my $form = undef;
	my $name = $query->param('name');
	my $rename_macro = undef;
	my $saved = undef;
	my $are_you_sure = undef;
	my %save_macros = ();
	my @remove_macros = ();
	foreach my $qname ($query->param) {
		if ($qname =~ /rename_(\S+)/) { 
			$rename_macro = 1;
			$name = $1;	
		} elsif ($qname =~ /remove_(\S+)/) {
			push @remove_macros, $1;
		} elsif ($qname =~ /value_(\S+)/) {
			$save_macros{$1}{'value'} = $query->param($qname);
		} elsif ($qname =~ /description_(\S+)/) {
			$save_macros{$1}{'description'} = $query->param($qname);
		}
	}
	if ($query->param('add')) {
		$name =~ s/^\s+|\s+$//;
		my %macro = StorProc->fetch_one('monarch_macros','name',$name);
		if ($name =~ /\s|\$|!/) {
			push @errors, "Check name (name = $name). Names can not contain illegal characters.";
		} elsif ($name && $macro{'name'} ne $name) {
			my $description = $query->param('description');
			my $value = $query->param('value');
			my @values = ('',$name,$value,$description);
			my $result = StorProc->insert_obj('monarch_macros',\@values);
			if ($result =~ /^Error/) { push @errors, $result }				
		} else {
			push @errors, "Check name (name = '$name'). It is either blank or a record already exixts.";
		}
	} elsif ($query->param('save')) {
		foreach my $macro (keys %save_macros) {
			my %values = ('description' => $save_macros{$macro}{'description'},'value' => $save_macros{$macro}{'value'});
			my $result = StorProc->update_obj('monarch_macros','name',$macro,\%values);				
			if ($result =~ /^Error/) { push @errors, $result }				
		}
		unless (@errors) { $saved = "All changes accepted." }
	} elsif ($query->param('rename')) {
		$rename_macro = 1;
		my $new_name = $query->param('new_name');
		$new_name =~ s/^\s+|\s+$//;
		my %macro = StorProc->fetch_one('monarch_macros','name',$new_name);
		if ($new_name =~ /\s|\$|!/) {
			push @errors, "Check name (name = $new_name). Names can not contain illegal characters.";
		} elsif ($new_name && !$macro{'name'}) {
			my %values = ('name' => $new_name);
			my $result = StorProc->update_obj('monarch_macros','name',$name,\%values);				
			if ($result =~ /^Error/) { push @errors, $result }				
		} else {
			push @errors, "Check name (name = '$new_name'). It is either blank or a record already exixts.";
		}
		unless (@errors) { $rename_macro = undef }
	} elsif ($query->param('remove') || $query->param('are_you_sure')) {
		unless ($query->param('no')) {
			if ($query->param('yes')) {
				foreach my $macro (@remove_macros) { 
					my $result = StorProc->delete_all('monarch_macros','name',$macro);				
					if ($result =~ /^Error/) { push @errors, $result }					
				}
				
			} else {
				$hidden{'remove'} = 1;
				my @checked =  $query->param('macro_checked');
				$are_you_sure = "Are you sure you want to remove the following macros from all groups and service checks?"; 
				foreach my $macro (@checked) { $hidden{"remove_$macro"} = 1; $are_you_sure .= "<br />$macro"; }
			}
		}
	}
	if ($query->param('close') || $query->param('continue')) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
	} elsif ($rename_macro) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Forms->form_top('Rename Macro', Validation->dfv_onsubmit_javascript(),'');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->display_hidden('Name:','name',$name);
		$form .= Forms->text_box('Rename:','new_name','',$textsize{'name'},'');
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%rename,\%cancel,$tab++);
	} elsif ($are_you_sure) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Forms->form_top('Macros','','');
		$form .= Forms->wizard_doc('Remove macros',$are_you_sure);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%yes,\%no,$tab++);
	} elsif ($saved) {
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Forms->form_top('Macros','','');
		$form .= Forms->display_hidden('Saved:','',$saved);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%continue,$tab++);
	} else {
		my %docs = Doc->monarch_macros();
		$form .= Forms->header($page_title,$session_id,$top_menu);
		$form .= Forms->form_top('Macros','','');
		if (@errors) { $form .= Forms->form_errors(\@errors) }
		$form .= Forms->wizard_doc('Group macros',$docs{'macros'});
		my %macros = StorProc->get_macros();
		$form .= Forms->macros(\%macros);
		$form .= Forms->hidden(\%hidden);
		$form .= Forms->form_bottom_buttons(\%save,\%remove,\%close,$tab++);		
	}
	return $form;
}

#
############################################################################
# Nagios cgi
#

sub nagios_cgi($$) {
	my $gid = shift;
	my $gname = shift;
	my %checks = ();
	my %objects = ();
	my $step = $query->param('step');
	if ($step eq '1') {
		%checks = ('show_context_help' => '0',
			'use_authentication' => '0');
	}
	my %layout_val = ('User-defined coordinates' => '-zero-','Depth_layers' => '1','Collapsed tree' => '2','Balanced tree' => '3','Circular' => '4','Circular (Mark Up)' => '5','Circular (Balloon)' => '6');
	if ($query->param('next')) {
		my %nagios_set = ();
		if ($gid) {
			my %where = ('group_id' => $gid,'name' => 'physical_html_path');
			%nagios_set = StorProc->fetch_one_where('monarch_group_props',\%where);
		} else {
			%nagios_set = StorProc->fetch_one('setup','name','physical_html_path');
		}
		if ($nagios_set{'name'}) {
			my %nag_defined = ();
			if ($gid) {
				# GWMON-4818 monarch_group_props contains duplicate entries for nagios_cgi and nagios_cfg per group
				# Need to loop through hash of table contents to eliminate duplicate entries
				my %unique_props = ();
				my %where = ('group_id' => $gid,'type' => 'nagios_cgi');
				my %group_prop_hash = StorProc->fetch_list_hash_array('monarch_group_props',\%where);
				# process the id's in decending order to keep the latest values saved
				my @keys = keys %group_prop_hash;
				foreach my $id (sort {$b <=>$a } @keys) {
					if ($unique_props{$group_prop_hash{$id}[2]}) {
						%where = ('prop_id' => $id);
						my $res = StorProc->delete_one_where('monarch_group_props',\%where);
					} else {
						$unique_props{$group_prop_hash{$id}[2]} = 1;
						$nag_defined{$group_prop_hash{$id}[2]} = 1;
					}
					
				}
			} else {	
				my %where = ('type' => 'nagios_cgi');
				%nag_defined = StorProc->fetch_list_hash_array('setup',\%where);
			}
			foreach my $name($query->param) {
				unless ($name =~ /^next$|user_acct|^obj$|^nocache$/) {
					my $val = undef;
					if ($name =~ /layout/) {
						$val = $query->param($name);
						$val = $layout_val{$val};
					} elsif (defined $checks{$name}) {
						$checks{$name} = '1';
					} else {
						$val = $query->param($name);
					}
					if ($gid) {
						if ($nag_defined{$name}) {
							my %where = ('group_id' => $gid,'type' => 'nagios_cgi','name' => $name);
							my %values = ('value' => $val);
							my $result = StorProc->update_obj_where('monarch_group_props',\%values,\%where);
							if ($result =~ /^Error/) { push @errors, $result }
						} else {
							my @values = ('',$gid,$name,'nagios_cgi',$val);
							my $result = StorProc->insert_obj('monarch_group_props',\@values);
							if ($result =~ /^Error/) { push @errors, $result }
						}	
					} else {		
						if ($nag_defined{$name}) {
							my %values = ('value' => $val);
							my $result = StorProc->update_obj('setup','name',$name,\%values);
							if ($result =~ /^Error/) { push @errors, $result }
						} else {
							my @values = ($name,'nagios_cgi',$val);
							my $result = StorProc->insert_obj('setup',\@values);
							if ($result =~ /^Error/) { push @errors, $result }
						}
					}
				}
			}
				
			foreach my $name (keys %checks) {
				if ($gid) {
					if ($nag_defined{$name}) {
						my %where = ('group_id' => $gid,'type' => 'nagios_cgi','name' => $name);
						my %values = ('value' => $checks{$name});
						my $result = StorProc->update_obj_where('monarch_group_props',\%values,\%where);
						if ($result =~ /^Error/) { push @errors, $result }
					} else {
						my @values = ('',$gid,$name,'nagios_cgi',$checks{$name});
						my $result = StorProc->insert_obj('monarch_group_props',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				} else {
					if ($nag_defined{$name}) {
						my %values = ('value' => $checks{$name});
						my $result = StorProc->update_obj('setup','name',$name,\%values);
						if ($result =~ /^Error/) { push @errors, $result }
					} else {
						my @values = ($name,'nagios_cgi',$checks{$name});
						my $result = StorProc->insert_obj('setup',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
			}
		} else {
			my %nagios_defaults = StorProc->cgi_defaults();
			foreach my $name (keys %nagios_defaults) {
				if ($gid) {
					my @values = ('',$gid,$name,'nagios_cgi',$nagios_defaults{$name});
					my $result = StorProc->insert_obj('monarch_group_props',\@values);
					if ($result =~ /^Error/) { push @errors, $result }
				} else {
					my @values = ($name,'nagios_cgi',$nagios_defaults{$name});
					my $result = StorProc->insert_obj('setup',\@values);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
			$step = 0;
		}
		unless (@errors) {
			if ($step eq '0') {
				$step = 1;
			} elsif ($step eq '1') {
				$step = 2; 
			} elsif ($step eq '2') {
				$step = 'saved'; 
			}
		}
	} elsif ($query->param('back')) {
		$step = $step - 1;
	} elsif ($query->param('sync')) {
		my %where = ('type' => 'nagios_cgi');
		my %main_object = StorProc->fetch_list_hash_array('setup',\%where);
		%where = ('group_id' => $gid, 'type' => 'nagios_cgi');
		my $result = StorProc->delete_one_where('monarch_group_props',\%where);
		if ($result =~ /^Error/) { push @errors, $result }
		foreach my $object (keys %main_object) {
			my @vals = ('',$gid,$main_object{$object}[0],'nagios_cgi',$main_object{$object}[2]);
			my $result = StorProc->insert_obj('monarch_group_props',\@vals);
			if ($result =~ /^Error/) { push @errors, $result }
		}
	} elsif ($query->param('set_defaults')) {

		my %nagios_defaults = StorProc->cgi_defaults();
		if ($gid) {
			my %where = ('group_id' => $gid, 'type' => 'nagios_cgi');
			my $result = StorProc->delete_one_where('monarch_group_props',\%where);
			if ($result =~ /^Error/) { push @errors, $result }
		} else {
			my $result = StorProc->delete_all('setup','type','nagios_cgi');
			if ($result =~ /^Error/) { push @errors, $result }
		}
		foreach my $name (keys %nagios_defaults) {
			if ($gid) {
				my @vals = ('',$gid,$name,'nagios_cgi',$nagios_defaults{$name});
				my $result = StorProc->insert_obj('monarch_group_props',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }			
			} else {
				my @values = ($name,'nagios_cgi',$nagios_defaults{$name});
				my $result = StorProc->insert_obj('setup',\@values);
				if ($result =~ /^Error/) { push @errors, $result }
			}
		}
		$step = 1;				
	} elsif ($query->param('upload')) {
		my $file = $query->param('file');
		if ($file =~ /cgi\.cfg/) {
			my %where = ('group_id' => $gid, 'type' => 'nagios_cgi');
			my $result = StorProc->delete_one_where('monarch_group_props',\%where);
			if ($result =~ /^Error/) { push @errors, $result }
			$result = StorProc->upload('/tmp',$file);
			if ($result =~ /^Error/) { push @errors, $result }
			my @errs = StorProc->import_nagios_cgi($gid); 
			if (@errs) { push (@errors, @errs) }
			$step = 1;
		} else {
			if ($file) { push @errors, "Invalid file type $file. File must be cgi.cfg." }		
			$step = 'upload';
		}
	} elsif ($query->param('load_nagios_cfg')) {
		@errors = StorProc->load_nagios_cgi($nagios_etc); 
		$step = 1;
	} elsif ($task eq 'view_edit') {
		$step = 1;
	}
	%next = ('name' => 'next', 'value' => 'Save and Next >>');

	if ($gid) {
		%objects = StorProc->get_group_cgi($gid);
	} else {
		my %where = ('type' => 'nagios_cgi');
		%objects = StorProc->fetch_list_hash_array('setup',\%where);
	}

	my $form_title = 'Nagios CGI Configuration';
	if ($gid) { $form_title = "\u$gname Nagios CGI Configuration" };
	my %docs = Doc->cgi_cfg();
	my %val_layout = ('-zero-' => 'User-defined coordinates','1' => 'Depth_layers','2' => 'Collapsed tree','3' => 'Balanced tree',
		'4' => 'Circular','5' => 'Circular (Mark Up)','6' => 'Circular (Balloon)');
	my $page = undef;
	unless ($step) { $step = 1 }
	if ($step eq '1') {
		$hidden{'step'} = 1;
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top("$form_title Page 1",'');
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		$page .= Forms->text_box('Physical HTML path:','physical_html_path',$objects{'physical_html_path'}[2],$textsize{'long_name'},'',$docs{'physical_html_path'});
		$page .= Forms->text_box('URL HTML path:','url_html_path',$objects{'url_html_path'}[2],$textsize{'long_name'},'',$docs{'url_html_path'});
		$page .= Forms->checkbox('Context sensitive help','show_context_help',$objects{'show_context_help'}[2],$docs{'show_context_help'});
		$page .= Forms->text_box('Nagios process check command:','nagios_check_command',$objects{'nagios_check_command'}[2],$textsize{'long_name'},'',$docs{'nagios_check_command'});
		$page .= Forms->checkbox('Use authentication:','use_authentication',$objects{'use_authentication'}[2],$docs{'use_authentication'});				
		$page .= Forms->text_box('Default user name:','default_user_name',$objects{'default_user_name'}[2],$textsize{'short_name'},'',$docs{'default_user_name'});
		$page .= Forms->text_area('System/Process Information Access:','authorized_for_system_information',$objects{'authorized_for_system_information'}[2],'3','80','',$docs{'authorized_for_system_information'});
		$page .= Forms->text_area('System/Process Command Access:','authorized_for_system_commands',$objects{'authorized_for_system_commands'}[2],'3','80','',$docs{'authorized_for_system_commands'});
		$page .= Forms->text_area('Configuration information access:','authorized_for_configuration_information',$objects{'authorized_for_configuration_information'}[2],'3','80','',$docs{'authorized_for_configuration_information'});
		$page .= Forms->text_area('Global Host Information Access:','authorized_for_all_hosts',$objects{'authorized_for_all_hosts'}[2],'3','80','',$docs{'authorized_for_all_hosts'});
		$page .= Forms->hidden(\%hidden);
		if ($gid) {
			$page .= Forms->form_bottom_buttons(\%default,\%sync,\%upload,\%next,$tab++);					
		} else {
			%upload = ('name' => 'load_nagios_cfg','value' => 'Load From File');
			$page .= Forms->form_bottom_buttons(\%default,\%upload,\%next,$tab++);					
		}
	} elsif ($step eq '2') {
		$hidden{'step'} = 2;
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top("$form_title Page 2",'');
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		$page .= Forms->text_area('Global Host Command Access:','authorized_for_all_host_commands',$objects{'authorized_for_all_host_commands'}[2],'3','80','',$docs{'authorized_for_all_host_commands'});
		$page .= Forms->text_area('Global Service Information Access:','authorized_for_all_services',$objects{'authorized_for_all_services'}[2],'3','80','',$docs{'authorized_for_all_services'});
		$page .= Forms->text_area('Global Service Command Access:','authorized_for_all_service_commands',$objects{'authorized_for_all_service_commands'}[2],'3','80','',$docs{'authorized_for_all_service_commands'});
		$page .= Forms->text_box('Statusmap background image:','statusmap_background_image',$objects{'statusmap_background_image'}[2],$textsize{'long_name'},'',$docs{'statusmap_background_image'});
		my @options = ('User-defined coordinates','Depth_layers','Collapsed tree','Balanced tree','Circular','Circular (Mark Up)','Circular (Balloon)');
		$objects{'default_statusmap_layout'}[2] = $val_layout{$objects{'default_statusmap_layout'}[2]};
		$page .= Forms->list_box('Default statusmap layout:','default_statusmap_layout',\@options,$objects{'default_statusmap_layout'}[2],'',$docs{'default_statusmap_layout'});
		my @options = ('Collapsed tree','Balanced tree','Circular');
		$objects{'default_statuswrl_layout'}[2] = $val_layout{$objects{'default_statuswrl_layout'}[2]};
		$page .= Forms->list_box('Default statuswrl layout:','default_statuswrl_layout',\@options,$objects{'default_statuswrl_layout'}[2],'',$docs{'default_statuswrl_layout'});
		$page .= Forms->text_box('Status wrl include:','statuswrl_include',$objects{'statuswrl_include'}[2],$textsize{'long_name'},'',$docs{'statuswrl_include'});
		$page .= Forms->text_box('Ping syntax:','ping_syntax',$objects{'ping_syntax'}[2],$textsize{'long_name'},'',$docs{'ping_syntax'});
		$page .= Forms->text_box('Refresh rate:','refresh_rate',$objects{'refresh_rate'}[2],'7','',$docs{'refresh_rate'});
		$page .= Forms->text_box('Host unreachable sound:','host_unreachable_sound',$objects{'host_unreachable_sound'}[2],$textsize{'long_name'},'',$docs{'sound_options'});
		$page .= Forms->text_box('Host down sound:','host_down_sound',$objects{'host_down_sound'}[2],$textsize{'long_name'},'','');
		$page .= Forms->text_box('Service critical sound:','service_critical_sound',$objects{'service_critical_sound'}[2],$textsize{'long_name'},'','');
		$page .= Forms->text_box('Service warning sound:','service_warning_sound',$objects{'service_warning_sound'}[2],$textsize{'long_name'},'','');
		$page .= Forms->text_box('Service unknown sound:','service_unknown_sound',$objects{'service_unknown_sound'}[2],$textsize{'long_name'},'','');
		$page .= Forms->hidden(\%hidden);
		%save = ('name' => 'next', 'value' => 'Save and Done');
		$page .= Forms->form_bottom_buttons(\%back,\%save,$tab++);	

	} elsif ($step eq 'upload') {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top_file("$form_title Upload",'');
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		my @message = ("Select the cgi.cfg file you wish to import.");
		$page .= Forms->form_message('Upload file:',\@message,'row1');	
		$page .= Forms->form_file();
		$page .= Forms->hidden(\%hidden);
		$page .= Forms->form_bottom_buttons(\%upload,\%cancel,$tab++);
	} elsif ($step eq 'saved') {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top("$form_title",'');
		my @message = ("Changes to nagios configuration completed");
		$page .= Forms->form_message('Saved:',\@message,'row1');	
		delete $hidden{'task'};
		$page .= Forms->hidden(\%hidden);
		$page .= Forms->form_bottom_buttons(\%continue,$tab++);
	}
	return $page;
}


#
############################################################################
# Nagios main cfg
#

sub nagios_cfg($$) {
	my $gid = shift;
	my $gname = shift;
	my %checks = ();
	my %objects = ();
	my %misc_vals = ();
	my $step = $query->param('step');
	if ($step eq '1') {
		%checks = ('aggregate_status_updates' => '0',
			'enable_notifications' => '0',
			'execute_service_checks' => '0',
			'accept_passive_service_checks' => '0',
			'execute_host_checks' => '0',
			'accept_passive_host_checks' => '0',
			'enable_event_handlers' => '0',
			'check_external_commands' => '0',
			'retain_state_information' => '0',
			'use_retained_program_state' => '0',
			'use_retained_scheduling_info' => '0');
	} elsif ($step eq '2') {
		%checks = ('use_syslog' => '0',
			'log_notifications' => '0',
			'log_host_retries' => '0',
			'log_service_retries' => '0',
			'log_event_handlers' => '0',
			'log_initial_states' => '0',
			'log_external_commands' => '0',
			'log_passive_service_checks' => '0',
			'log_passive_checks' => '0',
			'auto_reschedule_checks' => '0');				
	} elsif ($step eq '3') {
		%checks = ('use_agressive_host_checking' => '0',
			'enable_flap_detection' => '0',
			'obsess_over_services' => '0',
			'obsess_over_hosts' => '0',
			'process_performance_data' => '0');
	} elsif ($step eq '4') {
		%checks = ('check_for_orphaned_services' => '0',
			'check_service_freshness' => '0',
			'check_host_freshness' => '0',
			'use_regexp_matching' => '0',
			'use_true_regexp_matching' => '0');
	}
	if ($query->param('next')) {
		my %nagios_set = ();
		if ($gid) {
			my %where = ('group_id' => $gid,'name' => 'log_file');
			%nagios_set = StorProc->fetch_one_where('monarch_group_props',\%where);		
		} else {
			%nagios_set = StorProc->fetch_one('setup','name','log_file');
		}
		if ($nagios_set{'name'}) {
			my %nag_defined = ();
			if ($gid) {
				# GWMON-4818 monarch_group_props contains duplicate entries for nagios_cgi and nagios_cfg per group
				# Need to loop through hash of table contents to eliminate duplicate entries
				my %unique_props = ();
				my %where = ('group_id' => $gid,'type' => 'nagios_cfg');
				my %group_prop_hash = StorProc->fetch_list_hash_array('monarch_group_props',\%where);
				# process the id's in decending order to keep the latest values saved
				my @keys = keys %group_prop_hash;
				foreach my $id (sort {$b <=>$a } @keys) {
					if ($unique_props{$group_prop_hash{$id}[2]}) {
						%where = ('prop_id' => $id);
						my $res = StorProc->delete_one_where('monarch_group_props',\%where);
					} else {
						$unique_props{$group_prop_hash{$id}[2]} = 1;
						$nag_defined{$group_prop_hash{$id}[2]} = 1;
					}
				}
			} else {	
				my %where = ('type' => 'nagios');
				%nag_defined = StorProc->fetch_list_hash_array('setup',\%where);
			}
			foreach my $name ($query->param) {
				unless ($name =~ /^next$|user_acct|^obj$|^nocache$|^step$|^top_menu$|^update_main$|^view$/) {
					if ($name =~ /radio_option/) {
						my $val = $query->param($name);
						$name =~ s/radio_option_//;
						if ($val eq 'other') {
							my $other = "other_$name";
							$val = $query->param($other);
						}
						if ($gid) {
							if ($nag_defined{$name}) {
								my %where = ('group_id' => $gid,'type' => 'nagios_cfg','name' => $name);
								my %values = ('value' => $val);
								my $result = StorProc->update_obj_where('monarch_group_props',\%values,\%where);
								if ($result =~ /^Error/) { push @errors, $result }
							} else {
								my @values = ('',$gid,$name,'nagios_cfg',$val);
								my $result = StorProc->insert_obj('monarch_group_props',\@values);
								if ($result =~ /^Error/) { push @errors, $result }
							}
						} else {
							if ($nag_defined{$name}) {
								my %values = ('value' => $val);
								my $result = StorProc->update_obj('setup','name',$name,\%values);
								if ($result =~ /^Error/) { push @errors, $result }
							} else {
								my @values = ($name,'nagios',$val);
								my $result = StorProc->insert_obj('setup',\@values);
								if ($result =~ /^Error/) { push @errors, $result }
							}
						}
					} else {
						if (defined $checks{$name}) {
							$checks{$name} = '1';
						} else {
							my $val = $query->param($name);
							if ($gid) {
								if ($name =~ /^\d+$/) {
									my %values = ('value' => $val);
									my %where = ('prop_id' => $name);
									my $result = StorProc->update_obj_where('monarch_group_props',\%values,\%where);
									if ($result =~ /^Error/) { push @errors, $result }
								} elsif ($nag_defined{$name}) {
									my %values = ('value' => $val);
									if ($val eq '0') { $values{'value'} = '-zero-' }
									my %where = ('group_id' => $gid,'type' => 'nagios_cfg','name' => $name);
									my $result = StorProc->update_obj_where('monarch_group_props',\%values,\%where);
									if ($result =~ /^Error/) { push @errors, $result }
								} else {
									if ($val eq '0') { $val = '-zero-' }
									my @values = ('',$gid,$name,'nagios_cfg',$val);
									my $result = StorProc->insert_obj('monarch_group_props',\@values);
									if ($result =~ /^Error/) { push @errors, $result }
								}
							} else {
								if ($name =~ /key\d+.\d+$/ || $nag_defined{$name}) {
									my %values = ('value' => $val);
									if ($val eq '0') { $values{'value'} = '-zero-' }
									my $result = StorProc->update_obj('setup','name',$name,\%values);
									if ($result =~ /^Error/) { push @errors, $result }
								} else {
									if ($val eq '0') { $val = '-zero-' }
									my @values = ($name,'nagios',$val);
									my $result = StorProc->insert_obj('setup',\@values);
									if ($result =~ /^Error/) { push @errors, $result }
								}
							}
						}
					}
				}
			}
			foreach my $name (keys %checks) {
				if ($gid) {
					if ($nag_defined{$name}) {
						my %where = ('group_id' => $gid,'type' => 'nagios_cfg','name' => $name);
						my %values = ('value' => $checks{$name});
						my $result = StorProc->update_obj_where('monarch_group_props',\%values,\%where);
						if ($result =~ /^Error/) { push @errors, $result }
					} else {
						my @values = ('',$gid,$name,'nagios_cfg',$checks{$name});
						my $result = StorProc->insert_obj('monarch_group_props',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				} else {
					if ($nag_defined{$name}) {
						my %values = ('value' => $checks{$name});
						my $result = StorProc->update_obj('setup','name',$name,\%values);
						if ($result =~ /^Error/) { push @errors, $result }
					} else {
						my @values = ($name,'nagios',$checks{$name});
						my $result = StorProc->insert_obj('setup',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
			}
		} else {
			my %nagios_defaults = StorProc->nagios_defaults($nagios_ver,$is_portal);
			foreach my $name (keys %nagios_defaults) {
				if ($gid) {
					my @values = ('',$gid,$name,'nagios_cfg',$nagios_defaults{$name});
					my $result = StorProc->insert_obj('monarch_group_props',\@values);
					if ($result =~ /^Error/) { push @errors, $result }
				} else {
					my @values = ($name,'nagios',$nagios_defaults{$name});
					my $result = StorProc->insert_obj('setup',\@values);
					if ($result =~ /^Error/) { push @errors, $result }
				}
			}
			$step = 0;
		}
		unless (@errors) {
			if ($step eq '0') {
				$step = 1;
			} elsif ($step eq '1') {
				$step = 2; 
			} elsif ($step eq '2') {
				$step = 3; 
			} elsif ($step eq '3') {
				$step = 4; 
			} elsif ($step eq '4') {
				$step = 'saved'; 
			}
		}
	} elsif ($query->param('rem_misc')) {
		my @rem_keys = $query->param('rem_key');
		foreach my $key (@rem_keys) {
			if ($gid) {
				my $result = StorProc->delete_all('monarch_group_props','prop_id',$key);
				if ($result =~ /^Error/) { push @errors, $result }
			} else {
				my $result = StorProc->delete_all('setup','name',$key);
				if ($result =~ /^Error/) { push @errors, $result }
			}
		}
	} elsif ($query->param('add_misc')) {
		my $misc_name = $query->param('misc_name');
		my $misc_value = $query->param('misc_value');
		if ($gid) {
			my @vals = ('',$gid,$misc_name,'nagios_cfg_misc',$misc_value);
			my $result = StorProc->insert_obj('monarch_group_props',\@vals);
			if ($result =~ /^Error/) { push @errors, $result }
		} else {
			$misc_name .= "key".rand(); 
			my @vals = ($misc_name,'nagios_cfg_misc',$misc_value);
			my $result = StorProc->insert_obj('setup',\@vals);
			if ($result =~ /^Error/) { push @errors, $result }
		}
	} elsif ($query->param('back')) {
		$step = $step - 1;
	} elsif ($query->param('sync')) {
		my %where = ('type' => 'nagios');
		my %main_object = StorProc->fetch_list_hash_array('setup',\%where);
		%where = ('group_id' => $gid, 'type' => 'nagios_cfg');
		my $result = StorProc->delete_one_where('monarch_group_props',\%where);
		if ($result =~ /^Error/) { push @errors, $result }
		foreach my $object (keys %main_object) {
			my @vals = ('',$gid,$main_object{$object}[0],'nagios_cfg',$main_object{$object}[2]);
			my $result = StorProc->insert_obj('monarch_group_props',\@vals);
			if ($result =~ /^Error/) { push @errors, $result }
		}
	} elsif ($query->param('set_defaults')) {
		my %nagios_defaults = StorProc->nagios_defaults($nagios_ver,$is_portal);
		if ($gid) {
			my %where = ('group_id' => $gid, 'type' => 'nagios_cfg');
			my $result = StorProc->delete_one_where('monarch_group_props',\%where);
			if ($result =~ /^Error/) { push @errors, $result }
		} else {
			my $result = StorProc->delete_all('setup','type','nagios');
			if ($result =~ /^Error/) { push @errors, $result }
		}
		foreach my $name (keys %nagios_defaults) {
			if ($gid) {
				my @vals = ('',$gid,$name,'nagios_cfg',$nagios_defaults{$name});
				my $result = StorProc->insert_obj('monarch_group_props',\@vals);
				if ($result =~ /^Error/) { push @errors, $result }			
			} else {
				my @values = ($name,'nagios',$nagios_defaults{$name});
				my $result = StorProc->insert_obj('setup',\@values);
				if ($result =~ /^Error/) { push @errors, $result }
			}
		}
		$step = 1;
	} elsif ($query->param('upload')) {
		my $file = $query->param('file');
		if ($file =~ /nagios\.cfg/) {
			my %where = ('group_id' => $gid, 'type' => 'nagios_cfg');
			my $result = StorProc->delete_one_where('monarch_group_props',\%where);
			if ($result =~ /^Error/) { push @errors, $result }
			$result = StorProc->upload('/tmp',$file);
			if ($result =~ /^Error/) { push @errors, $result }
			my @errs = StorProc->import_nagios_cfg($gid); 
			if (@errs) { push (@errors, @errs) }
			$step = 1;
		} else {
			if ($file) { push @errors, "Invalid file type $file. File must be nagios.cfg." }
			$step = 'upload';
		}
	} elsif ($query->param('load_nagios_cfg')) {
		@errors = StorProc->load_nagios_cfg($nagios_etc); 
		$step = 1;
	} elsif ($task eq 'view_edit') {
		$step = 1;
	}
	%next = ('name' => 'next', 'value' => 'Save and Next >>');

	if ($gid) {
		%objects = StorProc->get_group_cfg($gid);
	} else {
		my %where = ('type' => 'nagios');
		%objects = StorProc->fetch_list_hash_array('setup',\%where);
	}
	foreach my $obj (keys %objects) { $objects{$obj}[2] =~ s/-zero-/0/ }
	my %docs = Doc->nagios_cfg();
	my %where = ('type' => 'other');
	my @commands = StorProc->fetch_list_where('commands','name',\%where);
	my $page = undef;
	unless ($step) { $step = 1 }
	my $form_title = 'Nagios Main Configuration';
	if ($gid) { $form_title = "\u$gname Nagios Configuration" };
	if ($step eq '1') {
		$hidden{'step'} = 1;
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top("$form_title Page 1",'');
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		$page .= Forms->text_box('Log file:','log_file',$objects{'log_file'}[2],$textsize{'long_name'},'',$docs{'log_file'});
		if ($nagios_ver =~ /^[23]\.x$/) {
			$page .= Forms->text_box('Object cache file:','object_cache_file',$objects{'object_cache_file'}[2],$textsize{'long_name'},'',$docs{'object_cache_file'});
		}
		if ($nagios_ver eq '3.x') {
			$page .= Forms->text_box('Precached object file:','precached_object_file',$objects{'precached_object_file'}[2],$textsize{'long_name'},'',$docs{'precached_object_file'});
		}
		$page .= Forms->text_box('Resource file:','resource_file',$objects{'resource_file'}[2],$textsize{'long_name'},'',$docs{'resource_file'});
		$page .= Forms->text_box('Temp file:','temp_file',$objects{'temp_file'}[2],$textsize{'long_name'},'',$docs{'temp_file'});
		$page .= Forms->text_box('Status file:','status_file',$objects{'status_file'}[2],$textsize{'long_name'},'',$docs{'status_file'});
		$page .= Forms->checkbox('Aggregated status updates option:','aggregate_status_updates',$objects{'aggregate_status_updates'}[2],$docs{'aggregate_status_updates'});
		$page .= Forms->text_box('Aggregated status data update interval:','status_update_interval',$objects{'status_update_interval'}[2],'7','',$docs{'status_update_interval'});
		$page .= Forms->text_box('Nagios user:','nagios_user',$objects{'nagios_user'}[2],$textsize{'long_name'},'',$docs{'nagios_user'});
		$page .= Forms->text_box('Nagios group:','nagios_group',$objects{'nagios_group'}[2],$textsize{'long_name'},'',$docs{'nagios_group'});
		$page .= Forms->checkbox('Enable notifications:','enable_notifications',$objects{'enable_notifications'}[2],$docs{'enable_notifications'});
		$page .= Forms->checkbox('Execute service checks:','execute_service_checks',$objects{'execute_service_checks'}[2],$docs{'execute_service_checks'});
		$page .= Forms->checkbox('Accept passive service checks:','accept_passive_service_checks',$objects{'accept_passive_service_checks'}[2],$docs{'accept_passive_service_checks'});
		if ($nagios_ver =~ /^[23]\.x$/) {
			$page .= Forms->checkbox('Execute host checks','execute_host_checks',$objects{'execute_host_checks'}[2],$docs{'execute_host_checks'});
			$page .= Forms->checkbox('Accept passive host checks','accept_passive_host_checks',$objects{'accept_passive_host_checks'}[2],$docs{'accept_passive_host_checks'});
		}
		$page .= Forms->checkbox('Enable event handlers:','enable_event_handlers',$objects{'enable_event_handlers'}[2],$docs{'enable_event_handlers'});
		my @list = ('n','h','d','w','m');
		$page .= Forms->list_box('Log rotation method:','log_rotation_method',\@list,$objects{'log_rotation_method'}[2],'',$docs{'log_rotation_method'});
		$page .= Forms->text_box('Log archive path:','log_archive_path',$objects{'log_archive_path'}[2],$textsize{'long_name'},'',$docs{'log_archive_path'});
		$page .= Forms->checkbox('External command check option:','check_external_commands',$objects{'check_external_commands'}[2],$docs{'check_external_commands'});
		$page .= Forms->text_box('External command check interval:','command_check_interval',$objects{'command_check_interval'}[2],$textsize{'small'},'',$docs{'command_check_interval'});
		$page .= Forms->text_box('External command file:','command_file',$objects{'command_file'}[2],$textsize{'long_name'},'',$docs{'command_file'});
		$page .= Forms->text_box('Downtime file:','downtime_file',$objects{'downtime_file'}[2],$textsize{'long_name'},'',$docs{'downtime_file'});
		$page .= Forms->text_box('Comment file:','comment_file',$objects{'comment_file'}[2],$textsize{'long_name'},'',$docs{'comment_file'});
		$page .= Forms->text_box('Lock file:','lock_file',$objects{'lock_file'}[2],$textsize{'long_name'},'',$docs{'lock_file'});
		$page .= Forms->checkbox('State retention option:','retain_state_information',$objects{'retain_state_information'}[2],$docs{'retain_state_information'});
		$page .= Forms->text_box('State retention file:','state_retention_file',$objects{'state_retention_file'}[2],$textsize{'long_name'},'',$docs{'state_retention_file'});
		$page .= Forms->text_box('Retention update interval:','retention_update_interval',$objects{'retention_update_interval'}[2],$textsize{'small'},'',$docs{'retention_update_interval'});
		$page .= Forms->checkbox('Use retained program state:','use_retained_program_state',$objects{'use_retained_program_state'}[2],$docs{'use_retained_program_state'});
		if ($nagios_ver =~ /^[23]\.x$/) {
			$page .= Forms->checkbox('Use retained scheduling info:','use_retained_scheduling_info',$objects{'use_retained_scheduling_info'}[2],$docs{'use_retained_scheduling_info'});
		}
		$page .= Forms->hidden(\%hidden);
		if ($gid) {
			$page .= Forms->form_bottom_buttons(\%default,\%sync,\%upload,\%next,$tab++);					
		} else {
			%upload = ('name' => 'load_nagios_cfg','value' => 'Load From File');
			$page .= Forms->form_bottom_buttons(\%default,\%upload,\%next,$tab++);					
		}
	} elsif ($step eq '2') {
		$hidden{'step'} = 2;
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top("$form_title Page 2",'');
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		$page .= Forms->checkbox('Syslog logging option:','use_syslog',$objects{'use_syslog'}[2],$docs{'use_syslog'});
		$page .= Forms->checkbox('Notification logging option:','log_notifications',$objects{'log_notifications'}[2],$docs{'log_notifications'});
		$page .= Forms->checkbox('Host check retry logging option','log_host_retries',$objects{'log_host_retries'}[2],$docs{'log_host_retries'});
		$page .= Forms->checkbox('Service check retry logging option:','log_service_retries',$objects{'log_service_retries'}[2],$docs{'log_service_retries'});
		$page .= Forms->checkbox('Event handler logging option','log_event_handlers',$objects{'log_event_handlers'}[2],$docs{'log_event_handlers'});
		$page .= Forms->checkbox('Initial states logging option:','log_initial_states',$objects{'log_initial_states'}[2],$docs{'log_initial_states'});
		$page .= Forms->checkbox('External command logging option:','log_external_commands',$objects{'log_external_commands'}[2],$docs{'log_external_commands'});
		if ($nagios_ver eq '1.x') {
			$page .= Forms->checkbox('Log passive service checks:','log_passive_service_checks',$objects{'log_passive_service_checks'}[2],$docs{'log_passive_service_checks'});
		} else {
			$page .= Forms->checkbox('Passive check logging option:','log_passive_checks',$objects{'log_passive_checks'}[2],$docs{'log_passive_checks'});
		}
		$page .= Forms->list_box('Global host event handler:','global_host_event_handler',\@commands,$objects{'global_host_event_handler'}[2],'',$docs{'global_host_event_handler'});
		$page .= Forms->list_box('Global service event handler:','global_service_event_handler',\@commands,$objects{'global_service_event_handler'}[2],'',$docs{'global_service_event_handler'});
		$page .= Forms->text_box('Sleep time:','sleep_time',$objects{'sleep_time'}[2],$textsize{'small'},'',$docs{'sleep_time'});
		if ($nagios_ver eq '1.x') {
			$page .= Forms->radio_options('Inter check delay method:','inter_check_delay_method',$objects{'inter_check_delay_method'}[2],$docs{'inter_check_delay_method'});
		} else {
			$page .= Forms->radio_options('Service inter check delay method:','service_inter_check_delay_method',$objects{'service_inter_check_delay_method'}[2],$docs{'service_inter_check_delay_method'});
			$page .= Forms->text_box('Max service check spread:','max_service_check_spread',$objects{'max_service_check_spread'}[2],$textsize{'small'},'',$docs{'max_service_check_spread'});
		}
		$page .= Forms->radio_options('Service interleave factor:','service_interleave_factor',$objects{'service_interleave_factor'}[2],$docs{'service_interleave_factor'});
		$page .= Forms->text_box('Service reaper frequency:','service_reaper_frequency',$objects{'service_reaper_frequency'}[2],$textsize{'small'},'',$docs{'service_reaper_frequency'});
		if ($nagios_ver =~ /^[23]\.x$/) {
			$page .= Forms->radio_options('Host inter check delay method:','host_inter_check_delay_method',$objects{'host_inter_check_delay_method'}[2],$docs{'host_inter_check_delay_method'});
			$page .= Forms->text_box('Max host check spread:','max_host_check_spread',$objects{'max_host_check_spread'}[2],$textsize{'small'},'',$docs{'max_host_check_spread'});
		}
		$page .= Forms->text_box('Maximum Concurrent Service Checks:','max_concurrent_checks',$objects{'max_concurrent_checks'}[2],$textsize{'small'},'',$docs{'max_concurrent_checks'});
		if ($nagios_ver eq '3.x') {
			$page .= Forms->text_box('Check Result Path:','check_result_path',$objects{'check_result_path'}[2],$textsize{'long_size'},'',$docs{'check_result_path'});
		}
		$page .= Forms->text_box('Timing interval length:','interval_length',$objects{'interval_length'}[2],$textsize{'small'},'',$docs{'interval_length'});
		if ($nagios_ver =~ /^[23]\.x$/) {
			$page .= Forms->checkbox('Auto reschedule checks:','auto_reschedule_checks',$objects{'auto_reschedule_checks'}[2],$docs{'auto_reschedule_checks'});
			$page .= Forms->text_box('Auto rescheduling interval:','auto_rescheduling_interval',$objects{'auto_rescheduling_interval'}[2],$textsize{'small'},'',$docs{'auto_rescheduling_interval'});
			$page .= Forms->text_box('Auto rescheduling window:','auto_rescheduling_window',$objects{'auto_rescheduling_window'}[2],$textsize{'small'},'',$docs{'auto_rescheduling_window'});
		}
		$page .= Forms->hidden(\%hidden);
		$page .= Forms->form_bottom_buttons(\%back,\%next,$tab++);
	} elsif ($step eq '3') {
		$hidden{'step'} = 3;
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top("$form_title Page 3",'');
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		$page .= Forms->checkbox('Agressive Host Checking Option:','use_agressive_host_checking',$objects{'use_agressive_host_checking'}[2],$docs{'use_agressive_host_checking'});
		$page .= Forms->checkbox('Flap Detection Option:','enable_flap_detection',$objects{'enable_flap_detection'}[2],$docs{'enable_flap_detection'});
		$page .= Forms->text_box('Low service flap threshold:','low_service_flap_threshold',$objects{'low_service_flap_threshold'}[2],$textsize{'small'},'',$docs{'service_flap_detection_thresholds'});
		$page .= Forms->text_box('High service flap threshold:','high_service_flap_threshold',$objects{'high_service_flap_threshold'}[2],$textsize{'small'});
		$page .= Forms->text_box('Low host flap threshold:','low_host_flap_threshold',$objects{'low_host_flap_threshold'}[2],$textsize{'small'},'',$docs{'host_flap_detection_thresholds'});
		$page .= Forms->text_box('High host flap threshold:','high_host_flap_threshold',$objects{'high_host_flap_threshold'}[2],$textsize{'small'});
		$page .= Forms->text_box('Soft state dependencies:','soft_state_dependencies',$objects{'soft_state_dependencies'}[2],$textsize{'small'},'',$docs{'soft_state_dependencies'});
		$page .= Forms->text_box('Service check timeout:','service_check_timeout',$objects{'service_check_timeout'}[2],$textsize{'small'},'',$docs{'timeout_values'});
		$page .= Forms->text_box('Host check timeout:','host_check_timeout',$objects{'host_check_timeout'}[2],$textsize{'small'});
		$page .= Forms->text_box('Event handler timeout:','event_handler_timeout',$objects{'event_handler_timeout'}[2],$textsize{'small'});
		$page .= Forms->text_box('Notification timeout:','notification_timeout',$objects{'notification_timeout'}[2],$textsize{'small'});
		$page .= Forms->text_box('Ocsp timeout:','ocsp_timeout',$objects{'ocsp_timeout'}[2],$textsize{'small'});
		if ($nagios_ver =~ /^[23]\.x$/) {
			$page .= Forms->text_box('Ochp timeout:','ochp_timeout',$objects{'ochp_timeout'}[2],$textsize{'small'});
		}
		$page .= Forms->text_box('Perfdata timeout:','perfdata_timeout',$objects{'perfdata_timeout'}[2],$textsize{'small'});
		$page .= Forms->checkbox('Obsess over services:','obsess_over_services',$objects{'obsess_over_services'}[2],$docs{'obsess_over_services'});
		$page .= Forms->text_box('OCSP command:','ocsp_command',$objects{'ocsp_command'}[2],$textsize{'long_name'},'',$docs{'ocsp_command'});
		if ($nagios_ver =~ /^[23]\.x$/) {
			$page .= Forms->checkbox('Obsess over hosts:','obsess_over_hosts',$objects{'obsess_over_hosts'}[2],$docs{'obsess_over_hosts'});		
			$page .= Forms->text_box('OCHP command:','ochp_command',$objects{'ochp_command'}[2],$textsize{'long_name'},'',$docs{'ochp_command'});
		}
		$page .= Forms->checkbox('Process performance data:','process_performance_data',$objects{'process_performance_data'}[2],$docs{'process_performance_data'});
		$page .= Forms->list_box('Host perfdata command:','host_perfdata_command',\@commands,$objects{'host_perfdata_command'}[2],'',$docs{'host_perfdata_command'});
		$page .= Forms->list_box('Service perfdata command:','service_perfdata_command',\@commands,$objects{'service_perfdata_command'}[2],'',$docs{'service_perfdata_command'});
		if ($nagios_ver =~ /^[23]\.x$/) {
			$page .= Forms->text_box('Host performance data file:','host_perfdata_file',$objects{'host_perfdata_file'}[2],$textsize{'long_name'},'',$docs{'host_perfdata_file'});
			$page .= Forms->text_box('Service performance data file:','service_perfdata_file',$objects{'service_perfdata_file'}[2],$textsize{'long_name'},'',$docs{'service_perfdata_file'});
			$page .= Forms->text_box('Host performance data file template:','host_perfdata_file_template',$objects{'host_perfdata_file_template'}[2],$textsize{'long_name'},'',$docs{'host_perfdata_file_template'});
			$page .= Forms->text_box('Service performance data file template:','service_perfdata_file_template',$objects{'service_perfdata_file_template'}[2],$textsize{'long_name'},'',$docs{'service_perfdata_file_template'});
			my @opts = ('a','w');
			$page .= Forms->list_box('Host performance data file mode:','host_perfdata_file_mode',\@opts,$objects{'host_perfdata_file_mode'}[2],'',$docs{'host_perfdata_file_mode'});
			$page .= Forms->list_box('Service performance data file mode:','service_perfdata_file_mode',\@opts,$objects{'service_perfdata_file_mode'}[2],'',$docs{'service_perfdata_file_mode'});
			$page .= Forms->text_box('Host performance data file processing interval:','host_perfdata_file_processing_interval',$objects{'host_perfdata_file_processing_interval'}[2],$textsize{'small'},'',$docs{'host_perfdata_file_processing_interval'});
			$page .= Forms->text_box('Service performance data file processing interval:','service_perfdata_file_processing_interval',$objects{'service_perfdata_file_processing_interval'}[2],$textsize{'small'},'',$docs{'service_perfdata_file_processing_interval'});
			$page .= Forms->list_box('Host performance data file processing command:','host_perfdata_file_processing_command',\@commands,$objects{'host_perfdata_file_processing_command'}[2],'',$docs{'host_perfdata_file_processing_command'});
			$page .= Forms->list_box('Service performance data file processing command:','service_perfdata_file_processing_command',\@commands,$objects{'service_perfdata_file_processing_command'}[2],'',$docs{'service_perfdata_file_processing_command'});
		}
		$page .= Forms->hidden(\%hidden);
		$page .= Forms->form_bottom_buttons(\%back,\%next,$tab++);		
	} elsif ($step eq '4') {
		$hidden{'step'} = 4;
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top("$form_title Page 4",'');
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		$page .= Forms->checkbox('Check for orphaned services:','check_for_orphaned_services',$objects{'check_for_orphaned_services'}[2],$docs{'check_for_orphaned_services'});
		$page .= Forms->checkbox('Check service freshness:','check_service_freshness',$objects{'check_service_freshness'}[2],$docs{'check_service_freshness'});
		$page .= Forms->text_box('Service freshness check interval:','freshness_check_interval',$objects{'freshness_check_interval'}[2],$textsize{'small'},'',$docs{'freshness_check_interval'});
		if ($nagios_ver =~ /^[23]\.x$/) {
			$page .= Forms->checkbox('Check host freshness:','check_host_freshness',$objects{'check_host_freshness'}[2],$docs{'check_host_freshness'});
			$page .= Forms->text_box('Host freshness check interval:','host_freshness_check_interval',$objects{'host_freshness_check_interval'}[2],$textsize{'small'},'',$docs{'host_freshness_check_interval'});		
		}
		if ($is_portal) {
			$page .= Forms->text_box('Event broker options:','event_broker_options',$objects{'event_broker_options'}[2],$textsize{'small'},'',$docs{'event_broker_options'});
			$page .= Forms->text_box('Broker module:','broker_module',$objects{'broker_module'}[2],$textsize{'long_name'},'',$docs{'broker_module'});				
		}
		$page .= Forms->date_format($objects{'date_format'}[2],$docs{'date_format'});
		$page .= Forms->text_box('Illegal object name chars:','illegal_object_name_chars',$objects{'illegal_object_name_chars'}[2],$textsize{'long_name'},'',$docs{'illegal_object_name_chars'});
		$page .= Forms->text_box('Illegal macro output characters:','illegal_macro_output_chars',$objects{'illegal_macro_output_chars'}[2],$textsize{'long_name'},'',$docs{'illegal_macro_output_chars'});				
		$page .= Forms->text_box('Admin email:','admin_email',$objects{'admin_email'}[2],$textsize{'long_name'},'',$docs{'admin_email'});
		$page .= Forms->text_box('Admin pager:','admin_pager',$objects{'admin_pager'}[2],$textsize{'long_name'},'',$docs{'admin_pager'});
		%misc_vals = StorProc->get_main_cfg_misc($gid);
		$page .= Forms->main_cfg_misc(\%misc_vals,$docs{'misc_directives'});
		$page .= Forms->hidden(\%hidden);
		%save = ('name' => 'next', 'value' => 'Save and Done');
		$page .= Forms->form_bottom_buttons(\%back,\%save,$tab++);					
	} elsif ($step eq 'upload') {	
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top_file("Nagios configuration");
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		my @message = ("Select the nagios.cfg file you to import.");
		$page .= Forms->form_message('Upload file:',\@message,'row1');	
		$page .= Forms->form_file();
		$page .= Forms->hidden(\%hidden);
		$page .= Forms->form_bottom_buttons(\%upload,\%cancel,$tab++);
	} elsif ($step eq 'saved') {
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top("Nagios configuration",'');
		my @message = ("Changes to nagios configuration completed");
		$page .= Forms->form_message('Saved:',\@message,'row1');	
		delete $hidden{'task'};
		$page .= Forms->hidden(\%hidden);
		$page .= Forms->form_bottom_buttons(\%continue,$tab++);
	}
	return $page;
}

#
############################################################################
# Nagios resource macros
#

sub resource_cfg($$) {
	my $gid = shift;
	my $gname = shift;
	my $task = $query->param('submit');
	my $saved = 0;
	my $resource = undef;
	my $resource_sav = undef;
	my $file = $query->param('file');
	my $upload = $query->param('upload');
	if ($query->param('update_resource')) {
		$resource_sav = $query->param('resource');
		my $resource_value = $query->param('resource_value');
		my $comment = $query->param('comment');
		my %values = ('value' => $resource_value);
		if ($gid) {
			my %where = ('group_id' => $gid,'name' => $resource_sav);
			my $result = StorProc->update_obj_where('monarch_group_props',\%values,\%where);
			if ($result =~ /error/i) { push @errors, $result }
		} else {
			my $result = StorProc->update_obj('setup','name',$resource_sav,\%values);
			if ($result =~ /error/i) { push @errors, $result }
		}
		my $label = $resource_sav;
		$label =~ s/user//;
		my %values = ('value' => $comment);

		if ($gid) {
			my %where = ('group_id' => $gid,'name' => "resource_label$label");
			my $result = StorProc->update_obj_where('monarch_group_props',\%values,\%where);
			if ($result =~ /error/i) { push @errors, $result }
		} else {
			my $result = StorProc->update_obj('setup','name',"resource_label$label",\%values);
			if ($result =~ /error/i) { push @errors, $result }
		}
		unless (@errors) { 
			$resource_sav = undef;
			$resource = undef;
		}
	} elsif ($query->param('sync')) {
		my %where = ('type' => 'resource');
		my %main_object = StorProc->fetch_list_hash_array('setup',\%where);
		%where = ('group_id' => $gid, 'type' => 'resource');
		my $result = StorProc->delete_one_where('monarch_group_props',\%where);
		if ($result =~ /^Error/) { push @errors, $result }
		foreach my $object (keys %main_object) {
			my @vals = ('',$gid,$main_object{$object}[0],'resource',$main_object{$object}[2]);
			my $result = StorProc->insert_obj('monarch_group_props',\@vals);
			if ($result =~ /^Error/) { push @errors, $result }
		}
	} elsif ($upload && $file) {
		my %where = ('group_id' => $gid, 'type' => 'resource');
		my $result = StorProc->delete_one_where('monarch_group_props',\%where);
		if ($result =~ /^Error/) { push @errors, $result }
		$result = StorProc->upload('/tmp',$file);
		if ($result =~ /^Error/) { push @errors, $result }
		my @errs = StorProc->import_resource_cfg($gid); 
		if (@errs) { push (@errors, @errs) }
		unless (@errors) { $upload = undef }
	}
	my $page = Forms->header($page_title,$session_id,$top_menu);
	if ($upload) {
		$page .= Forms->form_top_file("Nagios Resource Macros \u$gname");
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		my @message = ("Select the resource.cfg file you wish to import.");
		$page .= Forms->form_message('Upload file:',\@message,'row1');	
		$page .= Forms->form_file();
		$page .= Forms->hidden(\%hidden);
		$page .= Forms->form_bottom_buttons(\%upload,\%cancel,$tab++);
	} else {
		$page .= Forms->form_top("Nagios Resource Macros \u$gname");
		my $resource_value = undef;
		if (@errors) { $page .= Forms->form_errors(\@errors) }
		my %resources = StorProc->get_resource_values($gid);
		my %selected = ();
		if ($resource_sav) {
			$resource = $resource_sav;
		} else {
			foreach my $name ($query->param) {
				if ($name =~ /^resource_(user\d+)/) { $resource = $1 }
			}
		}
		if ($resource) {
			$resource_value = $resources{$resource};
			%selected = ('name' => $resource,'value' => $resource_value);
		} else {
			$page .= Forms->form_doc('Select resource');
		}
		$page .= Forms->resource_select(\%resources,\%selected,$top_menu);
		$page .= Forms->hidden(\%hidden);
		if ($gid) {
			my %sync = ('name' => 'sync','value' => 'Sync With Main');
			$page .= Forms->form_bottom_buttons(\%close,\%upload,\%sync,$tab++);
		} else {
			$page .= Forms->form_bottom_buttons(\%close,$tab++);
		}
	}
	return $page;
}


#
############################################################################
# Pre Flight Test
#

sub pre_flight($) {
	my $group = shift;
	my @results = ();
	my $page = undef;
	if ($query->param('refreshed')) {
		my $group = $query->param('group');
		use MonarchFile;
		my ($files, $errors) = Files->build_files($user_acct,$group,'preflight','',$nagios_ver,$nagios_etc,"$monarch_home/workspace",'');
		my @errors = @{$errors};
		my @files = @{$files};
		unless ($errors[0]) { 
			@results = StorProc->pre_flight_check($nagios_bin,$monarch_home);
		}
		$page .= Forms->header($page_title,$session_id,$top_menu);
		$page .= Forms->form_top('Nagios Pre Flight Test','');
		if (@errors) { $page .= Forms->form_message("Error(s) building file(s):",\@errors ,'error') }
		$page .= Forms->form_message("Results:",\@results ,'row1');
		$hidden{'obj'} = undef;
		$page .= Forms->hidden(\%hidden);
		$page .= Forms->form_bottom_buttons(\%continue,$tab++);
	} else {
		my $now = time;
		$refresh_url = "?update_main=1&nocache=$now&refreshed=1&group=$group";
		foreach my $name (keys %hidden) {
			$refresh_url .= qq(&$name=$hidden{$name});
		}
		$page .= Forms->header($page_title,$session_id,$top_menu,$refresh_url);
		$page .= Forms->form_top('Nagios Pre Flight Test','');
		$page .= Forms->form_doc('Running pre-flight check...');
		$page .= Forms->form_bottom_buttons();		
	}
	return $page;
}

#
############################################################################
# Control Center
#

sub control() {
	my @menus = ();
	my %ver = StorProc->fetch_one('setup','name','nagios_version');
	my $page = undef;
	if ($query->param('close') || $query->param('continue') || $query->param('cancel')) {
		$page .= Forms->header($page_title,$session_id,$top_menu);
	} else {
#
############################################################################
# Users
#
		if ($obj eq 'users') {
			@errors = ();
			$table = 'users';
			my $user = $query->param('mod_user');
			my $user_name = $query->param('user_name');
			my @password = $query->param('passwd');
			if ($query->param('task') eq 'No') { $task = 'modify' }
			if ($query->param('add') && $user) {
				my $id = undef;
				$user =~ s/^\s+|\s+$//;
				my %p = StorProc->fetch_one('users','user_acct',$user);
				if (!$password[1]) { $password[1] = 1 }
				unless ($authentication{'disabled'}) {
					if ($password[0] eq $password[1]) { $password[1] = undef }
				} else {
					$password[1] = undef;
				}
				unless ($p{'user_acct'} || $user eq '' || $password[1]) {
					my $now = time;
					$now = $now - 100000;
					my @saltchars = ('a'..'z','A'..'Z','0'..'9',',','/');
					srand(time() ^ ($$ + ($$ << 15)));
					my $salt = $saltchars[int(rand(64))];
					$salt .= $saltchars[int(rand(64))];
					my $newpw = crypt($password[0], $salt);
					my @values = ('',$user,$user_name,$newpw,$now);
					$id = StorProc->insert_obj_id($table,\@values,'user_id');
					if ($id =~ /^Error/) { push @errors, $id }
				} else {
					if ($p{'user_acct'}) { push @errors, "User id $user already exists." }
					if ($user eq '') { push @errors, "Required: User id" }
					if ($password[1]) { push @errors, "Check password fields. They are either blank or a mismatch." }
				}
				unless (@errors) { 
					my @user_groups = $query->param('user_groups');
					my @ugs = StorProc->get_ids('usergroup_id','user_groups',\@user_groups);
					foreach (@ugs) {
						my @values = ($_,$id);
						my $result = StorProc->insert_obj('user_group',\@values);
						if ($result =~ /^Error/) { push @errors, $result }				
					}
				}
				unless (@errors) { 
					$page .= Forms->header($page_title,$session_id,$top_menu);
					$page .= Forms->form_top("User Account",'');
					my @message = ("User $user added.");
					$page .= Forms->form_message('Added:',\@message,'row1');	
					($task,$user) = undef;
					delete $hidden{'task'};
					$page .= Forms->hidden(\%hidden);
					$page .= Forms->form_bottom_buttons(\%continue,$tab++);
				}
			} elsif ($query->param('save')) {
				my %values = ();
				if (!$password[1]) { $password[1] = 1 }
				if ($query->param('set_password')) {
					if ($password[0] eq $password[1]) { $password[1] = undef }
				} else {
					$password[1] = undef;
				}
				unless ($password[1]) {
					$values{'user_name'} = $user_name;
					my @saltchars = ('a'..'z','A'..'Z','0'..'9',',','/');
					srand(time() ^ ($$ + ($$ << 15)));
					my $salt = $saltchars[int(rand(64))];
					$salt .= $saltchars[int(rand(64))];
					$values{'password'} = crypt($password[0], $salt);
					my $result = StorProc->update_obj('users','user_acct',$user,\%values);
					if ($result =~ /^Error/) { push @errors, $result }
					unless ($user eq 'super_user') {
						my %u = StorProc->fetch_one('users','user_acct',$user);
						$result = StorProc->delete_all('user_group','user_id',$u{'user_id'});
						if ($result =~ /^Error/) { push @errors, $result }
						my @user_groups = $query->param('user_groups');
						my @ugs = StorProc->get_ids('usergroup_id','user_groups',\@user_groups);
						foreach (@ugs) {
							my @values = ($_,$u{'user_id'});
							my $result = StorProc->insert_obj('user_group',\@values);
							if ($result =~ /^Error/) { push @errors, $result }				
						}
					}
				} else {
					push @errors, "Check password fields. It's either blank or a mismatch";
				}
				unless (@errors) { 
					$page .= Forms->header($page_title,$session_id,$top_menu);
					my $message = "Changes accepted.";					
					$page .= Forms->form_top("User Account",'');
					my @message = ("Changes to $user accepted.");
					$page .= Forms->form_message('Saved:',\@message,'row1');	
					($task,$user) = undef;
					delete $hidden{'task'};
					$page .= Forms->hidden(\%hidden);
					$page .= Forms->form_bottom_buttons(\%continue,$tab++);
				}
			} elsif ($query->param('confirm_delete')) {
				my $result = StorProc->delete_all('users','user_acct',$user);
				if ($result =~ /^Error/) { push @errors, $result }
				unless (@errors) { 
					$page .= Forms->header($page_title,$session_id,$top_menu,'','1');
					my $message = "User $user deleted.";					
					$page .= Forms->form_top("User Account",'');
					my @message = ("Changes to $user accepted.");
					$page .= Forms->form_message('Removed:',\@message,'row1');	
					($task,$user) = undef;
					delete $hidden{'task'};
					$page .= Forms->hidden(\%hidden);
					$page .= Forms->form_bottom_buttons(\%continue,$tab++);
				}
			} elsif ($query->param('delete')) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$hidden{'mod_user'} = $user;
				my $message = qq(Are you sure you want to remove $user?);
				$page .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden);
				$user = undef;
				$task = 'Delete';
			}
			if (@errors || $user || $task =~ /Add|new/i) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				my @members = $query->param('user_groups');
				$page .= Forms->form_top('User Account','onsubmit="selIt();"');
				if (@errors) { $page .= Forms->form_errors(\@errors) }
				if ($task =~ /Add|new/) {
					$page .= Forms->text_box('Userid:','mod_user',$user,$textsize{'short_name'},$required{'user_acct'});
					$page .= Forms->text_box('User name:','user_name',$user_name,$textsize{'long_name'});
					$hidden{'set_password'} = 1;
				} else {
					my %p = StorProc->fetch_one('users','user_acct',$user);
					if (!$members[0]) {
						@members = StorProc->get_names_in('usergroup_id','user_groups','user_group','user_id',$p{'user_id'}); 
					}
					$page .= Forms->display_hidden('User id:','mod_user',$user);
					$page .= Forms->text_box('User name:','user_name',$p{'user_name'},$textsize{'long_name'});
					$page .= Forms->checkbox('Set password:','set_password',$query->param('set_password'));
				}
				$page .= Forms->password_box('Password:','passwd',$textsize{'short_name'},$required{'password'});
				$page .= Forms->password_box('Password confirm:','passwd',$textsize{'short_name'},$required{'password'});
				%save = ('name' => 'save','value' => 'Save');
				unless ($user eq 'super_user') {
					my @nonmembers = StorProc->fetch_list('user_groups','name'); 
					$page .= Forms->members('User groups:','user_groups',\@members,\@nonmembers);
					$page .= Forms->hidden(\%hidden);
					if ($task =~ /Add|new/) {
						$page .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);
					} else {
						$page .= Forms->form_bottom_buttons(\%save,\%delete,\%cancel,$tab++);
					}
				} else {
					$page .= Forms->hidden(\%hidden);
					$page .= Forms->form_bottom_buttons(\%save,\%cancel,$tab++);
				}
			}

#
############################################################################
# User Groups
#
		} elsif ($obj eq 'user_groups') {
			@errors = ();
			$table = 'user_groups';
			my $groupid = $query->param('groupid');
			my $description = $query->param('description');
			if ($query->param('task') eq 'No') { $task = 'access_list' }
			my $access_set = $query->param('access_set');
			if ($access_set)  { $task = 'access_list' }
			my $access_type = $query->param('access_type');
			my $update_assets = undef;
			my $saved = 0;
			my @message = ();
			if ($query->param('continue') || $query->param('close') ||  $query->param('cancel')) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
			} elsif ($query->param('add') && $groupid) {
				$groupid =~ s/^\s+|\s+$//;
				my %p = StorProc->fetch_one('user_groups','name',$groupid);
				unless ($p{'name'}) {
					my @values = ('',$groupid,$description);
					my $result = StorProc->insert_obj($table,\@values);
					if ($result =~ /^Error/) { push @errors, $result }
				} else {
					push @errors, "Check name field. It's either blank or a record exists";
				}
				unless(@errors) {
					$task = 'access_list';
				}
			} elsif ($query->param('save')) {
				my %values = ();
				$values{'description'} = $description;
				my $result = StorProc->update_obj($table,'name',$groupid,\%values);
				if ($result =~ /^Error/) { push @errors, $result}
				$task = 'saved';
			} elsif ($query->param('update_access')) {
				my %g = StorProc->fetch_one('user_groups','name',$groupid);
				my $type = undef;
				my @assets = $query->param('access_list');
				if ($access_set eq 'tools' || $access_set eq 'control') {
					my %where = ('usergroup_id' => $g{'usergroup_id'},'type' => $access_set);
					my $result = StorProc->delete_one_where('access_list',\%where); 
					if ($result =~ /^Error/) { push @errors, $result }
					foreach my $asset (@assets) {
						my @values = ($asset,$access_set,$g{'usergroup_id'},'full_control');
						my $result = StorProc->insert_obj('access_list',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				} elsif ($access_set eq 'EZ') {
					my %where = ('usergroup_id' => $g{'usergroup_id'},'type' => 'ez');
					my $result = StorProc->delete_one_where('access_list',\%where); 
					if ($result =~ /^Error/) { push @errors, $result }
					my $enable_ez = $query->param('enable_ez');
					if ($enable_ez) {
						my @values = ($enable_ez,'ez',$g{'usergroup_id'},$enable_ez);
						my $result = StorProc->insert_obj('access_list',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
					my $ez_view = $query->param('ez_view');
					if ($ez_view) {
						my @values = ($ez_view,'ez',$g{'usergroup_id'},$ez_view);
						my $result = StorProc->insert_obj('access_list',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
					if ($result =~ /^Error/) { push @errors, $result }
					foreach my $asset (@assets) {
						my @values = ("ez_$asset",'ez',$g{'usergroup_id'},"ez_$asset");
						my $result = StorProc->insert_obj('access_list',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				} elsif ($access_set eq 'groups') {
					my %group_name = StorProc->get_table_objects('monarch_groups');
					my %where = ('usergroup_id' => $g{'usergroup_id'},'type' => 'group_macro');
					my $result = StorProc->delete_one_where('access_list',\%where); 
					if ($result =~ /^Error/) { push @errors, $result }
					foreach my $asset (@assets) {
						if ($asset eq 'manage') {
							my @values = ($asset,'group_macro',$g{'usergroup_id'},'manage');
							my $result = StorProc->insert_obj('access_list',\@values);
							if ($result =~ /^Error/) { push @errors, $result }
						} else {
							my @values = ($group_name{$asset},'group_macro',$g{'usergroup_id'},$asset);
							my $result = StorProc->insert_obj('access_list',\@values);
							if ($result =~ /^Error/) { push @errors, $result }
						}
					}
				} else {
					my %assets = ();
					my %vals = ();
					my %where = ('usergroup_id' => $g{'usergroup_id'},'type' => $access_set);
					my $result = StorProc->delete_one_where('access_list',\%where); 
					if ($result =~ /^Error/) { push @errors, $result }
					foreach my $asset ($query->param) {
						if ($asset eq 'nocache') { next }
						if ($asset =~ /(^\S+)-(\S+)-(.*)/) {
							my $obj = $3;
							$assets{$obj} = $1;
							$vals{$obj} .= "$2,";
						}
					}
					foreach my $asset (keys %assets) {
						$vals{$asset} =~ s/,$//;
						my @values = ($asset,$assets{$asset},$g{'usergroup_id'},$vals{$asset});
						my $result = StorProc->insert_obj('access_list',\@values);
						if ($result =~ /^Error/) { push @errors, $result }
					}
				}
				unless (@errors) { 
					@message = ("Changes to access set $access_set accepted");	
					$saved = 1;
				}
				$task = 'access_list';			} elsif ($groupid ne 'super_users' && $query->param('confirm_delete')) {
				my $result = StorProc->delete_all('user_groups','name',$groupid);
				if ($result =~ /^Error/) { push @errors, $result }
				unless (@errors) {
					$page .= Forms->header($page_title,$session_id,$top_menu,'','1');
					$page .= Forms->form_top("User Group",'');
					my @message = ("User group $groupid deleted.");
					$page .= Forms->form_message('Removed:',\@message,'row1');	
					($task,$groupid) = undef;
					delete $hidden{'task'};
					$page .= Forms->hidden(\%hidden);
					$page .= Forms->form_bottom_buttons(\%continue,$tab++);
					$task = 'delete';
				} else {
					$task = 'access_list';
				}
			} elsif ($groupid ne 'super_users' && $query->param('delete')) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$hidden{'groupid'} = $groupid;
				$hidden{'task'} = 'access_list';
				my $message = qq(Are you sure you want to remove $groupid?);
				$page .= Forms->are_you_sure('Confirm Delete:',$message,'confirm_delete',\%hidden);
				$groupid = undef;
				$task = 'delete';
			}
			if ($task eq 'new') {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('User Group','');
				if (@errors) { $page .= Forms->form_errors(\@errors) }
				$page .= Forms->text_box('Group id:','groupid','',$textsize{'short_name'},$required{'groupid'});
				$page .= Forms->text_box('Description:','description',$description,$textsize{'long_name'});
				delete $hidden{'task'};
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%add,\%cancel,$tab++);
			} elsif ($task eq 'access_list' || $query->param('access_list')) {
				unless ($groupid eq 'super_users') {
					$page .= Forms->header($page_title,$session_id,$top_menu);
					my %access_button = ();
					if (@errors) { $page .= Forms->form_errors(\@errors) }
					my %p = StorProc->fetch_one('user_groups','name',$groupid);
					$description = $p{'description'};
					if (!$access_set) { $access_set = 'design_manage' }
					$hidden{'groupid'} = $groupid;
					$hidden{'access_set'} = $access_set;
					my @menus = ('design_manage','groups','tools','control');
					if ($enable_ez) { push @menus, 'EZ'}
					$page .= Forms->access_top($groupid,$session_id,$access_set,\@menus);
					my %g = StorProc->fetch_one('user_groups','name',$groupid);
					if ($saved) {
						$page .= Forms->hidden(\%hidden);
						$page .= Forms->form_message("Saved:",\@message,'row1');
					} elsif ($access_set eq 'tools') {
						my @tool_menus = ('export','host_delete_tool','service_delete_tool');				
						$access_type = 'tools';
						my %values = ('usergroup_id' => $g{'usergroup_id'}, 'type' => 'tools');
						my @selected = ();
						my %selected_hash = StorProc->fetch_list_hash_array('access_list',\%values);
						foreach my $key (keys %selected_hash) { push @selected, $key }
						$page .= Forms->hidden(\%hidden);
						$page .= Forms->access_checkbox_list('Tools:','access_list', \@tool_menus,\@selected);
					} elsif ($access_set eq 'control') {
						my @control_menus = ('users','user_groups','setup','nagios_cgi_configuration','nagios_main_configuration','nagios_resource_macros',
						'load','pre_flight_test','commit');
						$access_type = 'control';
						my %assets_selected = undef;
						my %values = ('usergroup_id' => $g{'usergroup_id'}, 'type' => 'control');
						my @selected = ();
						my %selected_hash = StorProc->fetch_list_hash_array('access_list',\%values);
						foreach my $key (keys %selected_hash) { push @selected, $key }
						$page .= Forms->hidden(\%hidden);
						$page .= Forms->access_checkbox_list('Control list:','access_list', \@control_menus,\@selected);
					} elsif ($access_set eq 'groups') {
						my %docs = Doc->access_list();
						my @selected = ();
						my %where = ('usergroup_id' => $g{'usergroup_id'}, 'type' => 'group_macro');
						my %selected_hash = StorProc->fetch_list_hash_array('access_list',\%where);
						my @monarch_group_macro = ('manage');
						if ($selected_hash{'manage'}) { @selected = ('manage') }
						$page .= Forms->wizard_doc('Groups',$docs{'groups'});
						$page .= Forms->checkbox_list('Groups and macros:','access_list',\@monarch_group_macro,\@selected);
						my %group_name = StorProc->get_table_objects('monarch_groups','1');
						my @groups = StorProc->fetch_list('monarch_groups','name');
						foreach my $key (keys %selected_hash) { push @selected, $group_name{$key} }
						$page .= Forms->hidden(\%hidden);
						$page .= Forms->access_checkbox_list('Administered groups:','access_list', \@groups,\@selected);
					} elsif ($access_set eq 'EZ') {
						my %docs = Doc->access_list();
						my @selected = ();
						my %where = ('usergroup_id' => $g{'usergroup_id'}, 'type' => 'ez');
						my %selected_hash = StorProc->fetch_list_hash_array('access_list',\%where);
						foreach my $key (keys %selected_hash) { 
							$key =~ s/ez_//;
							push @selected, $key;
						}
						my @ez_set = ('enable','primary_interface','only_interface');
						if ($selected_hash{'manage'}) { @selected = ('manage') }
						$page .= Forms->wizard_doc('EZ Interface',$docs{'ez'});
						$page .= Forms->access_settings_ez(\%selected_hash);
						my @ez_options = ('hosts','import','discover','host_groups','profiles','notifications','commit','setup');
						$page .= Forms->hidden(\%hidden);
						$page .= Forms->access_checkbox_list('EZ options:','access_list', \@ez_options,\@selected);
					} else {
						my @access_list = ('time_periods','commands','contact_templates','contacts','contactgroups','escalations','profiles');
						push (@access_list, ('hosts','host_templates','extended_host_info_templates','hostgroups','parent_child','host_dependencies'));
						push @access_list, ('services','service_templates','service_dependency_templates','extended_service_info_templates');
						if ($nagios_ver =~ /^[23]\.x$/) { push @access_list, 'service_groups' }
						if ($enable_externals) { push @access_list, 'externals' }
						$access_type = 'design_manage';
						my %assets_selected = undef;
						my %values = ('usergroup_id' => $g{'usergroup_id'}, 'type' => $access_type);
						my %access_list_values = StorProc->fetch_list_hash_array('access_list',\%values);
						foreach my $key (keys %access_list_values) {
							$assets_selected{$key} = $access_list_values{$key}[3];
						}
						$page .= Forms->hidden(\%hidden);
						$page .= Forms->access_list('Design/Manage',\@access_list,\%assets_selected,$access_type);
					}
				} 
			} elsif ($task eq 'saved') {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('User Group','');
				$page .= Forms->display_hidden('Saved:','',$groupid);
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%close);						
			} elsif ($task eq 'modify') {
				my $groupid = $query->param('name');
				$page .= Forms->header($page_title,$session_id,$top_menu);
				my %p = StorProc->fetch_one('user_groups','name',$groupid);
				$description = $p{'description'};
				$page .= Forms->form_top('User Group','');
				$page .= Forms->display_hidden('Group id:','groupid',$groupid);
				$page .= Forms->text_box('Description:','description',$description,$textsize{'long_name'});
				$page .= Forms->hidden(\%hidden);
				my %set = ('name' => 'access_list','value' =>'Set Access Values');
				if ($groupid eq 'super_users') {
					$page .= Forms->form_bottom_buttons(\%save,\%close);					
				} else {
					$page .= Forms->form_bottom_buttons(\%save,\%set,\%delete,\%close);					
				}
			}
#
############################################################################
# Setup
#
		} elsif ($obj eq 'setup') {
			@errors = ();
			my $saved = 0;
			if ($query->param('save')) {
				my %where = ();
				my %cfg = StorProc->fetch_list_hash_array('setup',\%where);
				my @setup_props = ('cgi_home','login_authentication','session_timeout','nagios_etc','nagios_bin','nagios_version','upload_dir','backup_dir','enable_externals','enable_groups','enable_ez');
				foreach my $name (@setup_props) {
					my %values = ();
					my $value = $query->param($name);
					unless ($value) { $value = 0 }
					if ($cfg{$name}[0]) {
						$values{'value'} = $value;
						my $result = StorProc->update_obj('setup','name',$name,\%values);
						if ($result =~ /^Error/) { push @errors, $result }
					} else {
						my @vals = ($name,'config',$value);
						my $result = StorProc->insert_obj('setup',\@vals);
						if ($result =~ /^Error/) { push @errors, $result }		
					}
				}
				unless (@errors) { $saved = 1 }
			}
			if ($saved) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Setup','');
				$page .= Forms->form_doc('Updated: Changes to setup accepted.');
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%close,$tab++);					
				
			} else {
				my %docs = Doc->setup();
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Setup','');
				if (@errors) { $page .= Forms->form_errors(\@errors) }
				if ($is_portal) {
					# TODO: GWMON-5150 - set version number to 3.x on next line.
					$page .= Forms->display_hidden('Nagios version:','nagios_version','2.x',$docs{'nagios_version'});
					$page .= Forms->display_hidden('Nagios etc:','nagios_etc','/usr/local/groundwork/nagios/etc',$docs{'nagios_etc'});
					$page .= Forms->display_hidden('Nagios bin:','nagios_bin','/usr/local/groundwork/nagios/bin',$docs{'nagios_bin'});		
					$page .= Forms->display_hidden('Configuration home:','monarch_home','/usr/local/groundwork/monarch',$docs{'monarch_home'});
					$page .= Forms->display_hidden('Backup dir:','backup_dir','/usr/local/groundwork/monarch/backup',$docs{'backup_home'});
					$hidden{'upload_dir'} = $upload_dir;
					$hidden{'enable_groups'} = 1;
					$hidden{'enable_ez'} = 1;
				} else {
					my %p = StorProc->fetch_one('setup','name','login_authentication');
					my @members = ('active','passive','none');
					$page .= Forms->list_box('Login authentication:','login_authentication',\@members,$p{'value'},'',$docs{'login_authentication'});
					%p = StorProc->fetch_one('setup','name','session_timeout');
					$page .= Forms->text_box('Session timeout seconds:','session_timeout',$p{'value'},'5','',$docs{'session_timeout'});
					@members = ('1.x','2.x','3.x');
					%p = StorProc->fetch_one('setup','name','nagios_version');
					$page .= Forms->list_box('Nagios version:','nagios_version',\@members,$p{'value'},'',$docs{'nagios_version'});
					$page .= Forms->text_box('Nagios etc:','nagios_etc',$nagios_etc,$textsize{'long_name'},'',$docs{'nagios_etc'});
					$page .= Forms->text_box('Nagios bin:','nagios_bin',$nagios_bin,$textsize{'long_name'},'',$docs{'nagios_bin'});		
					$page .= Forms->display_hidden('Monarch home:','monarch_home',$monarch_home,$docs{'monarch_home'});
					$page .= Forms->text_box('Backup dir:','backup_dir',$backup_dir,$textsize{'long_name'},'',$docs{'backup_dir'});
					$page .= Forms->text_box('Upload dir:','upload_dir',$upload_dir,$textsize{'long_name'},'',$docs{'upload_dir'});
					$page .= Forms->checkbox('Enable groups:','enable_groups',$enable_groups,$docs{'enable_groups'});
					$page .= Forms->checkbox('Enable EZ:','enable_ez',$enable_ez,$docs{'ez'});
				}
				$page .= Forms->checkbox('Enable externals:','enable_externals',$enable_externals,$docs{'enable_externals'});
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%save,\%cancel,$tab++);					
			}
#
############################################################################
# Nagios cgi		
#
		} elsif ($obj eq 'nagios_cgi_configuration') {
			my $step = $query->param('step');
			$page .= nagios_cgi('','');
#
############################################################################
# Nagios main		
#
		} elsif ($obj eq 'nagios_main_configuration') {
			my $step = $query->param('step');
			$page .= nagios_cfg('','');

#
############################################################################
# Resource
#
		} elsif ($obj eq 'nagios_resource_macros') {
			$page .= resource_cfg('','')
#
############################################################################
# Load
#
		} elsif ($obj eq 'load') {
			my %backup = ('name' => 'backup','value' => 'Backup');
			my %load = ('name' => 'load_options','value' => 'Load');
			if ($query->param('continue')) {
				print "Content-type: text/html \n\n";
				$page .= Forms->header($page_title,$session_id,$top_menu);
				if ($query->param('continue') =~ /$abort{'value'}/) {
					$page .= Forms->form_top('Load Nagios Configuration','');
					$hidden{'obj'} = undef;
					$page .= Forms->hidden(\%hidden);
					my @message = ("Load of Nagios files aborted.");
					$page .= Forms->form_message("Action Canceled:",\@message ,'');
					$page .= Forms->form_bottom_buttons(\%continue,$tab++);		
					$hidden{'obj'} = undef;
				}
			} elsif ($query->param('backup')) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Load Nagios Configuration','');
				my %nagios = StorProc->fetch_one('setup','name','nagios_etc');
				my %backup_dir = StorProc->fetch_one('setup','name','backup_dir');
				my ($backup, $errs) = StorProc->backup($nagios{'value'},$backup_dir{'value'});
				push (@errors, @{$errs});
				if (@errors) {
					my @message = ("Problem(s) Backing up files and/or database to $backup.");
					push (@message, @errors);
					$page .= Forms->form_message("Backup error(s):",\@message ,'error');
				} else {
					my @message = ("Files backed up to $backup.");
					$page .= Forms->form_message("Backup complete:",\@message,'');
				}
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%load,\%abort,$tab++);		
			} elsif ($query->param('abort')) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Load Nagios Configuration','');
				$hidden{'obj'} = undef;
				$page .= Forms->hidden(\%hidden);
				my @message = ("Load of Nagios files aborted.");
				$page .= Forms->form_message("Action Canceled:",\@message ,'');
				$page .= Forms->form_bottom_buttons(\%continue,$tab++);		
				$hidden{'obj'} = undef;
			} elsif ($query->param('run_load')) {
				$page .= Forms->header($page_title,$session_id,$top_menu,'','','','2');
				$page .= Forms->form_top('Load Nagios Object Files','');
				$page .= Forms->wizard_doc('Load Process','Please keep this page open until status reads finished.');
				my $load_option = $query->param('load_option');
				my $purge_escalations = $query->param('purge_escalations');
				$hidden{'CGISESSID'} = $session_id;
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->process_load($load_option,$purge_escalations,$nagios_etc,$abort{'value'},$continue{'value'});
				use CGI::Ajax;
				my $url = Forms->get_ajax_url();
				my $pjx = new CGI::Ajax( 'process_load' => $url );
				return $pjx->build_html($query,$page);
			} elsif ($query->param('load_options')) {
				$page .= Forms->header($page_title,$session_id,$top_menu,'');
				$page .= Forms->form_top('Load Nagios Object Files','');
				$page .= Forms->load_options();
				$load{'name'} = 'run_load';
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%load,\%abort,$tab++);		
			} elsif (-e "$nagios_etc/nagios.cfg") {
				my @message = ();
				push @message, qq(You are about to update or drop all Nagios records in the database. Should you choose to continue it is strongly recommended that you first select the backup option.);
				push @message, qq(Are you sure you want to continue?);
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Load Nagios Configuration','');
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_message("Load from nagios.cfg:",\@message ,'');
				$page .= Forms->form_bottom_buttons(\%backup,\%load,\%abort,$tab++);		
			} else {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Error','');
				$hidden{'obj'} = undef;
				$page .= Forms->hidden(\%hidden);
				my @message = ("Unable to load $nagios_etc/nagios.cfg (update setup options).");
				$page .= Forms->form_message("Does not exist:",\@message ,'error');
				$page .= Forms->form_bottom_buttons(\%continue,$tab++);		
			}

#
############################################################################
# Pre Flight Test
#
		} elsif ($obj eq 'pre_flight_test') {
			$page .= pre_flight('');
#
############################################################################
# Commit
#
		} elsif ($obj eq 'commit') {
			my @results = ();
			my %abort = ('name' => 'abort','value' => 'Abort');
			my %backup = ('name' => 'backup','value' => 'Backup');
			my %commit = ('name' => 'commit','value' => 'Commit');
			my %nagios = StorProc->fetch_one('setup','name','nagios_etc');
			my %monarch_home = StorProc->fetch_one('setup','name','monarch_home');
			my $workspace = $monarch_home{'value'}.'/workspace';
			my %nagios_cfg = StorProc->fetch_one('setup','name','log_file');
			my %nagios_cgi = StorProc->fetch_one('setup','name','default_user_name');

			if ($query->param('backup')) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Commit','');
				my ($backup, $errs) = StorProc->backup($nagios{'value'},$backup_dir);
				push (@errors, @{$errs});
				if (@errors) {
					my @message = ("Problem(s) Backing up files and/or database to $backup.");
					push (@message, @errors);
					$page .= Forms->form_message("Backup error(s):",\@message ,'error');
				} else {
					my @message = ("Files backed up to $backup.");
					$page .= Forms->form_message("Backup complete:",\@message,'');
				}
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%abort,\%commit,$tab++);		
			} elsif ($query->param('abort')) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Nagios Commit','');
				$hidden{'obj'} = undef;
				$page .= Forms->hidden(\%hidden);
				my @message = ("Commit aborted.");
				$page .= Forms->form_message("Action Canceled:",\@message ,'');
				$page .= Forms->form_bottom_buttons(\%continue,$tab++);		
				$hidden{'obj'} = undef;
			} elsif ($query->param('commit')) {
				if ($query->param('refreshed')) {
					use MonarchFile;
					$page .= Forms->header($page_title,$session_id,$top_menu);
					my ($files, $errors) = Files->build_files($user_acct,'','preflight','',$nagios_ver,$nagios_etc,"$monarch_home/workspace",'');
					my @errors = @{$errors};
					my @files = @{$files};
					if (@errors) { 
						$page .= Forms->form_top('Commit Errors','','');
						$page .= Forms->form_errors(\@errors);
						$page .= Forms->hidden(\%hidden);
						$page .= Forms->form_bottom_buttons(\%close,$tab++);
					} else {
						@results = StorProc->pre_flight_check($nagios_bin,$monarch_home);
						my $res_str = pop @results;
						push @results, $res_str;
						unless ($res_str =~ /Things look okay/) {
							push @errors, "Make the necessary corrections and run pre flight check";
						}
						if (@errors) {
							$page .= Forms->form_top('Commit Errors','','');
							$page .= Forms->form_errors(\@errors);
							$page .= Forms->hidden(\%hidden);
							$page .= Forms->form_bottom_buttons(\%close,$tab++);
						} else {
							# my ($files, $errors) = Files->build_files($user_acct,'','','',$nagios_ver,$nagios_etc,$nagios_etc,'');
							
							my $res = Files->copy_files("$monarch_home/workspace",$nagios_etc);
							if ($res =~ /Error/) { 
								push @errors, $res; 
							} else {
								$res = Files->rewrite_nagios_cfg("$monarch_home/workspace",$nagios_etc);
								if ($res =~ /Error/) {  push @errors, $res } 
							}
							if (@errors) { 
								$page .= Forms->form_top('Commit Errors','','');
								$page .= Forms->form_errors(\@errors);
								$page .= Forms->hidden(\%hidden);
								$page .= Forms->form_bottom_buttons(\%close,$tab++);
							} else {
								my @commit = StorProc->commit($monarch_home);
								push (@results, @commit);
								$page .= Forms->form_top('Nagios Commit','');
								$page .= Forms->form_message("Results:",\@results ,'row1');
								$hidden{'obj'} = undef;
								$page .= Forms->hidden(\%hidden);
								$page .= Forms->form_bottom_buttons(\%close,$tab++);
							}
						}
					}
				} else {
					my $now = time;
					$refresh_url = "?nocache=$now&refreshed=1&commit=1";
					foreach my $name (keys %hidden) {
						$refresh_url .= qq(&$name=$hidden{$name});
					}
					$page .= Forms->header($page_title,$session_id,$top_menu,$refresh_url);
					$page .= Forms->form_top('Commit to Nagios','');
					$page .= Forms->form_doc('Running commit...');
					my $now = time;
					$refresh_url = "?update_main=1&nocache=$now&refreshed=1&commit=1";
					$page .= Forms->form_bottom_buttons();		
				}
			} elsif ($nagios_cfg{'value'} && $nagios_cgi{'type'}) {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Nagios Commit','');
				$page .= Forms->hidden(\%hidden);
				my @message = ("Are you sure you want to overwrite your active Nagios configuration and restart Nagios?");
				push @message, ("Should you choose to continue it is strongly recommended that you first select the backup option.");
				$page .= Forms->form_message("Nagios commit:",\@message ,'');
				$page .= Forms->form_bottom_buttons(\%abort,\%backup,\%commit,$tab++);		

			} else {
				$page .= Forms->header($page_title,$session_id,$top_menu);
				$page .= Forms->form_top('Nagios Commit','');
				unless ($nagios_cfg{'value'}) {
					push @errors, 'Nagios main configuration has not been defined.','Use Control->Nagios main configuration to load an existing file or set defaults.';
				}
				unless ($nagios_cgi{'type'}) {
					push @errors, 'Nagios CGI configuration has not been defined.','Use Control->Nagios CGI configuration to load an existing file or set defaults.';
				}	
				$page .= Forms->form_message("Error(s):",\@errors ,'error');
				$hidden{'obj'} = undef;
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%continue,$tab++);
			}
#
############################################################################
# Run Ext info scripts
#
		} elsif ($obj eq 'run_extended_info_scripts') {
			$page .= Forms->header($page_title,$session_id,$top_menu);
			my $ext_info = $query->param('ext_info');
			my $type = $query->param('type');
			if ($ext_info) {
				my @results = ();
				if ($type eq 'host') {
					my %x = StorProc->fetch_one('extended_host_info_templates','name',$ext_info);
					my %w = ('hostextinfo_id' => $x{'hostextinfo_id'});
					my @hosts = StorProc->fetch_list_where('hosts','name',\%w);
					push @results, "Script $x{'script'} from $x{'name'} launched for:";
					push @results, "<hr />";
					foreach my $host (@hosts) {
						my $script = $x{'script'};
						$script =~ s/\$HOSTNAME\$/$host/g;
						system("$script &");
						push @results, "$host '$script'";
						push @results, "<br />";
					}
				} elsif ($type eq 'service') {
					my %x = StorProc->fetch_one('extended_service_info_templates','name',$ext_info);
					my %service_hosts = StorProc->fetch_service_extinfo($x{'serviceextinfo_id'});
					push @results, "Script $x{'script'} from $x{'name'} launched for:";
					push @results, "<hr />";
					foreach my $sid (keys %service_hosts) {
						my $script = $x{'script'};
						$script =~ s/\$HOSTNAME\$/$service_hosts{$sid}[0]/g;
						$script =~ s/\$SERVICENAME\$/$service_hosts{$sid}[1]/g;
						system("$script &");
						push @results, "$service_hosts{$sid}[0] $service_hosts{$sid}[1] '$script'";
						push @results, "<br />";
					}
				}
				$page .= Forms->form_top('External Script','');
				if (@errors) { $page .= Forms->form_message("Error(s):",\@errors ,'error') }
				$page .= Forms->form_message("Results:",\@results ,'row1');
				$page .= Forms->hidden(\%hidden);
				$page .= Forms->form_bottom_buttons(\%continue,$tab++);
			} else {
				my %scripts = StorProc->fetch_scripts('host');				
				$page .= Forms->table_script_links($session_id,'host',\%scripts);
				%scripts = StorProc->fetch_scripts('service');				
				$page .= Forms->table_script_links($session_id,'service',\%scripts);
			}
#
############################################################################
# Run external scripts
#
		} elsif ($obj eq 'run_externals') {
			use MonarchExternals;	
			my @errors = Externals->build_externals($session_id);
			my @results = ("Externals module executed.");
			$page .= Forms->header($page_title,$session_id,$top_menu);
			$page .= Forms->form_top('Run Externals','');
			$page .= Forms->form_message("Results:",\@results ,'row1');
			if (@errors) { $page .= Forms->form_message("Error(s):",\@errors ,'error') }
			$hidden{'obj'} = undef;
			$page .= Forms->hidden(\%hidden);
			$page .= Forms->form_bottom_buttons(\%continue,$tab++);
		}
	}
	return $page;
}


#
############################################################################
# Search
#


sub search() {
	my $detail = Forms->header($page_title,$session_id,$top_menu);
	$detail .= Forms->form_top('Search Hosts','');
	$detail .= Forms->search($session_id);
	$hidden{'view'} = 'search_host';
	$hidden{'CGISESSID'} = $session_id;
	$detail .= Forms->hidden(\%hidden);
	$detail .= Forms->form_bottom_buttons();
	use CGI::Ajax;
	my $url = Forms->get_ajax_url();
	my $pjx = new CGI::Ajax( 'get_hosts' => $url );
	return $pjx->build_html($query,$detail);
}

sub search_services() {
	my $detail = Forms->header($page_title,$session_id,$top_menu);
	$detail .= Forms->form_top('Search Services','');
	$detail .= Forms->search($session_id,'services');
	$hidden{'view'} = 'search_service';
	$hidden{'CGISESSID'} = $session_id;
	$detail .= Forms->hidden(\%hidden);
	$detail .= Forms->form_bottom_buttons();
	use CGI::Ajax;
	my $url = Forms->get_ajax_url();
	my $pjx = new CGI::Ajax( 'get_services' => $url );
	return $pjx->build_html($query,$detail);
}

#
# Begin processing request
#

# db connection
my $auth = StorProc->dbconnect();
# get config info
my %where = ();
my %objects = StorProc->fetch_list_hash_array('setup',\%where);
if (-e '/usr/local/groundwork/config/db.properties') { $is_portal = 1 }
$nagios_ver = $objects{'nagios_version'}[2];
$nagios_bin = $objects{'nagios_bin'}[2];
$nagios_etc = $objects{'nagios_etc'}[2];
$monarch_home = $objects{'monarch_home'}[2];
$monarch_ver = $objects{'monarch_version'}[2];
$backup_dir = $objects{'backup_dir'}[2];
$upload_dir = $objects{'upload_dir'}[2];
$enable_externals = $objects{'enable_externals'}[2];
$enable_groups = $objects{'enable_groups'}[2];
$enable_ez = $objects{'enable_ez'}[2];
$nagios_share = $objects{'physical_html_path'}[2];
if ($is_portal) {
	$doc_root = '/usr/local/groundwork/apache2/htdocs';
}


#
# Check user
#

my $deny_access = 0;
my $show_login = 0;
my $session_timeout = 0;

if ($view eq 'logout') {
	$show_login = 1;
	($userid, $session_id) = undef;
} elsif ($is_portal || $auth == 1) {
	# Auth level 1 = full access no login. 
	$user_acct = $ENV{'REMOTE_USER'};
	if ($user_acct) { 
		my %super_user = ();
		if ($session_id) {
			($userid, $user_acct, $session_id) = StorProc->get_session($session_id);
		} else {
			($userid, $session_id) = StorProc->set_gwm_session($user_acct);
		}
		my ($auth_add, $auth_modify, $auth_delete) = StorProc->auth_matrix($userid,$auth);
		%auth_add = %{$auth_add};
		%auth_modify = %{$auth_modify};
		%auth_delete = %{$auth_delete};
	} else {
		$deny_access = 1;
	}
} elsif ($auth == 2) {
	# Auth level 2 = active login. 
	if ($query->param('process_login')) {
		$userid = StorProc->check_user($user_acct,$password);
		my ($auth_add, $auth_modify, $auth_delete) = StorProc->auth_matrix($userid);
		%auth_add = %{$auth_add};
		%auth_modify = %{$auth_modify};
		%auth_delete = %{$auth_delete};
		if ($auth_add{'enable_ez'} && ($auth_add{'ez_main'} || $auth_add{'ez'})) { $ez = 1 }
		if ($userid =~ /^\d+/) {
			$session_id = StorProc->set_session($userid,$user_acct);
		} else {
			$show_login = 1;
		}
	} elsif ($session_id) {
		($userid, $user_acct, $session_id) = StorProc->get_session($session_id);
		if ($user_acct) {
			my ($auth_add, $auth_modify, $auth_delete) = StorProc->auth_matrix($userid);
			%auth_add = %{$auth_add};
			%auth_modify = %{$auth_modify};
			%auth_delete = %{$auth_delete};
		} else {
			$session_timeout = 1;
		}
	} else {
		$show_login = 1;
		($userid, $session_id) = undef;
	}
} elsif ($auth == 3) {
	# Auth level 3 = passive login - single sign on. 
	# first check if we have a new user being passed
	my $new_user_acct = $ENV{'REMOTE_USER'};
	unless ($new_user_acct) { $new_user_acct = $query->param('user_acct') }
	if ($new_user_acct) {
		# now check for session info
		($userid, $user_acct, $session_id) = StorProc->get_session($session_id,$auth);
		# does stored user = new user? -- if there is one stored
		unless ($new_user_acct eq $user_acct) { 
			# no? then see if new user is valid and give them a sessionid if so
			my %user = StorProc->fetch_one('users','user_acct',$new_user_acct);
			$session_id = StorProc->set_session($user{'user_id'},$new_user_acct);
			$user_acct = $new_user_acct;
		}
	} else {
		($userid, $user_acct, $session_id) = StorProc->get_session($session_id,$auth);
	}
	if ($session_id) {
		my ($auth_add, $auth_modify, $auth_delete) = StorProc->auth_matrix($userid);
		%auth_add = %{$auth_add};
		%auth_modify = %{$auth_modify};
		%auth_delete = %{$auth_delete};
	} else {
		$show_login = 1;
		($userid, $session_id) = undef;
	}
} 

#
# Create frames and content
#

unless ($view =~ /search/ || $query->param('run_load') || $show_login) {
	my $cookie = $query->cookie(CGISESSID => $session_id);
    print $query->header( -cookie=>$cookie );	
}
unless ($enable_externals) {
	delete $auth_add{'externals'};
	delete $auth_modify{'externals'};
	delete $auth_delete{'externals'};
}
unless ($enable_groups) {
	delete $auth_add{'groups'};
	delete $auth_modify{'groups'};
	delete $auth_delete{'groups'};
}

if ($show_login) {
	print "Content-type: text/html \n\n";
	print Forms->login($page_title,$userid);
} elsif ($deny_access) {
	print "Content-type: text/html \n\n";
	print Forms->form_top('Configuration','');
	print Forms->wizard_doc('Access Denied','You must login to use this feature.');
	print Forms->form_bottom_buttons();
	print Forms->footer($debug);
} elsif ($query->param('update_top')) {
	my @top_menus = ();
	my $login = $query->param('login');
	if ($session_timeout) {
		print Forms->login_redirect;
	} elsif ($ez) {
		for my $object (qw(hosts host_groups profiles notifications commit setup)) {
			no strict 'refs';
			push(@top_menus, $object) if ($auth==1 || $auth_add{'ez_' . $object});
		}
		my $login = $query->param('login');
	} else {
		for my $object (qw(profiles services hosts contacts escalations time_periods commands)) {
			push(@top_menus, $object) if ($auth==1 || $auth_add{$object} || $auth_modify{$object});
		}
		for my $object (qw(groups control)) {
			push(@top_menus, $object) if ($auth==1 || $auth_add{$object});
		}
		push @top_menus, 'tools';
	}
	push @top_menus, 'help';
	print Forms->top_frame($session_id,$top_menu,\@top_menus,$auth,$monarch_ver,$enable_ez,$ez,\%auth_add,$login);
} elsif ($query->param('update_main')) {
	$hidden{'update_main'} = 1;
	if ($debug) {
		foreach my $name ($query->param) { 
			my $value = $query->param($name);
			$debug .= "<br>$name $value";
		}
	}
	if ($session_timeout) {
		if ($view =~ /search/) { print "Content-type: text/html \n\n" }
		$body .= Forms->login_redirect;
	} elsif ($view eq 'host_wizard') {
		$body .= host_wizard();
	} elsif ($view eq 'host_profile') {
		$body .= host_profile();
	} elsif ($view eq 'service_profile') {
		$body .= service_profile();
	} elsif ($view eq 'service_template') {
		$body .= service_template();
	} elsif ($view eq 'service_group') {
		$body .= service_group();
	} elsif ($view eq 'service') {
		$body .= service();
	} elsif ($view eq 'service_externals') {
		$body .= externals('service');
	} elsif ($view eq 'host_externals') {
		$body .= externals('host');
	} elsif ($view eq 'profile_importer') {
		$body .= profile_importer();
	} elsif ($view eq 'manage_host') {
		$body .= manage_host();
	} elsif ($view eq 'search_host') {
		$body .= search();
	} elsif ($view eq 'search_service') {
		$body .= search_services();
	} elsif ($view eq 'clone_host') {
		$body .= clone_host();
	} elsif ($view eq 'host_dependencies') {
		$body .= host_dependencies();
	} elsif ($view eq 'parent_child') {
		$body .= parent_child();
	} elsif ($view eq 'escalations') {
		$body .= escalations();
	} elsif ($view eq 'escalation_trees') {
		$body .= escalation_trees();
	} elsif ($view eq 'commands') {
		$body .= command_wizard();
	} elsif ($view eq 'tools') {
		$body .= tools();
	} elsif ($view eq 'manage') {
		$body .= manage();
	} elsif ($view eq 'design') {
		$body .= design();
	} elsif ($view eq 'groups') {
		$body .= groups();
	} elsif ($view eq 'macros') {
		$body .= macros();
	} elsif ($view eq 'control') {
		$body .= control();
	} else {
		$body .= Forms->header($page_title,$session_id,$top_menu);
	}

	print $body;
	print Forms->footer($debug);
} else {
	print Forms->frame($session_id,$top_menu,$is_portal,$ez);
}

my $result = StorProc->dbdisconnect();