#!/usr/local/bin/perl -w -I./
#***********************************************************************
#                                                                       
#   Confidential Trade Secret.                                          
#   Copyright (c) 2001 Paul Rubin, Roswell, GA                          
#   as an unpublished work.  All rights reserved.                       
#                                                                       
#   This program is owned by Paul Rubin and                             
#   contains information that is a confidential trade secret            
#   to the company.                                                     
#                                                                       
# **********************************************************************
#              
#     Program: FlexAdmin.pl $Id: //depot/Inetpub/wwwroot/cgi-bin/FlexAdmin.pl#3 $
#              
#     Written: Sat Aug 29, 1998
#              
#     Purpose: 
#              
#       Notes: 
#              
# Last Update: $Change: 9 $ $Revision: #3 $ $DateTime: 2002/02/03 19:26:58 $ $Author: Paul $ 
#
#==========================================================================

use strict;

$MAIN::SessionFile = "FlexAdmin.log";
$MAIN::UsersFile = "Users.dat";
#    <expiration time[10]>\t<user[16]>\t<ip address[15]>\t<login time[24]> [69/70]
$MAIN::SessionSize = 69 + $MAIN::CRLF;

#==========================================================================
# Initialize cgi resources
#==========================================================================

$|=1;

use CGI qw(:all);
use CGI::Carp qw(fatalsToBrowser confess carp croak);
use MIME::Base64;

import_names('cgi');

print header(
#         -nph=>1,
         -status=>"200 Ok",
         -type=>"text/html"
      );

use FlexConfig;
use FlexData;
use FlexDefTmpl;
use FlexTemplate;

ReadConfig();

#==========================================================================
# Administrative User Functions
#==========================================================================


#==========================================================================
# LoginForm
#==========================================================================
# 
# Purpose:    Export A Login Form And Exit
#             
#--------------------------------------------------------------------------

sub LoginForm
{
   my $html;
   $html =  "\n<div align=\"center\"><center>";
   $html .= "\n   <table border=\"8\" cellpadding=\"0\" cellspacing=\"0\">";
   $html .= "\n      <tr>";
   $html .= "\n         <td>";
   $html .= "\n            <form method=\"post\" enctype=\"application/x-www-form-urlencoded\">";
   $html .= "\n               <input type=\"hidden\" name=\"Operation\" value=\"Login\">";
   $html .= "\n               <center>Flex Administrative Login</center>";
   $html .= "\n               <table border=\"0\">";
   $html .= "\n                  <tr>";
   $html .= "\n                     <td align=\"right\">User:</td>";
   $html .= "\n                     <td><input type=\"text\" size=\"16\"";
   if (defined($_[0]))
      { $html .= "\n                     maxlength=\"16\" name=\"User\" value=\"$_[0]\"></td>" }
   else 
      { $html .= "\n                     maxlength=\"16\" name=\"User\" ></td>" }
   $html .= "\n                  </tr>";
   $html .= "\n                  <tr>";
   $html .= "\n                     <td align=\"right\">Password:</td>";
   $html .= "\n                     <td><input type=\"password\" size=\"16\"";
   if (defined($_[1]))
      { $html .= "\n                     maxlength=\"16\" name=\"Password\" value=\"$_[1]\"></td>" }
   else 
      { $html .= "\n                     maxlength=\"16\" name=\"Password\" ></td>" }
   $html .= "\n                  </tr>";
   $html .= "\n               </table>";
   $html .= "\n               <center>";
   $html .= "\n                  <input type=\"submit\" value=\"Login\">";
   $html .= "\n                  <input type=\"reset\"></td>";
   $html .= "\n               </center>";
   $html .= "\n            </form>";
   $html .= "\n         </td>";
   $html .= "\n      </tr>";
   $html .= "\n   </table>";
   $html .= "\n</center></div>";
   return $html;
}

#==========================================================================
# AdminTest
#==========================================================================
# 
# Purpose:    This tests the need for and executes the administrative
#             login
#             
# Algorithm:  when a script is executed directly, the request mode is
#             get, but there is no query_string, and there are no argv's
#             
#--------------------------------------------------------------------------

