<?php
/******************************************************************************\
*  AnalogPHPClock, A PHP-class which produces an image of a analog clock.      *
*  Copyright (C) 2005, Michael Erkens (http://www.erkens.info/41               *
*                                                                              *
*  This library is free software; you can redistribute it and/or               *
*  modify it under the terms of the GNU Lesser General Public                  *
*  License as published by the Free Software Foundation; either                *
*  version 2.1 of the License, or (at your option) any later version.          *
*                                                                              *
*  This library is distributed in the hope that it will be useful,             *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of              *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           *
*  Lesser General Public License for more details.                             *
*                                                                              *
*  You should have received a copy of the GNU Lesser General Public            *
*  License along with this library; if not, write to the Free Software         *
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *
\******************************************************************************/



/**
* This class constructs a image which represents an analog clock
*
*@version 1.0
*@author M. Erkens <michael@erkens.info>
*/
class AnalogClock {
  var
$size;      // size of the image in pixels
  
var $bgcolor;   // background color
  
var $fgcolor;   // foreground color
  
var $hour;      // information about the hour arm
  
var $minute;    // information about the minute arm
  
var $img;       // the resource to the image
  
var $builded;   // boolean to see if image is already constructed

  /**
   * Constructor
   *
   *@param int $size The height and width of the clock
   *@param string $bg Background color of the clock in HTML hex: FF0000 for red
   *@param string $fg Foreground color of the clock in HTML hex: 0000FF for blue
   */
  
function AnalogClock($size,$bg,$fg){
    
$this->size    = $size;

    
$this->bgcolor = $this->hex2rgb($bg);
    
$this->fgcolor = $this->hex2rgb($fg);
    
    
$this->builed  = false;
  }

  
/**
   * Calculates the positions for the arms of the clock
   *
   *@param int $hour The hours of the time to be displayed
   *@param int $min  The minutes of the time to be displayed
   */
  
function setTime($hour,$min){
    
$this->hour = array();
    
$this->hour['v'] = $hour%12;
    if (
$this->hour==0) $this->hour = 12;

    
$this->minute = array();
    
$this->minute['v'] = $min%60;
    if (
$this->minute==60) $this->minute = 0;

    
    
$this->minute['a'] = $this->calcRad($this->minute['v'],60);
    
$this->hour['a'] = $this->calcRad($this->hour['v'],12) + deg2rad($this->minute['v']/2);
    
    
$this->hour['x'] = (($this->size/2) - (0.2*$this->size)) * cos($this->hour['a']) + ($this->size/2);
    
$this->hour['y'] = (($this->size/2) - (0.2*$this->size)) * sin($this->hour['a']) + ($this->size/2);

    
$this->minute['x'] = (($this->size/2) - (0.05*$this->size)) * cos($this->minute['a']) + ($this->size/2);
    
$this->minute['y'] = (($this->size/2) - (0.05*$this->size)) * sin($this->minute['a']) + ($this->size/2);
  }
  
  
  
/**
   * Creates the image in PNG format
   *
   *@param string $output Optional param, when set, no content-type will be set and the image will be saved to the file specified here
   */
  
function createPNG($output=null){
    
$this->createImage();
    if (
$output==null){
      
header('Content-Type: image/png');
      
imagepng($this->img);
    }else{
      
imagepng($this->img,$output);
    }
  }
  
  
/**
   * Creates the image in JPG format
   *
   *@param string $output Optional param, when set, no content-type will be set and the image will be saved to the file specified here
   */
  
function createJPG($output=null){
    
$this->createImage();
    if (
$output==null){
      
header('Content-Type: image/jpeg');
      
imagejpeg($this->img);
    }else{
      
imagejpeg($this->img,$output);
    }
  }
  
  
/**
   * Creates the image in GIF format
   *
   *@param string $output Optional param, when set, no content-type will be set and the image will be saved to the file specified here
   */
  
function createGIF($output=null){
    
$this->createImage();
    if (
$output==null){
      
header('Content-Type: image/gif');
      
imagegif($this->img);
    }else{
      
imagegif($this->img,$output);
    }
  }
  
  
/**************************\
  *    Internal functions    *
  \**************************/
  
  /**
   * Internal function to construct the image
   */  
  
function createImage(){
    if (!
$this->builded){
      
$this->img = imagecreate($this->size,$this->size);
      
      
$bgcolor = imagecolorallocate($this->img,$this->bgcolor['r'],$this->bgcolor['g'],$this->bgcolor['b']);
      
$fgcolor = imagecolorallocate($this->img,$this->fgcolor['r'],$this->fgcolor['g'],$this->fgcolor['b']);
      
      
// using imagearc, because imageellipse needs GD > 2.0.2
      
imagearc($this->img, ($this->size/2), ($this->size/2), $this->size-1, $this->size-1, 0, 360, $this->fgcolor);
      
      
// draw hours
      
imageline($this->img, ($this->size/2), ($this->size/2), $this->hour['x'], $this->hour['y'], $this->fgcolor);
      
// draw minutes
      
imageline($this->img, ($this->size/2), ($this->size/2), $this->minute['x'], $this->minute['y'], $this->fgcolor);

      
$this->builded = true;
    }
  }
  
  
/**
   * Internal function to change a hex color to an array with RGB
   *
   *@param string $hex The HTML hex color in the format FF00FF for full red, no green and full blue
   *@returns array with the keys r, g and b
   */
  
function hex2rgb($hex) {
    
$hex = eregi_replace("[^a-fA-F0-9]", "", $hex);
    if (
strlen($hex) != 6) {
      
trigger_error('Invalid color "'.$hex.'"',E_USER_WARNING);
      
$hex = '000000'; // use black when error hasn't catched
    
}
    
$rgb = explode(" ", chunk_split($hex, 2, " "));
    
$rgb = array_map("hexdec", $rgb); // hexdec() is a PHP internal function
    
return array("r" => $rgb[0], "g" => $rgb[1], "b" => $rgb[2]);
  }

  
/**
   * Internal function to calculate radian value for the time, used for calculating the position of the clock
   *
   *@param float $val Value to calculate
   *@param int $max Max value
   *@returns float radian value
   */
  
function calcRad($val,$max){
    return
deg2rad(abs(360/$max)*((($val-$max/4)<0)?(($val-$max/4)+$max):($val-$max/4)));
  }

}
?>