# ==========================================================================
#
# ZoneMinder Wanscam IP Control Protocol Module, 2012-12-08 
# 
# 
#
# ==========================================================================

package ZoneMinder::Control::Wanscam;

use 5.006;
use strict;
use warnings;

require ZoneMinder::Base;
require ZoneMinder::Control;

our @ISA = qw(ZoneMinder::Control);

our $VERSION = $ZoneMinder::Base::VERSION;

# ==========================================================================
#
# Wanscam IP Control Protocol
#
# ==========================================================================
# Change "ZoneMinder::Logger" to "ZoneMinder::Debug" for zoneminder < 1.25.0

use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);

 use Time::HiRes qw( usleep );
 
 sub new
 { 
  my $class = shift;
  my $id = shift;
  my $self = ZoneMinder::Control->new( $id );
  my $logindetails = "";
  bless( $self, $class );
  srand( time() );
  return $self;
 }
 
 our $AUTOLOAD;
 
 sub AUTOLOAD
 {
  my $self = shift;
  my $class = ref($self) || croak( "$self not object" );
  my $name = $AUTOLOAD;
  $name =~ s/.*://;

  Info( "Autoload $name" );
  Debug( "Autoload $name" );
  if ( exists($self->{$name}) )
  {
    return( $self->{$name} );
  }
  Fatal( "Can't access $name member of object of class $class" );
 }
 our $stop_command;
 
 sub open
 {
  my $self = shift;
 
  $self->loadMonitor();
 
  use LWP::UserAgent;
  $self->{ua} = LWP::UserAgent->new;
  $self->{ua}->agent( "ZoneMinder Control Agent/".ZM_VERSION );
 
  $self->{state} = 'open';
 }
 
 sub close
 { 
  my $self = shift;
  $self->{state} = 'closed';
 }
 
 sub printMsg
 {
  my $self = shift;
  my $msg = shift;
  my $msg_len = length($msg);
 
  Debug( $msg."[".$msg_len."]" );
 }
 
 sub sendCmd
 {
  my $self = shift;
  my $cmd = shift;
  my $result = undef;
  printMsg( $cmd, "Tx" );
 
# ==========================================================================
# Please change username and password to how your camera is setup.
# ==========================================================================
 
  my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd"."&user=admin&pwd=" );
  my $res = $self->{ua}->request($req);
 
  if ( $res->is_success )
  {
    $result = !undef;
  }
  else
  {
    Error( "Error check failed:'".$res->status_line()."'" );
  }
 
  return( $result );
 }
 
# Reset / Reboot the Camera
 sub reset
 {
  my $self = shift;
  Debug( "Camera Reset" );
  my $cmd = "reboot.cgi?";
  $self->sendCmd( $cmd );
 }

# Zoom Tele
 sub zoomConTele
 {
  my $self = shift;
  $stop_command = "17";
  Debug( "Zoom Tele" );
  my $cmd = "decoder_control.cgi?command=16";
  $self->sendCmd( $cmd );
  #$self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
 }

# Zoom Wide
 sub zoomConWide
 {
  my $self = shift;
  $stop_command = "19";
  Debug( "Zoom Wide" );
  my $cmd = "decoder_control.cgi?command=18";
  $self->sendCmd( $cmd );
 # $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
 }

#Up Arrow
 sub moveConUp
 {
  my $self = shift;
  $stop_command = "1";
  Debug( "Move Up" );
  my $cmd = "decoder_control.cgi?command=2";
  $self->sendCmd( $cmd );
#  my $autostop = $self->getParam( $params, 'autostop', 0 );
# if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
#  {
#      usleep( $self->{Monitor}->{AutoStopTimeout} );
#      $self->moveStop( $params );
#  }
 }
 
#Down Arrow
 sub moveConDown
 {
  my $self = shift;
  $stop_command = "1";
  Debug( "Move Down" );
  my $cmd = "decoder_control.cgi?command=0";
  $self->sendCmd( $cmd );
#  my $autostop = $self->getParam( $params, 'autostop', 0 );
#  if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
#  {
#      usleep( $self->{Monitor}->{AutoStopTimeout} );
#      $self->moveStop( $params );
#  }
 }
 
#Left Arrow
 sub moveConLeft
 {
  my $self = shift;
  $stop_command = "1";
  Debug( "Move Left" );
  my $cmd = "decoder_control.cgi?command=4";
  $self->sendCmd( $cmd );
#  if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
#  {
#      usleep( $self->{Monitor}->{AutoStopTimeout} );
#      $self->moveStop( $params );
#  }
 }
 