sub AdminTest
{
   my $req = $ENV{"REQUEST_METHOD"};

   if ($#ARGV != -1) { return; }
   if (!defined($req)) { return; }

   my $qry = $ENV{"QUERY_STRING"};

   if (!defined($qry)) { $qry=''; }
   if ($req eq "GET" && $qry eq '') {
      #if we get here we need to execute the login.
      print start_html("Flex Administrative Login");
      print LoginForm();
      print TagLine();
      print end_html();
      exit 0;
   }
}

#==========================================================================
# Session Information
#==========================================================================
# 
# The session file doubles as the log in file for users that log in 
# and preform maintenance.  While this is not an activity log it will 
# provide a basis for login in and logout tine.  Entries in this file 
# will only be held valid as long as the user pulls a page within 
# the time in seconds specified in the config file.
# 
# To make this file editable all records will be created in a fixed 
# width format. 
# 
#    <expiration time[10]>\t<user[16]>\t<ip address[15]>\t<login time[24]> [69/70]
# 
# This file will grow until the session number reaches the limit 
# set in the config file is reached.  Then the session number will be 
# reset and the first records will be overwritten.  
# 

#==========================================================================
# SessionManage
#==========================================================================
# 
# Purpose:    This procedure creates new sessions and tests old ones for 
#             valid login status
#             
# Algorithm:  if passed session is 0
#                get new session number
#                seek to record position
#                configure session record
#             else 
#                read session record
#                if expired return failure
#                else update time
#             write session record
#             return success
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub SessionManage
{
   push(@MAIN::CallStack, "SessionManage");
   my $session = shift;
   my $user = shift;
   my @session_record;
   my $max = $MAIN::SessionSize - 1 - $MAIN::CRLF;

   if (-e $MAIN::SessionFile) 
   {
      open ( SESSION, "+< $MAIN::SessionFile") || 
         AdminError( "SessionManage", "Cannot open file $MAIN::SessionFile $!");
   }
   else 
   {
      open ( SESSION, "> $MAIN::SessionFile") || 
         AdminError( "SessionManage", "Cannot create file $MAIN::SessionFile $!");
      print SESSION pack("A$max", "Expiration\tUser\tLogin in Time"), "\n";
      $MAIN::Config{"NextSession"} = 1;
      WriteRecordHash(\%MAIN::Config, $MAIN::ConfigFile, 1, ".");
   }

   # if passed session is 0
   if ($session == 0)
   {
      # get new session number
      ReadConfig();
      $session = $MAIN::Config{"NextSession"}++;
      if ($MAIN::Config{"NextSession"} > $MAIN::Config{"MaxSession"}) { $MAIN::Config{"NextSession"} = 1 }
      WriteRecordHash(\%MAIN::Config, $MAIN::ConfigFile, 1, ".");

      # seek to record position
      seek (SESSION, $MAIN::SessionSize * $session, 0);

      # configure session record
      @session_record = (time() + $MAIN::Config{"SessionTimeout"}, $user, 
         $ENV{"REMOTE_ADDR"}, $_ = localtime());
   }
   else 
   {
      # read session record
      seek (SESSION, $MAIN::SessionSize * $session, 0);
      $_ = StripRecord(0, $_=<SESSION>);
      @session_record = split(/\t/);

      # if expired return failure
      if ((time() > $session_record[0]) || 
          ($session_record[2] ne $ENV{"REMOTE_ADDR"}) ) 
      { 
         close (SESSION);
         pop(@MAIN::CallStack);
         return 0 
      }
      # else update time
      else
      {
         $session_record[0] = time() + $MAIN::Config{"SessionTimeout"};
      }
   }
   # write session record
   seek (SESSION, $MAIN::SessionSize * $session, 0);
   print SESSION pack("A$max", join("\t", @session_record)), "\n";
   close (SESSION);

   # return success
   pop(@MAIN::CallStack);
   return $session, $session_record[1];
}

#==========================================================================
# Session Management tests
#==========================================================================

 #reset session file
 #unlink ($MAIN::SessionFile);
 #
 #print header();
 #
 #$ENV{"REMOTE_ADDR"} = "127.0.0.1";
 #my @a;
 #@a = SessionManage(0, "Paul");
 #print "\n<br>New Session Returns: @a";
 #
 #@a = SessionManage(0, "Paul");
 #print "\n<br>New Session Returns: @a";
 #
 #@a = SessionManage(1, "Paul");
 #print "\n<br>Session 1 check Returns: @a";
 #
 ## mess up the ip address
 #$ENV{"REMOTE_ADDR"} = "127.0.0.2";
 #@a = SessionManage(1, "Paul");
 #print "\n<br>Session 1 check Returns (should fail): @a";
 #
 #
 #print end_html();
 #exit 0;


#==========================================================================
# MenuOption
#==========================================================================
# 
# Purpose:    Produce a string which is a complete selection for the specific
#             menu option passed
#             
# Format:     MenuOption('session', 'operation')
#             
#--------------------------------------------------------------------------
sub MenuOption
{
   my $session = shift;
   my $operation = shift;
   my $link;

   $link = url();
   #remove commands
   $link =~ s/\?.+//;
   $link .= "?Operation=$operation";
   $link .= "&Session=$session";

   return $link;
}

#==========================================================================
# MenuButton
#==========================================================================
# 
# Purpose:    Produce a button that makes a one button form (operation)
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     MenuButton ('session', 'button label', 'operation')
#             
#--------------------------------------------------------------------------
sub MenuButton
{
   my $session = shift;
   my $button = shift;
   my $operation = shift;
   my $html;
   
   $html .= "<form method=\"GET\" action=\"" . url() . "\">";
   $html .= "   <input type=\"hidden\" name=\"Operation\" value=\"$operation\">";
   $html .= "   <input type=\"hidden\" name=\"Session\" value=\"$session\">";
   $html .= "   <p><input type=\"submit\" value=\"$button\" name=\"Submit\"></p>";
   $html .= "</form>";

   return $html;
}

#==========================================================================
# MainMenu
#==========================================================================
# 
# Purpose:    Produce a menu of available options
#             
# Algorithm:  
#             
# Notes:      level 9 all, 8 no config, 7 no users, 4 no templates
#             
# Format:     MainMenu('session', 'security level')
#             
#--------------------------------------------------------------------------
sub MainMenu
{
   my $session = shift;
   my $level = shift;
   my $html;

   $html = start_html("Flex  Administrative Main Menu");
   $html = MessageCheck($html);
   $html .= "\n<center>";
   $html .= "\n<h1>Flex  Administrative Main Menu</h1>";
   $html .= "\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">";
   if ($level >= $MAIN::Config{"DataFileMenuSec"} || $level >= $MAIN::Config{"ViewAllOptSec"})
   {
      $html .= "\n<tr><td align=center>" . MenuButton($session, "Data File Maintenance Menu", "DatabaseMenu") . "</td></tr>";
   }
   if ($level >= $MAIN::Config{"TemplateMenuSec"} || $level >= $MAIN::Config{"ViewAllOptSec"})
   {
      $html .= "\n<tr><td align=center>" . MenuButton($session, "HTML Template Maintenance", "TemplateMenu") . "</td></tr>";
   }
   if ($level >= $MAIN::Config{"StaticPageMenuSec"} || $level >= $MAIN::Config{"ViewAllOptSec"})
   {
      $html .= "\n<tr><td align=center>" . MenuButton($session, "HTML StaticPage Maintenance", "StaticPageMenu") . "</td></tr>";
   }
   if ($level >= $MAIN::Config{"ImageMenuSec"} || $level >= $MAIN::Config{"ViewAllOptSec"})
   {
      $html .= "\n<tr><td align=center>" . MenuButton($session, "Image Maintenance", "ImageMenu") . "</td></tr>";
   }
   if ($level >= $MAIN::Config{"UserMaintSec"} || $level >= $MAIN::Config{"ViewAllOptSec"})
   {
      $html .= "\n<tr><td align=center>" . MenuButton($session, "User Maintenance", "UserEditTable") . "</td></tr>";
   }
   if ($level >= $MAIN::Config{"SystemConfigSec"} || $level >= $MAIN::Config{"ViewAllOptSec"})
   {
      $html .= "\n<tr><td align=center>" . MenuButton($session, "Edit System Configuration", "ConfigEditForm") . "</td></tr>";
   }
   $html .= "\n</table></center>";
   $html .= TagLine();
   return $html;
}

#==========================================================================
# DirectoryMenu
#==========================================================================
# 
# Purpose:    Take in a directory, filespec and a function to call for
#              each item in the menu.
# Algorithm:  
#             
# Notes:      Function Sig: (function)('session', 'security level', 'file name', 'mod time')
#             
# Format:     DirectoryMenu ('directory', 'file spec', 
#                'function pointer (menu item)', 'session', 'security level')
#             
#--------------------------------------------------------------------------
sub DirectoryMenu
{
   my $dir = shift;
   my $spec = shift;
   my $func = shift;
   my $session = shift;
   my $level = shift;
   my @files;
   my $id;
   my $html;
   my $time;
   my @stat;

   opendir (DIR, "$dir");
   while (defined($_ = readdir(DIR))) 
   { 
      if (/$spec/i) { push @files, $_ } 
   }
   closedir(DIR);

   @files = sort @files;

   for ($id=0; $id <= $#files; $id++)
   {
     @stat = stat($dir . "/" . $files[$id]);
     $time = localtime($stat[9]);
     $time = substr($time, 11, 8 ) . " " . substr($time, 0, 10) . ", " . substr($time, 20, 4);
      $html .= &{$func}($session, $level, $files[$id], $time);
   }
   return $html;
}

#==========================================================================
# StaticPageMenuItem
#==========================================================================
# 
# Purpose:    Static page menu items formatting function
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     StaticPageMenuItem ('session', 'security level', 'file name', 'mod time')
#             
#--------------------------------------------------------------------------
sub StaticPageMenuItem
{
   my $session = shift;
   my $level = shift;
   my $StaticPage = shift;
   my $time = shift;
   my $html;

   $html .= "\n<tr>";
   $html .= "\n   <td colspan=3><font size=\"+2\">$StaticPage</font>&nbsp;&nbsp;$time";
   $html .= "\n</td></tr><tr>";

   $html .= "\n   <td><a href=\"" . WebRootFix($MAIN::Config{"StaticDir"}) . "/$StaticPage\">";
   $html .= "View Static Page</a></td>";

   $html .= "\n   <td><a href=" . MenuOption($session, "EditStaticPageForm");
   $html .= "&StaticPage=$StaticPage >Edit Static Page</a></td>";

   $html .= "\n   <td><a href=" . MenuOption($session, "DeleteStaticPage");
   $html .= "&StaticPage=$StaticPage >Delete Static Page</a></td>";

   $html .= "\n</tr>";
   return $html;
}

#==========================================================================
# StaticPageMenu
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub StaticPageMenu
{
   my $session = shift;
   my $level = shift;
   my $html;
   my @files;

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"StaticPageMenuSec"} && $level < $MAIN::Config{"ViewAllOptSec"})
   {
      AdminError( "StaticPageMenu", "Not allowed to Use this menu");
   }

   $html = start_html("StaticPage Menu");
   $html = MessageCheck($html);
   $html .= "\n<center>";
   $html .= "\n   <h1>StaticPage Menu</h1>";
   $html .= "\n</center>";

   $html .= "\n<table cellspacing=6>";

   $html .= DirectoryMenu($MAIN::Config{"StaticDir"}, "(?:\\.html\$)|(?:\\.htm\$)|(?:\\.shtml\$)", 
         \&StaticPageMenuItem, $session, $level);

   $html .= "\n</table><br>";

   $html .= "\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">";
   $html .= "\n<tr><td>" . MenuButton($session, "Upload StaticPage File", "UploadStaticPageForm") . "</td></tr>";
   $html .= "\n<tr><td>" . MenuButton($session, "Create StaticPage File", "CreateStaticPageForm") . "</td></tr>";
   $html .= "\n<tr><td>" . MenuButton($session, "Main Menu", "MainMenu") . "</td></tr>";
   $html .= "\n</table>";
   $html .= TagLine();
   $html .= end_html();
   return $html;

}

