#!/usr/bin/perl
#

use strict;
use File::Basename;
use CGI qw(:standard);
use WWW::Curl::Easy;
use LWP::UserAgent;
use HTTP::Request::Common qw(POST); 
use Crypt::Blowfish;

my $Version = "1.0-5";

my $imageLOC = "/images/PTZ";

# if you leave the key blank we'll try to generate a unique key based on
# the system, if that fails or generates a weak key you will be notified
# if that happens or you chose to enter your own key it needs to be a 
# minimum of 8 charcters and can be a maximum of 56 characters - if you
# enter less then 16 character it will be considered a weak key and you
# will be notified of that - if you enter more then 56 character it will 
# be truncated to 56 characters - the key is used to encrypt and remember 
# the password between operations
my $key = "";

my $CMD = basename($0);
my $DocRoot = $ENV{'DOCUMENT_ROOT'};
my $HTTPhost = $ENV{'HTTP_HOST'};

my $URL = "";
my $USER = "";
my $PASS = "";
my $newPASS = "";

my $true = 1;
my $false = 0;

my $SpeedSync = $true;
my $verbose = $false;

my $keyMaxLen = 56;	# blowfish don't like keys bigger then this
my $weakKey = $false;
my $badKey = $false;
my $keyLen;
($key ne "") && (length($key) != ($keyLen = int(length($key)/8) * 8)) && ($key = substr($key,0,$keyLen)); 
($key ne "") && ($keyLen > $keyMaxLen) && ($key = substr($key,0,$keyMaxLen));
($key ne "") && (checkKey($key));

$URL = param("URL");
$URL =~ s/http:\/\///;
$URL =~ s/\/+$//;

my $AuthReq = param("authReq");
if ($AuthReq ne "") {
    $USER = param("user");
    $PASS = param("pass");
    ($key eq"") && ($key = genKey());

    $newPASS = param("newPass");
    if ($URL ne "" && $USER ne "" && $PASS ne "" && $newPASS eq "") {
        my $cipher = Crypt::Blowfish->new($key);
        my $Pos = 0;
        my $PT = "";
        my $cryptPASS = "";
        while ($Pos < length($PASS)) {
            $cryptPASS = substr($PASS, $Pos, 8);
            $cryptPASS = $cipher->decrypt($cryptPASS);
            $PT .= $cryptPASS;
            $Pos += 8;
        }
        $PASS = $PT;
        $PASS =~ s/\0//g;
    }
    if ($newPASS ne "") { $PASS = $newPASS; }
}

my $Form = param("form");

my $Up = "";
my $Left = "";
my $Home = "";
my $Right = "";
my $Down = "";

my $Plus = "";
my $Zoom = "";
my $Minus = "";

my $Pan = "";
my $Stop = "";
my $Patrol = "";


my $NewPanSpeed = "";
my $NewTiltSpeed = "";
my $NewZoomSpeed = "";
my $NewAutoSpeed = "";

my $PresetList = "";
my @PresetList = ();
my $PatrolList = "";
my @PatrolList = ();

my $StatusWindow = param("status");

my $HTTPreply = "";

if ($URL ne "" && ($AuthReq eq "" || ($USER ne "" && $PASS ne ""))) {
    $Up = param("up");
    $Left = param("left");
    $Home = param("home");
    $Right = param("right");
    $Down = param("down");

    $Plus = param("plus");
    $Zoom = param("zoom");
    $Minus = param("minus");

    $Pan = param("pan");
    $Stop = param("stop");
    $Patrol = param("patrol");

    $PresetList = param("presetList");
    $PatrolList = param("patrolList");

    $NewPanSpeed = param("panSpeed");
    $NewTiltSpeed = param("tiltSpeed");
    $NewZoomSpeed = param("zoomSpeed");
    $NewAutoSpeed = param("autoSpeed");
}

sub filterKey {
    my ($Key) = @_;
    $Key =~ s/\n|\s+|-|:|\.|\///g;
    return $Key;
}

sub checkKey {
    my ($key) = @_;
    (length($key) < 16) && ($weakKey = $true);
    ($key eq "") && ($badKey = $true);
}

