<?php

/* SIMPLE CAPTCHA
-------------------------------------*/

class captcha extends sessHandlr {

  public $c_var = 'cpt_create';

  private $cfg = array(
    // Length of code..max 62
    // If you increase this, make sure image width/height can accomodate all characters.
    'length' => 8,
    
    // Use word list..if yes, length above is ignored, therefore words must be set that
    // fit on the captcha. eg: if 8 was set above initially, words should not contain more
    // than 8 chars
    'word_list' => 'no',
    
    // Location of word list file
    'word_list_loc' => 'control/classes/system/_captcha_word_list.txt',
    
    // Size of captcha image.
    'image-size' => array(130,50),
    
    // Background color (R,G,B)
    'bg-color' => array(239, 239, 239),
    
    // Text color (R,G,B)
    'txt-color' => array(85, 85, 85),
    
    // Line color (R,G,B)
    'line-color' => array(176, 150, 184),
    
    // How many lines? 0 for no lines.
    'line-count' => 5,
    
    // Pixel color (R,G,B)
    'pixel-color' => array(221, 221, 221),
    
    // How many pixels? 0 for no pixels.
    'pixel-count' => 1000,
    
    // Font..must exist in theme fonts folder.
    'font' => '{theme}/assets/fonts/Comfortaa-Light.ttf',
    
    // Font size.
    'font-size' => 15,
    
    // Positions.
    'pos' => array(
      'x' => array(15, 15),
      'y' => array(35, 35)
    ),
    
    // Random angle.
    'angle' => array(-5, 10),
    
    // Image content type.
    // image/jpeg or image/png
    'content-type' => 'image/jpeg'
  );
  
  public function code() {
    switch($this->cfg['word_list']) {
      case 'yes':
        if (file_exists(GPATH . $this->cfg['word_list_loc'])) {
          $read = array_map('trim', captcha::words());
          shuffle($read);
          $code = (isset($read[0]) && $read[0] ? $read[0] : captcha::rand());
        } else {
          $code = captcha::rand();
        }
        break;
      default:
        $code = captcha::rand();
        break;
    }
    $this->set(array($this->c_var => $code));
    return $code;
  }
  
  private function rand() {
    $code = '';
    $upper = range('A','Z');
    $lower = range ('a','z');
    $num = range(0,9);
    $all = array_merge($upper, $lower, $num);
    shuffle($all);
    if ($this->cfg['length'] > 62) {
      $this->cfg['length'] = 7;
    }
    for ($i=0; $i<$this->cfg['length']; $i++) {
      $code .= $all[rand(10,40)];
    }
    return $code;
  }
  
  private function create($code) {
    // Draw captcha.
    if (function_exists('imagecreatetruecolor')) {
      $layer = imagecreatetruecolor($this->cfg['image-size'][0],$this->cfg['image-size'][1]);
      $bg    = imagecolorallocate($layer, $this->cfg['bg-color'][0], $this->cfg['bg-color'][1], $this->cfg['bg-color'][2]);
      $color = imagecolorallocate($layer, $this->cfg['txt-color'][0], $this->cfg['txt-color'][1], $this->cfg['txt-color'][2]);
      $pixel = imagecolorallocate($layer, $this->cfg['pixel-color'][0], $this->cfg['pixel-color'][1], $this->cfg['pixel-color'][2]);
      $line  = imagecolorallocate($layer, $this->cfg['line-color'][0], $this->cfg['line-color'][1], $this->cfg['line-color'][2]);
      if (file_exists(PATH . str_replace('{theme}', THEME_FOLDER, $this->cfg['font']))) {
        imagefill($layer, 0, 0, $bg);
        if ($this->cfg['line-count'] > 0) {
          for ($i=0; $i<$this->cfg['line-count']; $i++) {
            imageline($layer, 0, rand() % 50, 200, rand() % 50, $line);
          }
        }
        if ($this->cfg['pixel-count'] > 0) {
          for ($i=0; $i<$this->cfg['pixel-count']; $i++) {
            imagesetpixel($layer, rand() % 200, rand() % 50, $pixel);
          }
        }
        imagettftext(
          $layer,
          $this->cfg['font-size'],
          mt_rand($this->cfg['angle'][0],$this->cfg['angle'][1]),
          mt_rand($this->cfg['pos']['x'][0],$this->cfg['pos']['x'][1]),
          mt_rand($this->cfg['pos']['y'][0],$this->cfg['pos']['y'][1]),
          $color, PATH . str_replace('{theme}', THEME_FOLDER, $this->cfg['font']),
          $code
        );
        return $layer;
      }
    }
    return '';
  }
  
  public function words() {
    return file(GPATH . $this->cfg['word_list_loc']);
  }
  
  public function show($code) {
    $c = captcha::create($code);
    if ($c) {
      header("Content-type: " . $this->cfg['content-type']);
      switch($this->cfg['content-type']) {
        case 'image/jpeg':
          imagejpeg(captcha::create($code));
          break;
        default:
          imagepng(captcha::create($code));
          break;
      }
      imagedestroy($c);
      exit;
    } else {
      return '--';
    }
  }
  
  public function check() {
    return $this->get($this->c_var);
  }

}

?>