#==========================================================================
# ImageMenuItem
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub ImageMenuItem
{
   my $session = shift;
   my $level = shift;
   my $image = shift;
   my $time = shift;
   my $linkimage = CGI::escape($image);
   my $html;

   $html .= "\n<tr>";
   $html .= "\n   <td colspan=2><font size=\"+2\">$image</font>&nbsp;&nbsp;$time</td>";
   $html .= "\n</tr><tr>";

   $html .= "\n   <td><a href=\"" . WebRootFix($MAIN::Config{"ImageDir"}) . "/$linkimage\">";
   $html .= "View Image</a></td>";

   $html .= "\n   <td><a href=" . MenuOption($session, "DeleteImage");
   $html .= "&ImageFile=$image >Delete Image</a></td>";

   $html .= "\n</tr>";
   return $html;
}

#==========================================================================
# ImageMenu
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub ImageMenu
{
   my $session = shift;
   my $level = shift;
   my $html;
   my @files;

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"ImageMenuSec"} && $level < $MAIN::Config{"ViewAllOptSec"})
   {
      AdminError( "ImageMenu", "Not allowed to Use this menu");
   }

   $html = start_html("Image Menu");
   $html = MessageCheck($html);
   $html .= "\n<center>";
   $html .= "\n   <h1>Image Menu</h1>";
   $html .= "\n</center>";

   $html .= "\n<table cellspacing=6>";

   $html .= DirectoryMenu($MAIN::Config{"ImageDir"}, "\\.jpg\$|\\.gif\$", 
         \&ImageMenuItem, $session, $level);

   $html .= "\n</table><br>";

   $html .= "\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">";
   $html .= "\n<tr><td>" . MenuButton($session, "Upload Image File", "UploadImageForm") . "</td></tr>";
   $html .= "\n<tr><td>" . MenuButton($session, "Main Menu", "MainMenu") . "</td></tr>";
   $html .= "\n</table>";
   $html .= TagLine();
   $html .= end_html();
   return $html;

}


#==========================================================================
# DatabaseMenuOption
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub DatabaseMenuItem
{
   my $session = shift;
   my $level = shift;
   my $datafile = shift;
   my $time = shift;
   my $html;

   $html .= "\n<tr>";
   $html .= "\n   <td colspan=2><font size=\"+2\">$datafile</font>&nbsp;&nbsp;$time";
   $html .= "\n</td></tr><tr><td>";

   #sample templates
   $html .= "\n   <a href=" . MenuOption($session, "DefaultSingleTemplate");
   $html .= "&DataFile=$datafile >Default Single Record Template</a><br>";
   $html .= "\n   <a href=" . MenuOption($session, "DefaultMultiTemplate");
   $html .= "&DataFile=$datafile >Default Multi Record Template</a><br>";
   $html .= "\n   <a href=" . MenuOption($session, "DefaultSearchForm");
   $html .= "&DataFile=$datafile >Default Search Form</a></td>";

   #search/edit option
   $html .= "\n   <td><a href=" . MenuOption($session, "SearchEditForm");
   $html .= "&DataFile=$datafile >Search Records to Edit</a><br>";
   $html .= "\n   <a href=" . MenuOption($session, "DefaultEditTemplate");
   $html .= "&DataFile=$datafile >Default Edit Record Template</a><br>";
   $html .= "\n   <a href=" . MenuOption($session, "DefaultRecordManagerTemplate");
   $html .= "&DataFile=$datafile >Default Record Manager Template</a></td><td>";

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level >= $MAIN::Config{"DataFileMenuSec"} || $level >= $MAIN::Config{"ViewAllOptSec"})
   {
      $html .= "\n   <a href=" . MenuOption($session, "AddDataRecord");
      $html .= "&DataFile=$datafile >Add Record</a><br>";
   }

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level >= $MAIN::Config{"DataFileMenuSec"} || $level >= $MAIN::Config{"ViewAllOptSec"})
   {
      #Edit Field Names
      $html .= "\n   <a href=" . MenuOption($session, "EditFieldNames");
      $html .= "&DataFile=$datafile >Edit Field Names</a><br>";

      #Edit Configuration Option
      #$html .= "\n   <a href=" . MenuOption($session, "EditFileConfig");
      #$html .= "&DataFile=$datafile >Edit Data File Configuration</a><br>";

      #Repair Data File
      $html .= "\n   <a href=" . MenuOption($session, "RepairDataFile");
      $html .= "&DataFile=$datafile >Repair Data File</a>&nbsp;&nbsp;";

      #Delete File
      $html .= "\n   <a href=" . MenuOption($session, "DeleteDataFile");
      $html .= "&DataFile=$datafile >Delete Data File</a>";
   }

   $html .= "\n</td></tr>";

   return $html;
}

#==========================================================================
# DatabaseMenu
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      level 6 all, 4 no config
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub DatabaseMenu
{
   my $session = shift;
   my $level = shift;
   my $html;
   my @files;

   if (($level < $MAIN::Config{"DataFileMenuSec"}) &&
       ($level < $MAIN::Config{"ViewAllOptSec"})) 
   {
      AdminError( "DataBaseMenu", "Now allowed to use Data File Menu");
   }

   $html = start_html("Database Menu");
   $html = MessageCheck($html);
   $html .= "\n<center>";
   $html .= "\n   <h1>Database Menu</h1>";
   $html .= "\n</center>";

   $html .= "\n<table cellspacing=6>";

   $html .= DirectoryMenu($MAIN::Config{"DataDir"}, "\\.dat\$", 
         \&DatabaseMenuItem, $session, $level);

   $html .= "\n</table><br>";

   $html .= "\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">";
   $html .= "\n<tr><td>" . MenuButton($session, "Upload Data File", "UploadDataForm") . "</td></tr>";
   $html .= "\n<tr><td>" . MenuButton($session, "Create Data File", "CreateDataForm") . "</td></tr>";
   $html .= "\n<tr><td>" . MenuButton($session, "Main Menu", "MainMenu") . "</td></tr>";
   $html .= "\n</table>";
   $html .= TagLine();
   $html .= end_html();
   return $html;

}

#==========================================================================
# TemplateMenuOption
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub TemplateMenuItem
{
   my $session = shift;
   my $level = shift;
   my $template = shift;
   my $time = shift;
   my $html;

   $html .= "\n<tr>";
   $html .= "\n   <td colspan=2><font size=\"+2\">$template</font>&nbsp;&nbsp;$time";
   $html .= "\n</td></tr><tr>";

   $html .= "\n   <td><a href=" . MenuOption($session, "ViewTemplate");
   $html .= "&TemplateFile=$template >View Template File</a></td>";

   $html .= "\n   <td><a href=" . MenuOption($session, "EditTemplateForm");
   $html .= "&TemplateFile=$template >Edit Template File</a></td>";

   $html .= "\n   <td><a href=" . MenuOption($session, "DeleteTemplate");
   $html .= "&TemplateFile=$template >Delete Template File</a></td>";

   $html .= "\n</tr>";
   return $html;
}