sub genKey {
    # try and generated a machine specific unique key as best we can
    my $code = "";
    my $md5;
    (`which md5sum 2>/dev/null` ne "") && ($md5 = 1) || ($md5 = 0);
    (`hostid 2>/dev/null` ne "") && ($code .= `hostid 2>/dev/null`);
    ((length($code = filterKey($code)) < $keyMaxLen) || ($md5)) && ($code .= $ENV{'REMOTE_ADDR'} . $ENV{'SERVER_ADDR'} . $ENV{'SSL_SERVER_M_SERIAL'});
    my @data = `ifconfig 2>&1`;
    @data = grep (/\s+(HWaddr|inet6 addr)/, @data);
    foreach (@data) { if (((length($code = filterKey($code)) < $keyMaxLen) || $md5) && /(HWaddr|inet6 addr:)(\s+|.*?)(..:..:..:..:..:..|.+::.+:.+:.+:.+?\/)/) { $code .= $3; } }
    ((length($code = filterKey($code)) < $keyMaxLen) || ($md5)) && (`cat /proc/version 2>/dev/null` ne "") && ($md5) && ($code .= `cat /proc/version 2>/dev/null | md5sum`);
    ((length($code = filterKey($code)) < $keyMaxLen) || ($md5)) && (`uname -a 2>/dev/null` ne "") && ($md5) && ($code .= `uname -a 2>/dev/null | md5sum`);
    if ($URL ne "" && $USER ne "") {
        while (length($code) < $keyMaxLen) {
            $code = filterKey("$code$URL$USER");
        }
    }
#    my $keyLen = int(length($key)/8) * 8;
    (! $md5) && ($code = substr($code,0,$keyMaxLen));
    (($code= filterKey($code)) ne "") && ($md5) && ($code = filterKey(`echo "$code" | md5sum`));
    checkKey($code);
    return $code;
}

sub buildList {
    my ($PREFIX, $Start, $End, $Presets) = @_;

    my @Names;
    ($Presets) && (@Names = ("name", "pan", "tilt", "zoom")) || (@Names = ("name", "dwelling"));
    my $Name;
    my $List = "";
    my $Count;
    for ($Count = $Start; $Count <= $End; $Count++) {
        foreach $Name (@Names) {
            $List = sprintf("%s%s%i_%s&", $List, $PREFIX, $Count, $Name);
        }
    }
    $List =~ s/&$//;
    return $List;
}

sub parseList {
    my ($LIST, $PREFIX, $Start, $End, $Presets) = @_;

    my @Names;
    ($Presets) && (@Names = ("name", "pan", "tilt", "zoom")) || (@Names = ("name", "dwelling"));
    my $Name;
    my @List = ();
    my $Param;
    my $Search;
    my $Value;
    my $Count;
    my $GotName;
    for ($Count = $Start; $Count <= $End; $Count++) {
        $GotName = $false;
        $Value = "$Count";
        foreach $Name (@Names) {
            $Param = sprintf("%s%i_%s=", $PREFIX, $Count, $Name);
            $LIST =~ /$Param'(.*)'/;
            $Search = $1;
            $Value = "$Value\_$Name=$Search";
            if ($Name eq "name" && $Search ne "") { $GotName = $true; }
        }
        if ($GotName) { push @List, $Value; }
    }
    return @List;
}

sub getPresets {
    if ($URL ne "" && ($AuthReq eq "" || ($USER ne "" && $PASS ne ""))) {
        my $PresetList = buildList("camctrl_c0_preset_i",0,19,$true);
        my $SaveQuery = camQuery($PresetList);
        my @PresetList = parseList($SaveQuery, "camctrl_c0_preset_i",0,19,$true);
        return @PresetList;
    }
}

sub getPatrol {
    if ($URL ne "" && ($AuthReq eq "" || ($USER ne "" && $PASS ne ""))) {
        my $PatrolList = buildList("camctrl_c0_patrol_i",0,39,$false);
        my $SaveQuery = camQuery($PatrolList);
    }
}

sub go2Preset {
    my ($Preset) = @_;

    $Preset =~ /\_name=(.*?)\_/;
    my $PickedName = $1;

    my $ua = LWP::UserAgent->new;
    $ua->agent("Mozilla 8.0 blah...");

    my $request = (POST "http://$USER:$PASS\@$URL/cgi-bin/camctrl/recall.cgi", ["presetname" => "$PickedName","recall" => "$PickedName"]);

    my $response_code = $ua->request($request);
    my $response_body = $request->content;
    $HTTPreply = sprintf("%s%s<br>%s<br>%s<br><br>", $HTTPreply, $request, $response_code, $response_body);
}