#Right Arrow
 sub moveConRight
 {
  my $self = shift;
  $stop_command = "1";
  Debug( "Move Right" );
  my $cmd = "decoder_control.cgi?command=6";
  $self->sendCmd( $cmd );
#  if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
#  {
#      usleep( $self->{Monitor}->{AutoStopTimeout} );
#      $self->moveStop( $params );
#  }
 }
 
#Diagonally Up Right Arrow
 sub moveConUpRight
 {
  my $self = shift;
  $stop_command = "1";
  Debug( "Move Diagonally Up Right" );
  my $cmd = "decoder_control.cgi?command=93";
  $self->sendCmd( $cmd );
  $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
 }
 
#Diagonally Down Right Arrow
 sub moveConDownRight
 {
  my $self = shift;
  $stop_command = "1";
  Debug( "Move Diagonally Down Right" );
  my $cmd = "decoder_control.cgi?command=91";
  $self->sendCmd( $cmd );
  $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
 }
 
#Diagonally Up Left Arrow
 sub moveConUpLeft
 {
  my $self = shift;
  $stop_command = "1";
  Debug( "Move Diagonally Up Left" );
  my $cmd = "decoder_control.cgi?command=92";
  $self->sendCmd( $cmd );
  $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
 }
 
#Diagonally Down Left Arrow
 sub moveConDownLeft
 {
  my $self = shift;
  $stop_command = "1";
  Debug( "Move Diagonally Down Left" );
  my $cmd = "decoder_control.cgi?command=90";
  $self->sendCmd( $cmd );
  $self->autoStop( $stop_command, $self->{Monitor}->{AutoStopTimeout} );
 }

#Up Rel
 sub moveRelUp
 {
  my $self = shift;
  my $params = shift;
  my $step = $self->getParam( $params, 'tiltstep' );
  $stop_command = "1";
  Debug( "Move Rel Up $step" );
  my $cmd = "decoder_control.cgi?command=2&degree=$step";
  $self->sendCmd( $cmd );
 }
 
#Down Rel 
 sub moveRelDown
 {
  my $self = shift;
  my $params = shift;
  my $step = $self->getParam( $params, 'tiltstep' );
  $stop_command = "1";
  Debug( "Move Rel Down $step" );
  my $cmd = "decoder_control.cgi?command=0&degree=$step";
  $self->sendCmd( $cmd );
 }

#Left Rel 
 sub moveRelLeft
 {
  my $self = shift;
  my $params = shift;
  my $step = $self->getParam( $params, 'panstep' );
  Debug( "Move Rel Left $step" );
  my $cmd = "decoder_control.cgi?command=4&degree=$step";
  $self->sendCmd( $cmd );
 }

#Right Rel
 sub moveRelRight
 {
  my $self = shift;
  my $params = shift;
  my $step = $self->getParam( $params, 'panstep' );
  Debug( "Move Rel Right $step" );
  my $cmd = "decoder_control.cgi?command=6&degree=$step";
  $self->sendCmd( $cmd );
 }

#Diagonally Up Right Rel
 sub moveRelUpRight
 {
  my $self = shift;
  my $params = shift;
  my $step = $self->getParam( $params, 'panstep' );
  Debug( "Diagonally Up Right Rel $step" );
  my $cmd = "decoder_control.cgi?command=93&degree=$step";
  $self->sendCmd( $cmd );
 }
 
#Diagonally Up Left Rel
 sub moveRelUpLeft
 {
  my $self = shift;
  my $params = shift;
  my $step = $self->getParam( $params, 'panstep' );
  Debug( "Diagonally Up Left Rel $step" );
  my $cmd = "decoder_control.cgi?command=92&degree=$step";
  $self->sendCmd( $cmd );
 }
 
#Diagonally Down Right Rel
 sub moveRelDownRight
 {
  my $self = shift;
  my $params = shift;
  my $step = $self->getParam( $params, 'panstep' );
  Debug( "Diagonally Down Right Rel $step" );
  my $cmd = "decoder_control.cgi?command=91&degree=$step";
  $self->sendCmd( $cmd );
 }
 
#Diagonally Down Left Rel
 sub moveRelDownLeft
 {
  my $self = shift;
  my $params = shift;
  my $step = $self->getParam( $params, 'panstep' );
  Debug( "Diagonally Down Left Rel $step" );
  my $cmd = "decoder_control.cgi?command=90&degree=$step";
  $self->sendCmd( $cmd );
 }
 
 
#Stop
 sub moveStop
 {
  my $self = shift;
  Debug( "Move Stop" );
  my $cmd = "decoder_control.cgi?command=1";
  $self->sendCmd( $cmd );
 }
 
 
 