#==========================================================================
# TemplateMenu
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub TemplateMenu
{
   my $session = shift;
   my $level = shift;
   my $html;
   my @files;

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"TemplateMenuSec"} && $level < $MAIN::Config{"ViewAllOptSec"})
   {
      AdminError( "TemplateMenu", "Not allowed to Use this menu");
   }

   $html = start_html("Template Menu");
   $html = MessageCheck($html);
   $html .= "\n<center>";
   $html .= "\n   <h1>Template Menu</h1>";
   $html .= "\n</center>";

   $html .= "\n<table cellspacing=6>";

   $html .= DirectoryMenu($MAIN::Config{"TemplateDir"}, "\\.html\$", 
         \&TemplateMenuItem, $session, $level);

   $html .= "\n</table><br>";

   $html .= "\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">";
   $html .= "\n<tr><td>" . MenuButton($session, "Upload Template File", "UploadTemplateForm") . "</td></tr>";
   $html .= "\n<tr><td>" . MenuButton($session, "Create Template File", "CreateTemplateForm") . "</td></tr>";
   $html .= "\n<tr><td>" . MenuButton($session, "Main Menu", "MainMenu") . "</td></tr>";
   $html .= "\n</table>";
   $html .= TagLine();
   $html .= end_html();
   return $html;
}

#==========================================================================
# AuthorizeLogin
#==========================================================================
# 
# Purpose:    Authorize logins to the system
#             
# Algorithm:  collect user and password
#             lookup in users.dat
#             validate password
#             create session id
#             return main menu
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub AuthorizeLogin
{
   my $user = param("User");
   my $password = param("Password");
   my %record;
   my $decoded;
   my $session;
   my $rec;
   
   # find the user in the user file
   ($rec) = IndexLookup($MAIN::UsersFile, 'User', $user, "" , ".");
   ReadRecordHash (\%record, $MAIN::UsersFile, $rec, ".");
   $decoded = MIME::Base64::decode($record{"Password"});

   # validate the login
   if (($record{"User"} ne $user) || ($decoded ne "$user\t$password"))
   {
      #if we get here login is no good
      print start_html("Flex Administrative Login");
      print "<Center>Your Login is not valid, Please Re-enter</center></p>";
      print LoginForm($user, $password);
      print TagLine();
      print end_html();
      exit 0;
   }

   # create the session id
   ($session, $user) = SessionManage(0, $user);

   # return main menu
   print MainMenu($session, $record{"Level"});
   exit 0;
}


#my $encoded = MIME::Base64::encode("Chris Williams\tsuccess");
#print "\n", $encoded; 
#exit 0;

#==========================================================================
# UploadDataForm
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub UploadDataForm
{
   my $session = shift;
   my $level = shift;
   if ($level < $MAIN::Config{"DataFileUplSec"} && $level < $MAIN::Config{"ViewAllOptSec"})
   {
      AdminError( "UploadDataForm", "Not allowed to upload");
   }

   print start_html("Data File Upload");
   print "\n<center>";
   print "\n<h1>Upload Data File</h1>";
   print "\n<form method=\"POST\" enctype=\"multipart/form-data\" name=\"DataFileUploadForm\">";
   print "\n   <input type=\"hidden\" name=\"Operation\" value=\"UploadDataFile\">";
   print "\n   <input type=\"hidden\" name=\"Session\" value=\"$session\">";
   print "\n   <table border=\"0\">";
   print "\n      <tr>";
   print "\n         <td align=\"right\">Local Data File:</td>";
   print "\n         <td><input type=\"file\" size=\"36\" maxlength=\"255\" name=\"LocalDataFile\" ></td>";
   print "\n      </tr>";
   print "\n      <tr>";
   print "\n         <td align=\"right\">Flex  Data File:</td>";
   print "\n         <td><input type=\"text\" size=\"50\" name=\"DataFile\"></td>";
   print "\n      </tr>";
   print "\n      <tr>";
   print "\n         <td align=\"right\">File Type:</td>";
   print "\n         <td><input type=\"radio\" checked name=\"FileType\" value=\"1\">File Contains Field Labels<br>";
   print "\n         <input type=\"radio\" name=\"FileType\" value=\"0\">Field does not contain Field Labels</td>";
   print "\n      </tr>";
   print "\n      <tr>";
   print "\n         <td align=\"right\">Number of Fields</td>";
   print "\n         <td><input type=\"text\" size=\"10\" name=\"NumberOfFields\">";
   print "\n         <font size=\"-1\"><em> (unnecessary if file has field names)</em></font></td>";
   print "\n      </tr>";
   print "\n      <tr>";
   print "\n         <td align=\"right\">Delimiter Type</td>";
   print "\n         <td><input type=\"radio\" checked name=\"DelimiterType\" value=\"1\">Tab Delimited<br>";
   print "\n         <input type=\"radio\" name=\"DelimiterType\" value=\"2\">Quote+Comma Delimited<br>";
   print "\n         <input type=\"radio\" name=\"DelimiterType\" value=\"0\">Other Delimiter</td>";
   print "\n      </tr>";
   print "\n      <tr>";
   print "\n         <td align=\"right\">Other Delimiter:</td>";
   print "\n         <td><input type=\"text\" size=\"10\" name=\"Delimiter\">";
   print "\n         <font size=\"-1\"><em> (unnecessary if file has tab delimiters)</em></font></td>";
   print "\n      </tr>";
   print "\n   </table>";
   print "\n   <input type=\"submit\" name=\"Submit\" value=\"Submit\">";
   print "\n</form>";
   print "\n</center>";

   print end_html();
   exit 0;

}

#==========================================================================
# 
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub BasicUploadForm
{
   my $session = shift;
   my $level = shift;
   my $operation = shift;
   my $title = shift;
   print start_html("Upload $title");
   print "\n<center>";
   print "\n<h1>Upload $title</h1>";
   print "\n<form method=\"POST\" enctype=\"multipart/form-data\" name=\"FileUploadForm\" >";
   print "\n   <input type=\"hidden\" name=\"Operation\" value=\"$operation\">";
   print "\n   <input type=\"hidden\" name=\"Session\" value=\"$session\">";
   print "\n   <table border=\"0\">";
   print "\n      <tr>";
   print "\n         <td align=\"right\">Local File Name:</td>";
   print "\n         <td><input type=\"file\" size=\"36\" maxlength=\"255\" name=\"BrowserFile\"></td>";
   print "\n      </tr>";
   print "\n      <tr>";
   print "\n         <td align=\"right\">Flex  File:</td>";
   print "\n         <td><input type=\"text\" size=\"50\" name=\"LocalFile\"></td>";
   print "\n      </tr>";
   print "\n   </table>";
   print "\n   <input type=\"submit\" name=\"Submit\" value=\"Submit\">";
   print "\n</form>";
   print "\n</center>";

   print end_html();
   exit 0;
}

#==========================================================================
# UploadTemplateForm
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub UploadTemplateForm
{
   my $session = shift;
   my $level = shift;
   if ($level < $MAIN::Config{"TemplateUplSec"} && $level < $MAIN::Config{"ViewAllOptSec"})
   {
      AdminError( "UploadTemplateForm", "Not allowed to upload");
   }

   BasicUploadForm($session, $level, "UploadTemplateFile", "Template File");

}

#==========================================================================
# UploadStaticPage
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub UploadStaticPageForm
{
   my $session = shift;
   my $level = shift;
   if ($level < $MAIN::Config{"StaticPageUplSec"} && $level < $MAIN::Config{"ViewAllOptSec"})
   {
      AdminError( "UploadStaticPage", "Not allowed to upload");
   }
   BasicUploadForm($session, $level, "UploadStaticPage", "Static Page");
   
}