sub PTZspeeds {
    if ($URL ne "" && ($AuthReq eq "" || ($USER ne "" && $PASS ne ""))) {
        my $SaveQuery = camQuery("camctrl_c0_panspeed&camctrl_c0_tiltspeed&camctrl_c0_zoomspeed&camctrl_c0_autospeed");
        my $Query = $SaveQuery;
        $Query =~ /camctrl_c0_panspeed='(.*)'/;
        my $PanSpeed = $1;
        $Query = $SaveQuery;
        $Query =~ /camctrl_c0_tiltspeed='(.*)'/;
        my $TiltSpeed = $1;
        $Query = $SaveQuery;
        $Query =~ /camctrl_c0_zoomspeed='(.*)'/;
        my $ZoomSpeed = $1;
        $Query = $SaveQuery;
        $Query =~ /camctrl_c0_autospeed='(.*)'/;
        my $AutoSpeed = $1;
        return $PanSpeed, $TiltSpeed, $ZoomSpeed, $AutoSpeed;
    } else {
        return "", "", "", "";
    }
}

(my $PanSpeed, my $TiltSpeed, my $ZoomSpeed, my $AutoSpeed) = PTZspeeds;

sub camControl {
    my ($OPT) = @_;

    my $COMMAND = "/cgi-bin/camctrl/camctrl.cgi?$OPT";
    my $RC = sendCommand($COMMAND);
    return $RC;
}

sub camQuery {
    my ($OPT) = @_;

    my $COMMAND = "/cgi-bin/viewer/getparam.cgi?$OPT";
    my $RC = sendCommand($COMMAND);
    return $RC;
}

sub sendCommand {
    my ($OPT) = @_;

    my $RC = "";
    if ($URL eq "") { return "Missing URL"; }
    if ($AuthReq ne "" && ($USER eq "" || $PASS eq "")) { return "Missing credentials"; }
    my $COMMAND;
    if ($AuthReq eq "") {
        $COMMAND = "http://$URL$OPT";
    } else {
        $COMMAND = "http://$USER:$PASS\@$URL$OPT";
    }
$HTTPreply = "$HTTPreply<br>URL: $COMMAND<br>";

    my $curl = new WWW::Curl::Easy;
                               
    $curl->setopt(CURLOPT_HEADER,1);
    $curl->setopt(CURLOPT_URL, $COMMAND);

    my $response_body = "";
    open (my $fileb, ">", \$response_body);
    $curl->setopt(CURLOPT_WRITEDATA, $fileb);

    my $retcode = $curl->perform;
    my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
    $HTTPreply = sprintf("%s%s<br>%s<br>%s<br>%s<br><br>", $HTTPreply, $response_code, $curl->strerror($retcode), $retcode, $response_body);
    if ($retcode == 0 && $response_code == 200) {
        $RC = $response_body;
        $RC =~ s/HTTP\/.* 200//;
        $RC =~ s/\r//g;
        chomp($RC);
        if ($verbose) {
            $RC = "$OPT: $RC";
        }
        close($fileb);
    } else {
        $RC = sprintf("%s %s %s",  $response_code, $curl->strerror($retcode), $retcode);
        close($fileb);
    }
    chomp($RC);
    return $RC;
}

my $Command;
my $Message = "";

