<?php
/*
     PHPMOTION DETECT.
     A PHP SCRIPT FOR MOTION DETECTION.
     OPTIONAL STORING OF SNAPSHOTS TO MYSQL DATABASE

     (C) 2002, Thomas Mejer Hansen, thomas@lixnet.dk)

     TODO 
     * SET TIME WHERE MOTION DETECTION IS PERFORMED
     * CREATE MPEG MOVIES DIRECTLY FORM THE WEBINTERFACE.
     * SAVE SNAPSHOTS IN DIRECTORY NAMED BY CURRENT DATE
     * DIFFERENT CRITERIA FOR MOTION DETECTION
       - Change in brightness between last stored snapshot 
         and the current.
       - Change in brightness between last taken 
         but not stores snapshot and the current.
         (This will probably be more tur to motion detection
          since e.g. light(day)-darkness(night) will not 
          neccesarily cause a motion detection)

*/


// SETUP
include("conf.php");


// OPEN CONNECTION TO DB IF CHOSEN
if ($usedb==1) {  
  VerboseInfo("USING DB ($user@$host)",1,$verbose);
  $db = mysql_connect($host, $user, $password);
  if (mysql_select_db($usebase,$db)) {
    VerboseInfo("SELECTED DB -- OK ($user@$host)",1,$verbose);
  }
}


// TAKE FIRST SNAPSHOT IF IT DOES NOT EXIST
if (!file_exists($old)) {
  $cmd="$capture $old >& /dev/null";
  system($cmd);
  VerboseInfo("Snapshot command (Old snapshot) : $cmd",5,$verbose);
} else {
  VerboseInfo("Using existing old=$old",5,$verbose);
}

$i=0;
while ($i>=0) {
  $i++;
  
  // TAKE SNAPSHOT
  $cmd="$capture $new >& /dev/null";
  VerboseInfo("Snapshot command (New snapshot) : $cmd",5,$verbose);
  system($cmd);

  // READ THE NEW SNAPSHOT
  VerboseInfo("Reading $new.",10,$verbose);
  $im_new = imagecreatefromjpeg($new);

  // ************* GET BRIGHTNESS LEVELS *********************
  // GET BRIGHTNESS OF REFERENCE(OLD) IMAGE IF NECCESARY
  if (!isset($bright_old)) {
    VerboseInfo("Reading $old.",10,$verbose);
    $im_old = imagecreatefromjpeg($old);
    $bright_old=GetBrightness($im_old); 
  }
  // GET BRIGHTNESS OF SNAPSHOT
  $bright_new=GetBrightness($im_new);  
  // DIFF IN BRIGHTNESS
  $D=$bright_new-$bright_old; // A MEASURE OF CHANGE IN BRIGHNESS

  // DISP BRIGHNESS INFO
  $t=sprintf("snap=%04d, New=%3.1f, Ref=%3.1f, Diff=%3.1f",$i,$bright_new,$bright_old,$D);
  VerboseInfo($t,1,$verbose);

  // INSERT INTO LOG-TABLE
  if ($usedb==1) {  
    VerboseInfo("Insert 'log' entry into DB",5,$verbose);
    $sql="INSERT INTO log (diff,bright_ref,bright) VALUES ('$D','$bright_old','$bright_new')";
    if (!$dbresult = mysql_query($sql,$db)) {
      VerboseInfo("Failed to insert into 'log' db ($sql)",2,$verbose);
    }
  }
  
  
  // COPY NEW FILE TO OLD FILE BEFORE ADDING ANY TEXT TO THE IMAGE
  // BUT ONLY IF CRONTAB IS USED AND MODE=1;
  if (($mode==1)&($usecron==1)) {
    if (!copy($new,$old)) {
      VerboseInfo("Failed to copy $new to $old",1,$verbose);
    } else {
      VerboseInfo("Succesfully copied $new to $old",5,$verbose);
    }
  }
  // VerboseInfo("snapshot $i, diff=$D",1,$verbose);
  
  if (abs($D)>$threshold) {
    // MOTION IS DETECTED, NOW ARCHIVE THE FILE 
    VerboseInfo("snapshot $i, Motion Detected : $D",0,$verbose);
    
    if (!copy($new,$old)) {
      VerboseInfo("Failed to copy $new to $old",1,$verbose);
    } else {
      // ADD TIMESTAMP TO SNAPSHOT
      $snap_date=sprintf("%s",date("YMd-H:i:s"));
      $black=ImageColorAllocate($im_new,0,0,0);
      $red=ImageColorAllocate($im_new,256,0,0);
      imagestring($im_new,4,5,5,$snap_date,$black);       
      // SAVE THE IMAGE WITH THE DATE ON
      if (imagejpeg($im_new,$new)){
        VerboseInfo("Wrote date $snap_date to $new",5,$verbose); 
      } else {
        VerboseInfo("COULD NOT add date to file $new",1,$verbose); 
      }
      
      $size=getimagesize($new);
      
      $sql_update="UPDATE log SET stored='Stored' WHERE id=LAST_INSERT_ID()";
      if (!$query_result=mysql_query($sql_update,$db)) {  
	VerboseInfo("Failed to update 'log' db",2,$verbose);
      } 

      if ($usedb==1) {  
	// NEXT 3 LINES SHOULD BE USED FOR OLDER MYSQL CLIENTS 
	// PRE 4.0
	$filesize=filesize($new);
	$im=addslashes(fread(fopen($new,"r"),$filesize));
	$sql="insert into images (log_id,image,width,height,type) values ( LAST_INSERT_ID(),'$im',$size[0],$size[1],$size[2])";
	// NEXT LINE SHOULD BE USED FOR MYSQL 4.0 ->
	//$sql="insert into images (log_id,image,width,height,type) values ( LAST_INSERT_ID(),load_file('$new'),$size[0],$size[1],$size[2])";
	if (!$query_result=mysql_query($sql,$db)) { 
	  VerboseInfo("Failed insert image into 'image' table ($sql)",2,$verbose);
	}
      } 
    }
    
    // ARCHIVE THE SNAPSHOT
    // MAKE SURE A DIRECTORY FOR TO DAY EXISTS, OTHERWISE CREATE IT
    $archivedir = sprintf("$outdir/%s",date("YMd"));
    if (!file_exists($archivedir)) {
      if (mkdir($archivedir,0777)) {
	VerboseInfo("Created $archivedir",10,$verbose); 
      } else {
	VerboseInfo("Could not created $archivedir - Possible a permission issue",0,$verbose); 
      }
    } else {
      VerboseInfo("$archivedir allready exists",30,$verbose); 
    }
    $archivefile = sprintf("$archivedir/snap_%s.jpeg",date("YMd-H:i:s"));
    
    // ADD TIMESTAMP TO SNAPSHOT
    //$black=ImageColorAllocate($im_new,0,0,0);
    //$red=ImageColorAllocate($im_new,256,0,0);
    //imagestring($im_new,4,5,5,$snap_date,$black);
    
    // ARCHIVE THE SNAPSHOT
    if (imagejpeg($im_new,$archivefile)){
      VerboseInfo("Archived snapshot as $archivefile",5,$verbose); 
    } else {
      VerboseInfo("COULD NOT archive snapshot as $archivefile - Permision trouble ?",1,$verbose); 
    }

    $bright_old=$bright_new;
    
  } // ACT ON MOTION DETECT
  

  
  if (($mode==1)&($usecron==0)) {
    // ALWAYS UPDATE THE REFERENCE IMAGE WHEN MODE=1 AND USED AS SCRIPT.
    $bright_old=$bright_new;
    if ($usecron==1) {
      // ALSO WRITE SNAPSHOT TO DISK IF USING CRON
      //if (imagejpeg($im_old,$archivefile)){
      //	VerboseInfo("Archived snapshot as $archivefile",5,$verbose); 
      //} else {
      //	VerboseInfo("COULD NOT archive snapshot as $archivefile - Permision trouble ?",1,$verbose); 
      //}
      
    }
  }




  // IF $usecron=1, TERMINATE THE WHILE LOOP
  if ($usecron==1) { 
    break;
  };
} // END LOOP OVER I