#Move Camera to Home Position
 sub presetHome
 {
  my $self = shift;
  Debug( "Home Preset" );
  my $cmd = "decoder_control.cgi?command=25";
  $self->sendCmd( $cmd );
 }


#Move Camera to Preset 1
 sub presetGoto1
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=31";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 2
 sub presetGoto2
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=33";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 3
 sub presetGoto3
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=35";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 4
 sub presetGoto4
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=37";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 5
 sub presetGoto5
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=39";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 6
 sub presetGoto6
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=41";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 7
 sub presetGoto7
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=43";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 8
 sub presetGoto8
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=45";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 9
 sub presetGoto9
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=47";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 10
 sub presetGoto10
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=49";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 11
 sub presetGoto11
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=51";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 12
 sub presetGoto12
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=53";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 13
 sub presetGoto13
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=55";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 14
 sub presetGoto14
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=57";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 15
 sub presetGoto15
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=59";
  $self->sendCmd( $cmd );
 }

#Move Camera to Preset 16
 sub presetGoto16
 {
  my $self = shift;
  Debug( "Preset" );
  my $cmd = "decoder_control.cgi?command=61";
  $self->sendCmd( $cmd );
 }


#Move Camera to Preset Position
  sub presetGoto
  {
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    Debug( "Goto Preset $preset" );
    #$preset - number of preset
    #go 1 - 31
    #go 2 - 33
    #go 3 - 35
    Info("Preset $preset");
    $preset=$preset*2+29;
    my $cmd = "decoder_control.cgi?command=$preset";
    $self->sendCmd( $cmd );
  }

# Set camera presets
  sub presetSet
  {
    my $self = shift;
    my $params = shift;
    my $preset = $self->getParam( $params, 'preset' );
    Debug( "Set Preset $preset" );
    #$preset - number of preset
    #go 1 - 30
    #go 2 - 32
    #go 3 - 34
    Info("Preset $preset");
    $preset=$preset*2+28;
    my $cmd = "decoder_control.cgi?command=$preset";
    $self->sendCmd( $cmd );
  }

#Move Camera to PseudoMap
sub movePseudoMap
{
    my $self = shift;
    my $params = shift;
    my $xcoord = $self->getParam( $params, 'xcoord' );
    my $ycoord = $self->getParam( $params, 'ycoord' );
    my $direct=1; #Stop default
#   For FosCam 8908 frame height and width contain 14 "onestep" steps with standard lens
    my $steps=14;
    my $x_steps=0;
    my $istep=0;
    Debug( "Move Map to $xcoord,$ycoord" );
    Info( "1 Move Map to $xcoord,$ycoord" );
#    Info("2 monitor Width".$self->{Monitor}->{Width});
#    Info("3 monitor Height".$self->{Monitor}->{Height});
#    6>  4<  2v 0^;
   if ( $xcoord < ( $self->{Monitor}->{Width})/2 ) 
   { # Left rotate
     Info("5 X dir Left");
     $direct=4;
   }
   if ( $xcoord > ( $self->{Monitor}->{Width})/2 ) 
   { #Right rotate
     Info("6 X dir Right");
     $direct=6;
   }
   $x_steps = abs(($self->{Monitor}->{Width})/2-$xcoord)/(($self->{Monitor}->{Width})/$steps) ;
#   $x_steps = round($x_steps);
    Info("x_steps= $x_steps");

#   if ( $ycoord < ( $self->{Monitor}->{Height})/2 ) 
#   {
#     Info("7 Y dir UP");
#     If ( $direct=1 )
#        {
#        #UP
#        $direct=0;
#        }
#     If ( $direct=6 )
#        {
#        #Right Up
#        $direct=91;
#        }
#         If ( $direct=4 )
#        {
#        #Left Up
#        $direct=90;
#        }
#   }
#   if ( $ycoord > ( $self->{Monitor}->{Height})/2 ) 
#   {
#     Info("8 Y dir Down");
#     If ( $direct=1 )
#        {
#        #Down
#        $direct=2;
#        }
#     If ( $direct=6 )
#        { #Right Down
#        Info("11 dir Right Down");
#        $direct=93;
#        }
#         If ( $direct=4 )
#        { #Left Down
#        Info("11 dir Left Down");
#        $direct=92;
#        }
#   }
   
 my $cmd = "decoder_control.cgi?command=$direct&onestep=1";
for($istep=1; $istep<=$x_steps; $istep++)
{
 $self->sendCmd( $cmd );
     Debug("Pseudomap FosCam command: $cmd ");
}
}
 
 1;