if ($URL ne "" && ($AuthReq eq "" || ($USER ne "" && $PASS ne ""))) {
    if ($Form eq "move") {
        if ($Up ne "") { $Command = camControl("move=up"); }
        if ($Left ne "") { $Command = camControl("move=left"); }
        if ($Home ne "") { $Command = camControl("move=home"); }
        if ($Right ne "") { $Command = camControl("move=right"); }
        if ($Down ne "") { $Command = camControl("move=down"); }

        if ($Pan ne "") { $Command = camControl("auto=pan"); }
        if ($Stop ne "") { $Command = camControl("auto=stop"); }
        if ($Patrol ne "") { $Command = camControl("auto=patrol"); }

        if ($Plus ne "") { $Command = camControl("zoom=tele"); }
        if ($Minus ne "") { $Command = camControl("zoom=wide"); }

        if ($PresetList ne "" && $PresetList !~ /clear|get|pick|edit/) { $PresetList = "pick"; }
    }

    if ($Form eq "speed") {
        if ($NewPanSpeed ne "" && $NewPanSpeed != $PanSpeed) { 
            $Command = camControl("speedpan=$NewPanSpeed");
            $Message = "CPS $PanSpeed NPS $NewPanSpeed";
        }
        if ($NewTiltSpeed ne "" && $NewTiltSpeed != $TiltSpeed) {
            $Command = camControl("speedtilt=$NewTiltSpeed");
            $Message = "$Message CTS $TiltSpeed NTS $NewTiltSpeed";
        }
        if ($NewZoomSpeed ne "" && $NewZoomSpeed != $ZoomSpeed) {
            $Command = camControl("speedzoom=$NewZoomSpeed");
            $Message = "$Message CZS $ZoomSpeed NZS $NewZoomSpeed";
        }
        if ($NewAutoSpeed ne "" && $NewAutoSpeed != $AutoSpeed) {
            $Command = camControl("speedapp=$NewAutoSpeed");
            $Message = "$Message CAS $AutoSpeed NAS $NewAutoSpeed";
        }
        if ($SpeedSync) {
            my $waitCnt = 1;
            my $speedTot = $NewPanSpeed + $NewTiltSpeed + $NewZoomSpeed + $NewAutoSpeed;
            while ($waitCnt <= 5 && $speedTot != ($PanSpeed + $TiltSpeed + $ZoomSpeed + $AutoSpeed)) {
                sleep 1;
                ($PanSpeed, $TiltSpeed, $ZoomSpeed, $AutoSpeed) = PTZspeeds;
                $waitCnt++;
            }
        }
    }
    if ($PresetList ne "" && $PresetList ne "clear") { @PresetList = getPresets(); }
    if ($Form eq "presets") {
#$HTTPreply = "$HTTPreply<br>PresetList $PresetList<br>";
        if ($PresetList ne "" && $PresetList !~ /clear|get|pick|edit/) { go2Preset($PresetList); }
        if ($PatrolList eq "get" || $PresetList eq "edit") { getPatrol(); }
    }
}

sub formTrailer {
    my ($Form,$Pad) = @_;

    my $cryptPASS = "";
    if ($URL ne "" && $USER ne "") {
        my $cipher = Crypt::Blowfish->new($key);
        my $Pos = 0;
        my $CP = "";
        while ($Pos < length($PASS)) {
            $cryptPASS = substr($PASS, $Pos, 8);
            $cryptPASS .= "\000"x(8-length($cryptPASS)) if length($cryptPASS) < 8;
            $cryptPASS = $cipher->encrypt($cryptPASS);
            $CP .= $cryptPASS;
            $Pos += 8;
        }
        $cryptPASS = $CP;
    }
    print "$Pad    <tr>\n$Pad      <td align=\"center\" valign=\"center\" wrap>\n        ";
    print "$Pad<input type=\"hidden\" name=\"form\" value=\"$Form\">";
    if ($Form ne "move") { print "<input type=\"hidden\" name=\"authReq\" value=\"$AuthReq\">"; }
    if ($Form ne "presets") {
        print "<input type=\"hidden\" name=\"presetList\" value=\"$PresetList\">";
        print "<input type=\"hidden\" name=\"status\" value=\"$StatusWindow\">";
    }
    print "<input type=\"hidden\" name=\"URL\" value=\"$URL\">";
    print "<input type=\"hidden\" name=\"user\" value=\"$USER\">";
    printf "<input type=\"hidden\" name=\"pass\" value=\"%s\">", $cryptPASS;
    print "\n$Pad      </td>\n$Pad    </tr>\n";
}

(my $daYear) = (localtime(time()))[5] + 1900;