function ImageDiff($im1,$im2) {
  // FUNCTION TO FIND THE DIFFERENCE IN BRIGHTNESS 
  // BETWEEN TWO FILES.
  
  $NX=imagesx($im1);  
  $NY=imagesy($im2);  

  $nc_im1=imagecolorstotal($im1);
  $nc_im2=imagecolorstotal($im2);
  
  $diff=0;
  $br1=0;
  $br2=0;
  for ($ix = 1; $ix <= $NX; $ix++) {
    for ($iy = 1; $iy <= $NY; $iy++) {

      $rgb1=imagecolorsforindex($im1, imagecolorat($im1, $ix, $iy)); 
      $rgb2=imagecolorsforindex($im2, imagecolorat($im2, $ix, $iy)); 

      $brightness1 = $rgb1["red"] + $rgb1["green"] + $rgb1["blue"];
      $brightness2 = $rgb2["red"] + $rgb2["green"] + $rgb2["blue"];

      $br1=$br1+$brightness1;
      $br2=$br2+$brightness2;
      $diff=$diff+$brightness1-$brightness2;
 
      VerboseInfo(sprintf("%s,%s  %s\n",$brightness1,$brightness1,$brightness1-$brightness2),20,$verbose); 

    }
  }
  
  $meandiff=$diff/($NX*$NY);
  $meanbr1=$br1/($NX*$NY);
  $meanbr2=$br2/($NX*$NY);

  return array($meandiff,$meanbr1,$meanbr2);
}


function GetBrightness($im) {
  // FUNCTION TO FIND THE BRIGHTNESS OF A PICTURE 
  // BETWEEN TWO FILES.
  
  VerboseInfo('Getting brighntess ...',10,1);

  $NX=imagesx($im);  
  $NY=imagesy($im);  

  $brightness=0;
  for ($ix = 1; $ix <= $NX; $ix++) {
    for ($iy = 1; $iy <= $NY; $iy++) {
      $rgb1=imagecolorsforindex($im, imagecolorat($im, $ix, $iy)); 
      $d_br = $rgb1["red"] + $rgb1["green"] + $rgb1["blue"];
      $brightness=$brightness+$d_br;
      VerboseInfo(sprintf("Brightness : %s\n",$brightness),20,$verbose); 
    }
  }
  
  $meanbrightness=$brightness/(3*$NX*$NY);

  return $meanbrightness;

}


function VerboseInfo($txt,$showverbose,$verbose) {
  if ($verbose>=$showverbose) {
    echo "motiondetect($verbose) $showverbose : $txt \n";
  }
}
  
?>