#==========================================================================
# UploadImage
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub UploadImageForm
{
   my $session = shift;
   my $level = shift;
   if ($level < $MAIN::Config{"ImageUplSec"} && $level < $MAIN::Config{"ViewAllOptSec"})
   {
      AdminError( "UploadImage", "Not allowed to upload");
   }
   BasicUploadForm($session, $level, "UploadImage", "Image File");
   
}
#==========================================================================
# BasicUpload
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub BasicUpload
{
   my $session = shift;
   my $level = shift;
   my $ext = shift;
   my $dir = shift;
   my $binary = shift;
   my $source = param("BrowserFile");
   my $destination = param("LocalFile");
   my $extsr = "\\." . $ext . "\$";

   if($destination eq "")
   {
      my $slash  = rindex($source, "/");
      my $bslash = rindex($source, "\\");
      if ($bslash > $slash) {$slash = $bslash}
      # use the local file name as a base
      if ($slash == -1) { $destination = lc($source) }
      else { $destination = substr(lc($source), $slash + 1) }
   }

   if($ext ne "")
   {
      if($destination =~ /$extsr/i) { }
      elsif($destination =~ /\.tar$/i) { $binary = 1 }
      else { $destination .= ".$ext" }
   }

   open (DESTFILE, "> $dir/$destination") || AdminError( "BasicUpload", "cannot open file $destination: $!");

   no strict "refs";
   if ($binary == 1)
   {
      my $bytes;
      my $buffer;
      binmode(DESTFILE);
      binmode($source);
      while(!eof($source))
      {
         $bytes = read($source, $buffer, 1024);
         if ($bytes) { print DESTFILE $buffer }
      }
   }
   else
   {
      while(<$source>)
      {
         chomp;
         if ($MAIN::CRLF == 0) { s/\r//g }
         print DESTFILE $_, "\n";
      }
   }
   use strict "refs";
   close(DESTFILE);

   if($destination =~ /\.tar$/i) 
   { 
      # Expand Tar File 
      print "\n Unpacking TAR File <br>";

      open (TAR, " tar -xvf $dir/$destination -C $dir | ") || AdminError("BasicUpload", "cannot open tar of $destination ");
      while (<TAR>)
      {
         print "\n $_ <br>";
      }
      close (TAR);
      unlink ("$dir/$destination");
   }
   return $destination;
}

#==========================================================================
# UploadTemplateFile
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub UploadTemplateFile
{
   my $session = shift;
   my $level = shift;
   my $input = param("LocalFile");
   my $template = param("BrowserFile");

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"TemplateUplSec"})
   {
      if ($level == $MAIN::Config{"ViewAllOptSec"}) { ViewOnlyMessage() }
      AdminError( "UploadTemplateFile", "Not allowed to upload");
   }

   BasicUpload($session, $level, "html", $MAIN::Config{"TemplateDir"});

   param("Message", "Template File Uploaded");
   print TemplateMenu($session, $level);
   exit 0;
}

#==========================================================================
# UploadStaticPage
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub UploadStaticPage
{
   my $session = shift;
   my $level = shift;

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"StaticPageUplSec"})
   {
      if ($level == $MAIN::Config{"ViewAllOptSec"}) { ViewOnlyMessage() }
      AdminError( "UploadStaticPage", "Not allowed to upload");
   }

   BasicUpload($session, $level, "html", $MAIN::Config{"StaticDir"});

   param("Message", "Static Page Uploaded");

}

#==========================================================================
# UploadImage
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub UploadImage
{
   my $session = shift;
   my $level = shift;

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"ImageUplSec"})
   {
      if ($level == $MAIN::Config{"ViewAllOptSec"}) { ViewOnlyMessage() }
      AdminError( "UploadImage", "Not allowed to upload");
   }

   BasicUpload($session, $level, "", $MAIN::Config{"ImageDir"}, 1);

   param("Message", "Image Uploaded");

}

#==========================================================================
# EditTemplateForm
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub EditTemplateForm
{
   my $session = shift;
   my $level = shift;
   my $template = param("TemplateFile");
   my $html;
   
   if(defined($template)) { $html = ReadTemplate($template) }
   
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"TemplateMenuSec"} && $level < $MAIN::Config{"ViewAllOptSec"})
   {
      AdminError( "EditTemplateForm", "Not allowed to Edit");
   }

   print start_html("Edit Template File");
   print "\n<center>";
   print "\n   <h1>Edit Template File<br><em>$template</em></h1>";
   print "\n   <form method=\"post\" enctype=\"application/x-www-form-urlencoded\">";
   print "\n      <input type=\"hidden\" name=\"Operation\" value=\"EditTemplateFile\">";
   print "\n      <input type=\"hidden\" name=\"Session\" value=\"$session\">";
   if ($template)
   {
      print "\n      <input type=\"hidden\" name=\"TemplateFile\" value=\"$template\"}\">";
   }
   print "\n      <table border=\"0\">";
   if ($template eq "")
   {
      print "\n         <tr>";
      print "\n            <td align=\"right\" valign=\"top\">Template Name:</td>";
      print "\n            <td><input type=\"text\" name=\"TemplateFile\" ></td>";
      print "\n         </tr>";
   }
   print "\n         <tr>";
   print "\n            <td align=\"right\" valign=\"top\">Contents:</td>";
   print "\n            <td><textarea name=\"TemplateData\" rows=\"30\" cols=\"72\">$html</textarea></td>";
   print "\n         </tr>";
   print "\n      </table>";
   print "\n      <input type=\"submit\" value=\"Save\">";
   print "\n   </form>";
   print "\n</center>";

   print end_html();
   exit 0
}

#==========================================================================
# EditTemplateFile
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub EditTemplateFile
{
   my $session = shift;
   my $level = shift;
   my $template = param("TemplateFile");
   my $templatedata = param("TemplateData");
   
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"TemplateMenuSec"})
   {
      if ($level == $MAIN::Config{"ViewAllOptSec"}) { ViewOnlyMessage() }
      AdminError( "EditTemplateFile", "Not allowed to Edit");
   }

   if($template =~ /\.html$/) { }
   else { $template .= ".html" }

   if ($MAIN::CRLF == 0) {$templatedata =~ s/\r//g }

   open (TEMPLATEFILE, "> $MAIN::Config{\"TemplateDir\"}/$template") || AdminError( "EditTemplateFile", "cannot open file $template: $!");
   print TEMPLATEFILE $templatedata;
   close(TEMPLATEFILE);

   param("Message", "Template File Edited");
}

#==========================================================================
# DeleteTemplate
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub DeleteTemplate
{
   my $session = shift;
   my $level = shift;
   my $template = param("TemplateFile");

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"TemplateMenuSec"})
   {
      if ($level == $MAIN::Config{"ViewAllOptSec"}) { ViewOnlyMessage() }
      AdminError( "DeleteTemplate", "Not allowed to Delete");
   }

   if (unlink("$MAIN::Config{\"TemplateDir\"}/$template"))
   {
      param("Message", "Template File: $MAIN::Config{\"TemplateDir\"}/$template Deleted");
   }
   else
   {
      param("Message", "Template File: $MAIN::Config{\"TemplateDir\"}/$template Filed to Delete");
   }
}

#==========================================================================
# EditStaticPageForm
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub EditStaticPageForm
{
   my $session = shift;
   my $level = shift;
   my $StaticPage = param("StaticPage");
   my $html;
   
   if(defined($StaticPage)) 
   { 
      $html = ReadTemplate($StaticPage, $MAIN::Config{"StaticDir"})
   }
   
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"StaticPageMenuSec"} && $level < $MAIN::Config{"ViewAllOptSec"})
   {
      AdminError( "EditStaticPageForm", "Not allowed to Edit");
   }

   print start_html("Edit Static Page");
   print "\n<center>";
   print "\n   <h1>Edit Static Page<br><em>$StaticPage</em></h1>";
   print "\n   <form method=\"post\" enctype=\"application/x-www-form-urlencoded\">";
   print "\n      <input type=\"hidden\" name=\"Operation\" value=\"EditStaticPageFile\">";
   print "\n      <input type=\"hidden\" name=\"Session\" value=\"$session\">";
   if ($StaticPage)
   {
      print "\n      <input type=\"hidden\" name=\"StaticPage\" value=\"$StaticPage\"}\">";
   }
   print "\n      <table border=\"0\">";
   if ($StaticPage eq "")
   {
      print "\n         <tr>";
      print "\n            <td align=\"right\" valign=\"top\">StaticPage Name:</td>";
      print "\n            <td><input type=\"text\" name=\"StaticPageFile\" ></td>";
      print "\n         </tr>";
   }
   print "\n         <tr>";
   print "\n            <td align=\"right\" valign=\"top\">Contents:</td>";
   print "\n            <td><textarea name=\"StaticPageData\" rows=\"30\" cols=\"72\">$html</textarea></td>";
   print "\n         </tr>";
   print "\n      </table>";
   print "\n      <input type=\"submit\" value=\"Save\">";
   print "\n   </form>";
   print "\n</center>";

   print end_html();
   exit 0
}