sub htmlHeader {
    my ($FH,$Type,$Tag) = @_;
    print $FH "<html>\n";
    print $FH "<head>\n";
    print $FH "    <title>$URL PTZ $Type</title>\n";
    if ($Tag ne "") { print $FH "    <base target=\"$CMD $Tag\">\n"; }
    print $FH "    <meta name=\"Generator\" content=\"PTZ Control\">\n";
    print $FH "    <meta name=\"Author\"    content=\"©2010-$daYear Curtronics Curtis J Blank\">\n";
    print $FH "    <meta name=\"Copyright\" content=\"©2010-$daYear Curtronics Curtis J Blank\">\n";
    print $FH "    <meta name=\"Keywords\"  content=\"Curtronics, ZoneMinder, PTZ, Camera Contol\">\n";
}

print "Content-type: text/html\n\n";
htmlHeader(\*STDOUT,"Control");

if ($AuthReq && $badKey) {
    print "    <script>\n";
    print "        window.resizeTo(400,400);\n";
    print "    </script>\n";
    print "\n</head>\n\n";

    print "<body text=\"black\" bgcolor=\"lightblue\">\n";
    print "<center>\n";
    print <<"EOF";
<h3>Bad Encryption Key</h3>
<p>
You have enabled authenticaion but it appears 
we tried and failed to generate a suitable KEY 
based on some of your systems unique parameters 
to encrypt your password.
<br><br>
At this time we are unable to continue. Try 
entering your own unique KEY in $CMD on 
the \$key = ""; line between the double quotes.
The KEY needs to be a minimum of 8 characters
and a maximum of 56 characters.
</p>
</BODY>
</HTML>
EOF
#
    exit;
}

print "\n    <style type=\"text/css\">\n";
print "        textarea { font-weight: bold; font-size: 8pt; width: 150; height: 18; }\n";
print "        option { font-size: 8pt; height: 10; }\n";
print "        b { top: 0; font-weight: bold; font-size: 8pt; }\n";
print "        p { font-size: 8pt; }\n";
print "    </style>\n";
my $WinWidth;
my $WinHeight;
($URL eq "") && ($WinWidth = 290) || ($WinWidth = 260);
(($AuthReq) && (($URL eq "") || ($USER eq "") || ($PASS eq "")) && ($WinHeight = 550)) || ($WinHeight = 500);
print "    <script>\n";
print "      if (window.innerWidth != $WinWidth || window.innerHeight != $WinHeight) {\n";
print "        window.resizeTo($WinWidth, $WinHeight);\n";
print "      }\n";
print "    </script>\n";
if ($StatusWindow ne "") {
    print <<"EOF";
    <script>
       window.open("/$CMD-HTTPreply.html", "$CMD Status", "height=300,width=600,status=0,toolbar=0,location=0,menubar=0,directories=0,resizable=1,scrollbars=1");
    </script>
EOF
#
    ($HTTPreply eq "") && ($HTTPreply = "No communication initiated");
    open(OFILE,">$DocRoot/$CMD-HTTPreply.html");
    htmlHeader(\*OFILE,"Status","Status");
    print OFILE <<"EOF";
</HEAD>
<BODY text="black" bgcolor="white" link="black" alink="black" vlink="black">
<p>
$HTTPreply
</p>
</BODY>
</HTML>
EOF
#
    close(OFILE);
}
#
print "\n</head>\n\n";

print "<body text=\"black\" bgcolor=\"lightblue\">\n";
print "<center>\n";

print "<table cellpadding=\"\" cellspacing=\"0\" border=\"0\">\n";
print "  <form method=POST action=\"/cgi-bin/$CMD\" name=\"move\">\n";

print "    <tr>\n      <td align=\"center\" valign=\"center\" nowrap>\n";
print "        <b>Camera URL</b><br><b>http://</b>\n";
print "        <textarea name=\"URL\" cols=\"20\" rows=\"1\" onfocus=this.select()>$URL</textArea>\n";
print "      </td>\n    </tr>\n";
if ($URL eq "") {
    print "    <tr>\n      <td align=\"center\" valign=\"top\" nowrap>\n";
    print "        <b>Supports Vivotek/4XEM PZ7131/PZ7132</b>\n";
    print "      </td>\n    </tr>\n";
}

print "    <tr>\n      <td align=\"center\" valign=\"top\" nowrap>";
print "<input type=\"checkbox\" onChange=\"this.form.submit()\" name=\"authReq\" value=\"checked\" $AuthReq><b>&nbsp;Auth Required</b></input>";
print "</td>\n    </tr>\n";
if ($AuthReq) {
    if ($URL eq "" || $USER eq "") {
        print "    <tr>\n      <td align=\"center\" valign=\"center\" nowrap>\n";
        print "        <b>Username</b><br>\n";
        print "        <textarea name=\"user\" cols=\"10\" rows=\"1\" onfocus=this.select()></textArea>\n";
        print "      </td>\n    </tr>\n";
    }
    if ($URL eq "" || $PASS eq "") {
        print "    <tr>\n      <td align=\"center\" valign=\"center\" nowrap>\n";
        print "        <b>Password</b><br>\n";
        print "        <input type=\"password\" name=\"newPass\" style=\"font-weight: bold; font-size: 8pt; width: 150; height: 18;\">\n";
        print "      </td>\n    </tr>\n";
    }
    if ($weakKey) {
        print "    <tr>\n      <td align=\"center\" valign=\"center\" nowrap>\n";
        print "        <b style=\"font-weight: bold; font-size: 6pt;\">Warning: Weak Encryption Key</b>\n";
        print "      </td>\n    </tr>\n";
    }
}

print "    <tr>\n      <td align=\"center\" valign=\"center\" nowrap>\n";
print "        <table cellpadding=\"\" cellspacing=\"0\" border=\"0\">\n";

print "          <tr>\n            <td colspan=\"3\" align=\"center\" valign=\"center\" nowrap><input type=\"image\" src=\"$imageLOC/up1.gif\" name=\"up\" value=\"Up\" onmouseover=\"this.src='$imageLOC/up2.gif'\" onmouseout=\"this.src='$imageLOC/up1.gif'\"></td>\n          </tr>\n"; 

print "          <tr>\n            <td align=\"center\" valign=\"center\" nowrap><input type=\"image\" src=\"$imageLOC/left1.gif\" name=\"left\" value=\"Left\" onmouseover=\"this.src='$imageLOC/left2.gif'\" onmouseout=\"this.src='$imageLOC/left1.gif'\"></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap><input type=\"image\" src=\"$imageLOC/home1.gif\" name=\"home\" value=\"Home\" onmouseover=\"this.src='$imageLOC/home2.gif'\" onmouseout=\"this.src='$imageLOC/home1.gif'\"></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap><input type=\"image\" src=\"$imageLOC/right1.gif\" name=\"right\" value=\"Right\" onmouseover=\"this.src='$imageLOC/right2.gif'\" onmouseout=\"this.src='$imageLOC/right1.gif'\"></td>\n          </tr>\n";
print "          <tr>\n            <td colspan=\"3\" align=\"center\" valign=\"center\" nowrap><input type=\"image\" src=\"$imageLOC/down1.gif\" name=\"down\" value=\"Down\" onmouseover=\"this.src='$imageLOC/down2.gif'\" onmouseout=\"this.src='$imageLOC/down1.gif'\"></td>\n          </tr>\n";

print "        </table>\n      </td>\n    </tr>\n";
print "    <tr>\n      <td align=\"center\" valign=\"center\" nowrap>\n";
print "        <table cellpadding=\"\" cellspacing=\"0\" border=\"0\">\n";

print "          <tr>\n            <td align=\"center\" valign=\"center\" nowrap><input type=\"image\" src=\"$imageLOC/minus1.gif\" name=\"minus\" value=\"Minus\" onmouseover=\"this.src='$imageLOC/minus2.gif'\" onmouseout=\"this.src='$imageLOC/minus1.gif'\"></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap><img src=\"$imageLOC/zoom1.gif\" name=\"zoom\"></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap><input type=\"image\" src=\"$imageLOC/plus1.gif\" name=\"plus\" value=\"Plus\" onmouseover=\"this.src='$imageLOC/plus2.gif'\" onmouseout=\"this.src='$imageLOC/plus1.gif'\"></td>\n          </tr>\n";

print "        </table>\n      </td>\n    </tr>\n";
print "    <tr>\n      <td align=\"center\" valign=\"center\" nowrap>\n";
print "        <table cellpadding=\"\" cellspacing=\"0\" border=\"0\">\n";