#==========================================================================
# EditStaticPageFile
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub EditStaticPageFile
{
   my $session = shift;
   my $level = shift;
   my $StaticPage = param("StaticPage");
   my $StaticPagedata = param("StaticPageData");
   
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"StaticPageMenuSec"})
   {
      if ($level == $MAIN::Config{"ViewAllOptSec"}) { ViewOnlyMessage() }
      AdminError( "EditStaticPageFile", "Not allowed to Edit");
   }

   if($StaticPage =~ /\.html$/) { }
   else { $StaticPage .= ".html" }

   if ($MAIN::CRLF == 0) {$StaticPagedata =~ s/\r//g }

   open (STATICPAGEFILE, "> $MAIN::Config{\"StaticDir\"}/$StaticPage") || AdminError( "EditStaticPageFile", "cannot open file $StaticPage: $!");
   print STATICPAGEFILE $StaticPagedata;
   close(STATICPAGEFILE);

   param("Message", "StaticPage File Edited");
}

#==========================================================================
# DeleteStaticPage
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub DeleteStaticPage
{
   my $session = shift;
   my $level = shift;
   my $StaticPage = param("StaticPage");

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"StaticPageMenuSec"})
   {
      if ($level == $MAIN::Config{"ViewAllOptSec"}) { ViewOnlyMessage() }
      AdminError( "DeleteStaticPage", "Not allowed to Delete");
   }

   if (unlink("$MAIN::Config{\"StaticDir\"}/$StaticPage"))
   {
      param("Message", "Static Page: $MAIN::Config{\"StaticDir\"}/$StaticPage Deleted");
   }
   else 
   {
      param("Message", "File: $MAIN::Config{\"StaticDir\"}/$StaticPage Failed to delete");
   }
}


#==========================================================================
# DeleteImage
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub DeleteImage
{
   my $session = shift;
   my $level = shift;
   my $Image = param("ImageFile");

   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   # REPLACE WITH USER SECURITY
   if ($level < $MAIN::Config{"ImageMenuSec"})
   {
      if ($level == $MAIN::Config{"ViewAllOptSec"}) { ViewOnlyMessage() }
      AdminError( "DeleteImage", "Not allowed to Delete");
   }

   if (unlink("$MAIN::Config{\"ImageDir\"}/$Image"))
   {
      param("Message", "Image File: $MAIN::Config{\"ImageDir\"}/$Image Deleted");
   }
   else
   {
      param("Message", "Image File: $MAIN::Config{\"ImageDir\"}/$Image Filed to Delete");
   }

   param("Message", "Image File Deleted");
}

#==========================================================================
# 
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub ProcessBacklink
{
   my $backlink = shift;
   my $message = shift;
   my @pairs;
   my $param;
   my $value;
   $backlink =~ s/.+?\?//;
   @pairs = split('&',$backlink);
   foreach (@pairs) 
   {
      ($param,$value) = split('=');
      $param = CGI::unescape($param);
      $value = CGI::unescape($value);
      param($param, $value);
   }
   if ($message ne "") { param("Message", $message) }
   OperationMode();
}

#print header(). start_html();

#ProcessBacklink("http://paul/cgi-bin/FlexSearch.pl?Operation=TemplateProcess&amp;TemplateFile=car.html&amp;DataFile=cars.dat&amp;Record_Number=1");

#==========================================================================
# 
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub UserEditTable
{
   my $session = shift;
   my $level = shift;
   my $html;
   my @record;
   my $escuser;
   my $cnt=1;
   
   if ($level < $MAIN::Config{"UserMaintSec"})
   {
      if ($level == $MAIN::Config{"ViewAllOptSec"}) { ViewOnlyMessage() }
      AdminError("UserEditTable", "Not allowed to edit users");
   }

   # build html
   $html .= start_html("User Maintenance");
   $html = MessageCheck($html);
   $html .= "\n<div align=\"center\"><center><h1>User Maintenance</h1><table border=\"1\">";
   $html .= "\n  <tr><th>Options</th><th>User</th><th>Level</th></tr>";
   
   # locate records
   open (USERS, "< $MAIN::UsersFile") || AdminError( "UserEditTable", "cannot open Users file");
   $_=<USERS>;
   while (defined($_=<USERS>))
   {
      StripRecord;
      @record = split /\t/;
      if ((defined($record[0])) && ($record[2] <= $level)) 
      { 
         $escuser = CGI::escape($record[0]);

         $html .= "\n  <tr><td>";
         $html .= "<a href=\"" . url() . "?Operation=UserEditForm&Session=$session&Record_Number=$cnt\">Edit</a> ";
         $html .= "<a href=\"" . url() . "?Operation=DeleteUser&Session=$session&Record_Number=$cnt\">Delete</a> ";
         $html .= "</td><td>$record[0]</td><td>$record[2]</td></tr>";
      }
      $cnt++;
   }
   close (USERS);

   $html .= "\n</table>";
   $html .= "\n<a href=\"" . url() . "?Operation=UserEditForm&Session=$session&Record_Number=-1\">Add New User</a> ";
   $html .= "\n</center></div>";
   $html .= "\n" . MenuButton($session, "Main Menu", "MainMenu");
   $html .= end_html();
   return $html;
}

#==========================================================================
# UserEditForm
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub UserEditForm
{
   my $session = shift;
   my $level = shift;
   my $html;
   my %user;
   my $rec;
   my $decoded;
   my @decoded;

   if ($level < $MAIN::Config{"UserMaintSec"})
   {
      AdminError("UserEditForm", "Not allowed to edit users");
   }

   $rec = param("Record_Number");
   if ($rec == 0)
   {
      AdminError("UserEditForm", "Not allowed to edit user 0");
   }
   if ($rec != -1) { ReadRecordHash(\%user, $MAIN::UsersFile, $rec, ".") }

   if ($level < $user{"Level"})
   {
      AdminError("UserEditForm", "Not allowed to edit users with higher security");
   }

   if ($user{"Password"})
   {
      $decoded = MIME::Base64::decode($user{"Password"});
      @decoded = split("\t", $decoded);
   }

   $html .= start_html("User Editor");
   $html = MessageCheck($html);
   $html .= "\n<div align=\"center\"><center><h1>User Editor</h1>";
   $html .= "\n  <form method=\"post\">";
   $html .= "\n    <input type=\"hidden\" name=\"Operation\" value=\"UserEdit\">";
   $html .= "\n    <input type=\"hidden\" name=\"Session\" value=\"$session\">";
   $html .= "\n    <input type=\"hidden\" name=\"Record_Number\" value=\"$rec\">";
   $html .= "\n    <table border=\"0\">";
   $html .= "\n      <tr><th>Field</th><th>Value</th></tr>";
   $html .= "\n      <tr><td align=\"right\">User:</td><td><input type=\"text\" name=\"User\" value=\"$user{'User'}\"></td></tr>";
   $html .= "\n      <tr><td align=\"right\">Password:</td><td><input type=\"password\" name=\"Password\" value=\"$decoded[1]\"></td></tr>";
   $html .= "\n      <tr><td align=\"right\">Level:</td><td><input type=\"text\" name=\"Level\" value=\"$user{'Level'}\"></td></tr>";
   $html .= "\n    </table><input type=\"submit\" value=\"Save\">";
   $html .= "\n    <input type=\"button\" value=\"Back\" OnClick=\"history.back()\">";
   $html .= "\n  </form>";
   $html .= "\n</center></div>";
   $html .= end_html();
   return $html
}