print "          <tr>\n            <td align=\"center\" valign=\"center\" nowrap><input type=\"image\" src=\"$imageLOC/pan1.gif\" name=\"pan\" value=\"Pan\" onmouseover=\"this.src='$imageLOC/pan2.gif'\" onmouseout=\"this.src='$imageLOC/pan1.gif'\"></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap><input type=\"image\" src=\"$imageLOC/stop1.gif\" name=\"stop\" value=\"Stop\" onmouseover=\"this.src='$imageLOC/stop2.gif'\" onmouseout=\"this.src='$imageLOC/stop1.gif'\"></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap><input type=\"image\" src=\"$imageLOC/patrol1.gif\" name=\"patrol\" value=\"Patrol\" onmouseover=\"this.src='$imageLOC/patrol2.gif'\" onmouseout=\"this.src='$imageLOC/patrol1.gif'\"></td>\n          </tr>\n";

print "        </table>\n      </td>\n    </tr>\n";

formTrailer("move");
print "  </form>\n  <form method=POST action=\"/cgi-bin/$CMD\" name=\"speed\">\n";

print "    <tr>\n      <td align=\"center\" valign=\"center\" nowrap>\n";
print "        <table cellpadding=\"\" cellspacing=\"0\" border=\"0\">\n";

my $Speed;
# Pan Speed
print "          <tr>\n            <td align=\"left\" valign=\"center\" nowrap><b>Pan Speed</b></td>\n";
print "            <td align=\"left\" valign=\"center\" nowrap><b>&nbsp;</b></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap>\n              <select name=\"panSpeed\" style=\"font-weight: bold; font-size: 8pt;\" onChange=\"this.form.submit();\">\n";
if ($PanSpeed eq "") { print "                <option value=\"\" selected></option>\n"; }
$Speed = -5;
while ($Speed <= 5) {
    if ($PanSpeed ne "" && $Speed == $PanSpeed) {
        print "                <option style=\"font-weight: bold; font-size: 8pt;\" value=\"$Speed\" selected>$Speed</option>\n";
    } else {
        print "                <option style=\"font-weight: normal; font-size: 8pt;\" value=\"$Speed\">$Speed</option>\n";
    }
    $Speed++;
}
print "              </select>\n            </td>\n          </tr>\n";

# Tilt Speed
print "          <tr>\n            <td align=\"left\" valign=\"center\" nowrap><b>Tilt Speed</b></td>\n";
print "            <td align=\"left\" valign=\"center\" nowrap><b>&nbsp;</b></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap>\n              <select name=\"tiltSpeed\" style=\"font-weight: bold; font-size: 8pt;\" onChange=\"this.form.submit();\">\n";
if ($TiltSpeed eq "") { print "                <option value=\"\" selected></option>\n"; }
$Speed = -5;
while ($Speed <= 5) {
    if ($TiltSpeed ne "" && $Speed == $TiltSpeed) {
        print "                <option style=\"font-weight: bold; font-size: 8pt;\" value=\"$Speed\" selected>$Speed</option>\n";
    } else {
        print "                <option style=\"font-weight: normal; font-size: 8pt;\" value=\"$Speed\">$Speed</option>\n";
    }
    $Speed++;
}
print "              </select>\n            </td>\n          </tr>\n";

# Zoom Speed
print "          <tr>\n            <td align=\"left\" valign=\"center\" nowrap><b>Zoom Speed</b></td>\n";
print "            <td align=\"left\" valign=\"center\" nowrap><b>&nbsp;</b></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap>\n              <select name=\"zoomSpeed\" style=\"font-weight: bold; font-size: 8pt;\" onChange=\"this.form.submit();\">\n";
if ($ZoomSpeed eq "") { print "                <option value=\"\" selected></option>\n"; }
$Speed = -5;
while ($Speed <= 5) {
    if ($ZoomSpeed ne "" && $Speed == $ZoomSpeed) {
        print "                <option style=\"font-weight: bold; font-size: 8pt;\" value=\"$Speed\" selected>$Speed</option>\n";
    } else {
        print "                <option style=\"font-weight: normal; font-size: 8pt;\" value=\"$Speed\">$Speed</option>\n";
    }
    $Speed++;
}
print "              </select>\n            </td>\n          </tr>\n";

# Auto Speed
print "          <tr>\n            <td align=\"left\" valign=\"center\" nowrap><b>Auto Speed</b></td>\n";
print "            <td align=\"left\" valign=\"center\" nowrap><b>&nbsp;</b></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap>\n              <select name=\"autoSpeed\" style=\"font-weight: bold; font-size: 8pt;\" onChange=\"this.form.submit();\">\n";
if ($AutoSpeed eq "") { print "                <option value=\"\" selected></option>\n"; }
$Speed = 1;
while ($Speed <= 5) {
    if ($AutoSpeed ne "" && $Speed == $AutoSpeed) {
        print "                <option style=\"font-weight: bold; font-size: 8pt;\" value=\"$Speed\" selected>$Speed</option>\n";
    } else {
        print "                <option style=\"font-weight: normal; font-size: 8pt;\" value=\"$Speed\">$Speed</option>\n";
    }
    $Speed++;
}
print "              </select>\n            </td>\n          </tr>\n";

print "        </table>\n      </td>\n    </tr>\n";

my $Pad = "      ";
formTrailer("speed");
print "  </form>\n  <form method=POST action=\"/cgi-bin/$CMD\" name=\"presets\">\n";

print "    <tr>\n      <td align=\"center\" valign=\"center\" nowrap>\n";
print "        <table cellpadding=\"\" cellspacing=\"0\" border=\"0\">\n";

my $pList;
my @pList;
my @pName;
my $PickedName;
my $fWeight = "normal";
# Presets
if ($PresetList ne "" && $PresetList ne "get" && $PresetList ne "pick" && $PresetList ne "clear") { $fWeight = "bold"; }
print "          <tr>\n            <td align=\"left\" valign=\"center\" nowrap><b>Presets</b></td>\n";
print "            <td align=\"left\" valign=\"center\" nowrap><b>&nbsp;</b></td>\n";
print "            <td align=\"center\" valign=\"center\" nowrap>\n              <select name=\"presetList\" style=\"font-weight: $fWeight; font-size: 8pt;\" onChange=\"this.form.submit();\">\n";
if ($#PresetList < 0) {
    print "                <option style=\"font-weight: normal; font-size: 8pt;\" value=\"\" selected></option>\n";
} else {
    $PresetList =~ /\_name=(.*?)\_/;
    $PickedName = $1;
    if ($PickedName eq "" || $PickedName eq "pick") { print "                <option style=\"font-weight: normal; font-size: 8pt;\" value=\"pick\" selected>-- Pick --</option>\n"; }
    foreach $pList (@PresetList) {
        @pList = split /_/, $pList;
        @pName = split /=/, $pList[1];
        if ($PickedName eq $pName[1]) {
            print "                <option style=\"font-weight: bold; font-size: 8pt;\" value=\"$pList\" selected>$pName[1]</option>\n";
        } else {
            print "                <option style=\"font-weight: normal; font-size: 8pt;\" value=\"$pList\">$pName[1]</option>\n";
        }
    }
}
print "                <option style=\"font-weight: normal; font-size: 8pt;\" value=\"get\">** Get **</option>\n";
if ($#PresetList >= 0) {
    print "                <option style=\"font-weight: normal; font-size: 8pt;\" value=\"clear\">** Clear **</option>\n";
    print "                <option style=\"font-weight: normal; font-size: 8pt;\" value=\"edit\">** Edit **</option>\n";
}

print "              </select>\n            </td>\n          </tr>\n        </table>\n      </td>\n    </tr>\n";

print "    <tr>\n";
print "      <td align=\"center\" valign=\"center\" wrap>";
if ($Command ne "") { print "<b>$Command</b>"; }
if ($verbose && $Message ne "") {
    print "<br><b>$Message</b>";
}

if ($StatusWindow ne "" || ($Command ne "" && $Command != /OK/)) {
    if ($Command ne "") { print "<br>"; }
    print "<input type=\"checkbox\" onChange=\"this.form.submit()\" name=\"status\" value=\"checked\" $StatusWindow><b>&nbsp;Enable Status Window</b></input>";
}
print "</td>\n    </tr>\n";

formTrailer("presets");
print "  </form>\n";

print "</table>\n</center>\n</body>\n</html>\n";

#