#==========================================================================
# DeleteUser
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub DeleteUser
{
   my $session = shift;
   my $level = shift;
   my $rec;
   my %user;
   my @names;

   if ($level < $MAIN::Config{"UserMaintSec"})
   {
      AdminError("UserEditForm", "Not allowed to edit users");
   }

   $rec = param("Record_Number");
   if ($rec == 0)
   {
      AdminError("UserEditForm", "Not allowed to edit user 0");
   }
   if ($rec != -1) { ReadRecordHash(\%user, $MAIN::UsersFile, $rec, ".") }

   if ($level < $user{"Level"})
   {
      AdminError("UserEditForm", "Not allowed to edit users with higher security");
   }

   DeleteRecord ($MAIN::UsersFile, param("Record_Number"), 0, ".");

   # update Indexes
   CreateAllIndexes($MAIN::UsersFile, ".");

   param ("Message", "User Deleted");
   print UserEditTable($session, $level);
   exit 0;

}


#==========================================================================
# UserEdit
#==========================================================================
# 
# Purpose:    
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub UserEdit
{
   my $session = shift;
   my $level = shift;
   my %user;
   my %user_old;
   my $rec;
   my $password;
   my @names;

   if ($level < $MAIN::Config{"UserMaintSec"})
   {
      AdminError("UserEditForm", "Not allowed to edit users");
   }

   $rec = param("Record_Number");
   if ($rec == 0)
   {
      AdminError("UserEditForm", "Not allowed to edit user 0");
   }
   $rec = ReadRecordHash(\%user, $MAIN::UsersFile, $rec, ".");

   %user_old = %user;

   $password = param("Password");
   $user{"User"} = param("User");
   $user{"Level"} = param("Level");

   if ($level < $user{"Level"})
   {
      param ("Message", "Users level must be lower than or equal to $level");
      print UserEditForm($session, $level);
      exit 0;
   }

   $user{"Password"} = MIME::Base64::encode("$user{'User'}\t$password");
   chomp($user{"Password"});

   WriteRecordHash (\%user, $MAIN::UsersFile, $rec, ".");

   # update Indexes
   @names = ("User*", "Level*#");

   foreach (@names)
   {
      my $wrk = $_;
      $wrk =~ s/\*[\$# ]*?$//;
      if($user{$wrk} ne $user_old{$wrk})
      {
         IndexUpdate ($MAIN::UsersFile, $wrk, $rec, $user_old{$wrk}, $user{$wrk}, ".");
      }
   }

   param ("Message", "User Updated");
   print UserEditTable($session, $level);

}


#==========================================================================
# 
#==========================================================================
# 
# Purpose:    Return a path spec changing directiory from FS path to web Path
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub WebRootFix
{
   my $test=shift;
   $test =~ s/$MAIN::Config{"RootDir"}//;
   return $test;
}

#==========================================================================
# ViewOnlyMessage
#==========================================================================
# 
# Purpose:    Output a polite message that the user has tried an operation 
#                that their security does not allow.
#             
# Algorithm:  
#             
# Notes:      
#             
# Format:     
#             
#--------------------------------------------------------------------------
sub ViewOnlyMessage
{
   print start_html("Flex  Guest Error");
   print "\n<center><h1>Guest Notice</h1>";
   print "\nYou are Currently Logged on as a guest.<br>";
   print "\nYou are not allowed to make changes.<br><br>";
   print "\n   <form>";
   print "\n      <input type=\"button\" value=\"Back\" OnClick=\"history.back()\">";
   print "\n   </form>";
   print "\n</center>";
   print end_html();
   exit 0;
}

#==========================================================================
# SearchOperation
#==========================================================================
# 
# Purpose:    This is the procedure that process the search operation
#             
# Algorithm:  while search fields
#                if range not empty
#                   replace low and high with range 
#                if low or high and low != any
#                   while low contains items
#                      lookup records and add to list
#                   merge records to master list
#                if result contains data save to holder
#             if result empty and softsearch
#                restore last partial result (holder)
#             if result empty 
#                output no record template
#             if result one record
#                output single record template
#             else 
#                output multi record template
#
# Notes:      Add ability to do suppress or other on 'softsearch' necessary
#
# Format:     SearchOperation();
#             
#--------------------------------------------------------------------------
sub SearchOperation
{
   push(@MAIN::CallStack, "SearchOperation");
   my $session = shift;
   my @reclist;
   my $search;
   my $idx = 1;
   my $idx1;
   my $template;
   my $datafile = param("DataFile");

   if (!defined($datafile))
   {
      AdminError( "SearchOperation", "No DataFile Specified");
   }

	my ($searchData, $searchString) = buildSearchData();

   Search($datafile, $searchData, \@reclist, param("SoftSearch"));

   # if result list empty
   if ($#reclist == -1)

   {
      # output no record page
      if ((($template = param("NoRecordTemplate")) eq "Default") || !defined($template))
         { print DefaultNoRecordPage(); }
      else
         { print ReadTemplate($template); }
   }
   else
   {
      # if one record in list
      if ($#reclist == 0)
      {
         # load single record template
         if ((($template = param("SingleRecordTemplate")) eq "Default") || !defined($template))
            { $template = DefaultSingleTemplate($datafile, $session); }
         else
            { $template = ReadTemplate($template); }
      }
      else
      {
         # load multi record template
         if ((($template = param("MultiRecordTemplate")) eq "Default") || !defined($template))
            { $template = DefaultMultiTemplate($datafile, $session); }
         else
            { $template = ReadTemplate($template); }
      }

      # process template
      print HTMLTemplateProcess($template, $datafile, \@reclist, $session, $searchString);

   }

   print end_html();
   pop(@MAIN::CallStack);
   exit 0;

}


#==========================================================================
# OperationMode
#==========================================================================
# 
# Purpose:    Check the operation parameter and determine what action to 
#             take,  the give priority to the most common options
#             
#--------------------------------------------------------------------------

sub OperationMode
{
   push(@MAIN::CallStack, "OperationMode");
   my $command = param("Operation");
   my $session = param("Session");
   my $user;
   my %user_record;
   my @list1;
   my $URL;
   my $rec;
   my $backlink;
   my $level;

   #print EnvDump();

   $URL = $ENV{"HTTP_REFERER"};
   $URL =~ s/http:\/\///;
   $URL = substr($URL, 0, index($URL, "/"));

   if (index($MAIN::Config{"BaseURL"}, $URL) < 0)
   {
      AdminError("FlexAdmin", "Invalid Referrer");
   }
   if ($command eq "Search")
   {
      SearchOperation();
   }
   elsif ($command eq "Login")
   {
      AuthorizeLogin();
   }
   elsif ($command eq "SendMail")
   {
      SendMail($session);
   }
   elsif ($command eq "TemplateProcess")
   {
      @list1 = param("Record_Number");
      print HTMLTemplateProcess(ReadTemplate(param("TemplateFile")), param("DataFile"), \@list1);
      print end_html();
      exit 0;
   }
   elsif ($command eq "FormMerge")
   {
      print FormMerge(ReadTemplate(param("TemplateFile")), $session);
      print end_html();
      exit 0;
   }
   # Secure Functions
   elsif ($session)
   {
      ($session, $user) = SessionManage($session);
      if ($session == 0)
      {
         #session is expired
         print start_html("Flex Administrative Login");
         print "<Center>Your Login has been timed out by the server, Please Re-enter</center></p>";
         print LoginForm($user, param("Password"));
         print TagLine();
         print end_html();
         exit 0;
      }
      $URL = self_url();
      $URL =~ s/http:\/\///;
      $URL = substr($URL, 0, index($URL, "/"));

      # find the user in the user file
      ($rec) = IndexLookup($MAIN::UsersFile, 'User', $user, "" , ".");
      ReadRecordHash (\%user_record, $MAIN::UsersFile, $rec, ".");
      $level = $user_record{'Level'};

      if ($MAIN::Config{"VerboseMaintenance"} eq "Y") { $MAIN::ShowStatus = 1; }

      if ($command eq "ConfigEdit")
      {
         ConfigEdit($session, $level);
      }

      if (index($MAIN::Config{"BaseURL"}, $URL) < 0)
      {

#print "\n base: " . $MAIN::Config{"BaseURL"} . "<br>";
#print "\n URL: $URL<br>";

         param("Message", "Invalid Refering URL License Invalid");
         print ConfigEditForm(1, $session, $level);
         exit 0;
      }

      if ($MAIN::Config{"LicenseExp"} < time())
      {
         param("Message", "License Expired");
         print ConfigEditForm($session, 0, $level);
         exit 0;
      }

      if (($MAIN::Config{"LicenseExp"} - time()) < 2678400)
      {
         param ("Message", "Your License Expires in less than 30 days!");
      }
   
      if ($command eq "MainMenu")
      {
         print MainMenu($session, $level);
         print end_html();
         exit 0;
      }

      if ($command eq "DatabaseMenu")
      {
         print DatabaseMenu($session, $level);
         print end_html();
         exit 0;
      }

         #database specific operations
         elsif ($command eq "DefaultSearchForm")
         {
            DefaultSearchForm(param("DataFile"));
         }
         elsif ($command eq "SearchEditForm")
         {
            DefaultSearchForm(param("DataFile"), $session);
         }
         elsif ($command eq "DefaultSingleTemplate")
         {
            print DefaultSingleTemplate(param("DataFile"));
            print end_html();
            exit 0;
         }
         elsif ($command eq "DefaultMultiTemplate")
         {
            print DefaultMultiTemplate(param("DataFile"));
            print end_html();
            exit 0;
         }
         elsif ($command eq "DefaultEditTemplate")
         {
            print DefaultSingleTemplate(param("DataFile"), $session);
            print end_html();
            exit 0;
         }
         elsif ($command eq "DefaultRecordManagerTemplate")
         {
            print DefaultMultiTemplate(param("DataFile"), $session);
            print end_html();
            exit 0;
         }
         if ($command eq "EditSearch")
         {
            SearchOperation($session);
         }
         if ($command eq "Edit")
         {
            EditRecord($session, $level);
            if ($backlink = param("BackLink")) 
            {
               ProcessBacklink($backlink, "Record Updated Successfully");
            }
            else 
            {
               # no back link return to database menu
               print DatabaseMenu($session, $level);
            }

            exit 0;

         }
         if ($command eq "DeleteDataRecord")
         {
            DeleteDataRecord($session, $level);
            if ($backlink = param("BackLink")) 
            {
               ProcessBacklink($backlink, "Record Deleted<br>DataFile Reindexed");
            }
            else 
            {
               # no back link return to database menu
               print DatabaseMenu($session, $level);
            }

            exit 0;

         }
         elsif ($command eq "AddDataRecord")
         {
            $list1[0] = -1;
            print HTMLTemplateProcess(DefaultSingleTemplate(param("DataFile"), $session),
               param("DataFile"), \@list1, $session);
            print end_html();
            exit 0;
         }
         elsif ($command eq "EditFieldNames")
         {
            $list1[0] = 0;
            print HTMLTemplateProcess(DefaultSingleTemplate(param("DataFile"), $session),
               param("DataFile"), \@list1, $session);
            print end_html();
            exit 0;
         }
         elsif ($command eq "EditFileConfig")
         {

         }
         elsif ($command eq "DeleteDataFile")
         {
            DeleteDataFile($session, $level);
            print DatabaseMenu($session, $level);
            exit 0;
         }
         elsif ($command eq "RepairDataFile")
         {
            RepairDataFile($session, $level);
            print DatabaseMenu($session, $level);
            exit 0;
         }

         # General database operations
         elsif ($command eq "UploadDataForm")
         {
            UploadDataForm($session, $level);
         }
         elsif ($command eq "UploadDataFile")
         {
            UploadDataFile($session, $level);
            print DatabaseMenu($session, $level);
            exit 0;
         }
         elsif ($command eq "CreateDataForm")
         {

         }
         elsif ($command eq "CreateDataFile")
         {

         }

      elsif (($command eq "TemplateMenu"))
      {
         print TemplateMenu($session, $level);
         print end_html();
         exit 0;
      }
         # template specific
         elsif ($command eq "ViewTemplate")
         {
            print ReadTemplate(param("TemplateFile"));
            exit 0;
         }
         elsif ($command eq "EditTemplateForm")
         {
            EditTemplateForm($session, $level);
         }
         elsif ($command eq "EditTemplateFile")
         {
            EditTemplateFile($session, $level);
            print TemplateMenu($session, $level);
            exit 0
         }
         elsif ($command eq "DeleteTemplate")
         {
            DeleteTemplate($session, $level);
            print TemplateMenu($session, $level);
            exit 0;
         }

         #general Template
         elsif ($command eq "UploadTemplateForm")
         {
            UploadTemplateForm($session, $level);
         }
         elsif ($command eq "UploadTemplateFile")
         {
            UploadTemplateFile($session, $level);
         }
         elsif ($command eq "CreateTemplateForm")
         {
            EditTemplateForm($session, $level);
         }

      elsif (($command eq "StaticPageMenu"))
      {
         print StaticPageMenu($session, $level);
         print end_html();
         exit 0;
      }
         # StaticPage specific
         elsif ($command eq "EditStaticPageForm")
         {
            EditStaticPageForm($session, $level);
         }
         elsif ($command eq "EditStaticPageFile")
         {
            EditStaticPageFile($session, $level);
            print StaticPageMenu($session, $level);
            exit 0
         }
         elsif ($command eq "DeleteStaticPage")
         {
            DeleteStaticPage($session, $level);
            print StaticPageMenu($session, $level);
            exit 0;
         }

         #general StaticPage
         elsif ($command eq "UploadStaticPageForm")
         {
            UploadStaticPageForm($session, $level);
            print StaticPageMenu($session, $level);
            exit 0;
         }
         elsif ($command eq "UploadStaticPage")
         {
            UploadStaticPage($session, $level);
         }
         elsif ($command eq "CreateStaticPageForm")
         {
            EditStaticPageForm($session, $level);
         }

      elsif (($command eq "ImageMenu"))
      {
         print ImageMenu($session, $level);
         print end_html();
         exit 0;
      }
         # Image specific
         elsif ($command eq "DeleteImage")
         {
            DeleteImage($session, $level);
            print ImageMenu($session, $level);
            exit 0;
         }
         elsif ($command eq "UploadImageForm")
         {
            UploadImageForm($session, $level);
         }
         elsif ($command eq "UploadImage")
         {
            UploadImage($session, $level);
            print ImageMenu($session, $level);
            exit 0;
         }

      elsif ($command eq "UserEditTable" )
      {
         print UserEditTable($session, $level);
         exit 0;
      }
      elsif ($command eq "UserEditForm" )
      {
         print UserEditForm($session, $level);
         exit 0;
      }
      elsif ($command eq "UserEdit" )
      {
         UserEdit($session, $level);
         exit 0;
      }
      elsif ($command eq "DeleteUser" )
      {
         DeleteUser($session, $level);
      }

      elsif ($command eq "ConfigEditForm" )
      {
         print ConfigEditForm($session, 0, $level);
         exit 0;
      }
   }
   else 
   {
      print start_html("Flex Administrative Operation Failed");
      print "\n<h1>Flex Administrative Operation Failed</h1>";
      print h1("Operation \"$command\" is unknown");
   }

}



#==========================================================================
# open window script
#==========================================================================
# 
# Purpose:    Just a copy from elseware
#             
#--------------------------------------------------------------------------
#<SCRIPT>
#window.open("remotind.htm","newwindow","toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=290,height=370");
#</SCRIPT>

#start the CGI reply

if ($ENV{"CONTENT_LENGTH"} > 20000) { $MAIN::ShowStatus = 1; }

#print start_html();
#print "\ncontent_length:" . param("CONTENT_LENGTH") . "| > 20000:" . (param("CONTENT_LENGTH") > 20000) . "|<br>";

AdminTest();

#print EnvDump();


OperationMode();

#if we get here the operation did not complete


print EnvDump();

print dump();

print end_html();

