<?php
namespace imcat;

//生成验证码
class comVCode {

    private 
$im;            //图片对象
    
private $dis;           //图片对象
    
private $imw = 160;     //宽
    
private $imh = 40;      //高
    
private $mod = '';      //模块
    
private $ttf = '';      //字体文件 //array
    
private $ttOld = '';
    private 
$clOld = Null;
    private 
$code = '';     //字符
    
private $corg = '';     //字符
    
private $ctab = '';     //随机颜色表
    //private $cTab = "";
    //private $oTab = '';
    
static $ctabN = [];
    static 
$ctabA = [];
    static 
$ctabB = [];

    static function 
initTab(){
        
self::$ctabN['4'] = ['0'=>0, '5'=>85, 'A'=>170, 'F'=>255]; # gap:5 : 0-5-A-F
        
self::$ctabN['5'] = ['00'=>0, '40'=>64, '80'=>128, 'C0'=>192, 'F0'=>255]; # gap:8 : 00:80:C0:F0 
        
self::$ctabN['6'] = ['0'=>0, '3'=>51, '6'=>102, '9'=>153, 'C'=>204, 'F'=>255];
        
//
        
self::$ctabA['6'] = [ # gap:6
            
'0'=>['6','9','C','F'],
            
'3'=>[    '9','C','F'],
            
'6'=>['0',    'C','F'],
            
'9'=>['0','3',    'F'],
            
'C'=>['0','3','6'    ],
            
'F'=>['0','3','6','9'],
        ];
        
self::$ctabB['6'] = [ # gap:6
            
'0'=>['3'],
            
'3'=>['0','6'],
            
'6'=>['3','9'],
            
'9'=>['6','C'],
            
'C'=>['9','F'],
            
'F'=>['C'],
        ];
    }

    
# 前背景颜色
    
static function tabrc($n=6, $rc3=0, $rx=0){
        
$tbcn = self::$ctabN['6']; $tbkn = array_keys($tbcn); 
        
$tban = self::$ctabA['6']; $tbbn = self::$ctabB['6'];
        
# one
        
if(!$n){
            return 
$rc3 ? implode('',$tb3) : [$tbcn[$tb3[0]],$tbcn[$tb3[1]],$tbcn[$tb3[2]]];
        }
        
# RGB(n+1)
        
$tb3 = $ts1 = []; shuffle($tbkn); #dump($tbkn);
        
$xb3 = $xs1 = [];
        for(
$i=0;$i<3;$i++){
            
$tb3[] = $k1 = $tbkn[$i]; $ts1[] = $tban[$k1];
            
$xb3[] = $k1 = $tbkn[$i]; $xs1[] = $tbbn[$k1];
        } 
#dump($tb3); dump($ts1);
        # return n + 1 
        
$ts3[] = $rc3 ? implode('',$tb3) : [$tbcn[$tb3[0]],$tbcn[$tb3[1]],$tbcn[$tb3[2]]];
        for(
$i=0;$i<$n;$i++){ 
            
$k1 = array_rand($ts1[0],1); $c1=$ts1[0][$k1]; $k2 = array_rand($ts1[1],1); $c2=$ts1[1][$k2]; $k3 = array_rand($ts1[2],1); $c3=$ts1[2][$k3];
            
$ts3[] = $rc3 ? "$c1$c2$c3" : [$tbcn[$c1],$tbcn[$c2],$tbcn[$c3]];
            
$k1 = array_rand($xs1[0],1); $c1=$xs1[0][$k1]; $k2 = array_rand($xs1[1],1); $c2=$xs1[1][$k2]; $k3 = array_rand($xs1[2],1); $c3=$xs1[2][$k3];
            
$xs3[] = $rc3 ? "$c1$c2$c3" : [$tbcn[$c1],$tbcn[$c2],$tbcn[$c3]];
        }
        
#dump($tb3); dump($ts1); dump($ts3); 
        
return [$ts3, $xs3];
    }

    function 
__construct($mod='(istest)', $ttf='', $corg='0'){ 
        
$this->mod = $mod; 
        
$this->ttf = $ttf;
        
$this->corg = $corg;
        
self::initTab();
        
// 显示图片一般图片
        
if(function_exists('imagecreate')){ 
            
$this->show();
        }else{ 
//bmp
            
glbError::show("NO function:imagecreate!");
        }
    }
    function 
init(){
        if(
$this->mod=='(emtel)'){
            
$this->code = $this->corg;
            
$this->imw = 20+strlen($this->corg)*20;
        }else{
            
$this->code = self::strRand();
        }
        
$this->im = imagecreate($this->imw, $this->imh); 
        
// 填充
        
$this->ctbs = $this->tabrc(strlen($this->code), 0, 1); # n+1个颜色
        
$this->bgColor = $this->rndCimg($this->ctbs[0][0]);
        
imagefill($this->im,0,0,$this->bgColor);
    }
    
// 输出
    
function output(){
        
$typa = array(1=>'gif', 2=>'png', 3=>'jpeg'); 
        
$type = $typa[rand(1,3)]; 
        
basEnv::obClean();
        
#header("Pragma:no-cache");
        #header("Cache-control:no-cache");
        #header("Content-type:image/$type");
        
$func = "image$type"; //imagejpeg
        
$func($this->im); 
    }
    
// 显示
    
function show(){
        
$this->init();
        
safComm::formCVimg($this->mod, $this->code, 'save'); 
        
// 干扰: 点,线,特殊字符,雪花
        
if($this->mod!='(emtel)'){
            
$r = rand(1,4);
            if(
$r==1) $this->_rndPixels();
            if(
$r==2) $this->_rndLines();
            if(
$r==3) $this->_rndChars();
            if(
$r==4) $this->_rndSnow();
        }
        
$this->drawStr(); // Draw字符,划边框
        //$this->distOrtion(); // 扭曲文字 
        
$this->output();
        
imagedestroy($this->im); 
        if(
is_resource($this->dis)){
            
imagedestroy($this->dis);
        }
    }
    
// Draw字符
    
function drawStr(){        
        for(
$i=0;$i<strlen($this->code);$i++) {
            
$chr = $this->code[$i];
            if(
$this->mod=='(emtel)'){
                
$size = 20;
            }elseif(
ord($chr)>96){
                
$size = mt_rand(22,26);
            }else{
                
$size = mt_rand(16,20); 
            }
            
$angle = $this->mod=='(emtel)' ? 0              : mt_rand(-20,20);
            
$x     = $this->mod=='(emtel)' ? $i*20+8        : mt_rand(15,20)+$i*26;
            
$y     = $this->mod=='(emtel)' ? mt_rand(24,30) : mt_rand(27,30);
            
$ffile = $this->rndFonts(); $tcolor = $this->rndCimg($this->ctbs[0][$i+1]);
            if(
$this->mod!='(emtel)'){
                
// 外围描边(空心效果) ctab -> ctbs
                
$cb = $this->rndCimg($this->ctbs[1][$i]); 
                
imagettftext($this->im, $size, $angle, $x+1, $y, $cb, $ffile, $chr); // x
                
imagettftext($this->im, $size, $angle, $x, $y+1, $cb, $ffile, $chr); // y
            
}
            
// 文字本身
            
imagettftext($this->im, $size, $angle, $x, $y, $tcolor, $ffile, $chr);
        }
    }

    function 
rndCimg($ctab){
        
$cl = imagecolorallocate($this->im, $ctab[0], $ctab[1], $ctab[2]);
        if(
$cl===false){
            
$cl = imagecolorclosest($this->im, $ctab[0], $ctab[1], $ctab[2]);
        } 
        return 
$cl;
    }

    
// 随机颜色
    
function rndColor($no=0){
        
$ct = [];
        for(
$i=0;$i<3;$i++){ $ct[]=mt_rand(2,254); }
        
$cl = $this->rndCimg($ct); 
        return 
$cl;
    }
    
// 随机Font
    
public function rndFonts(){
        if(
is_string($this->ttf)){
            
$tti = $this->ttf;
        }else{
            
$tti = $this->ttf[mt_rand(0,count($this->ttf)-1)];
            while(
$this->ttOld==$tti){
                
$tti = $this->ttf[mt_rand(0,count($this->ttf)-1)];
            }
            
$this->ttOld = $tti; 
        } 
        
$ffile = DIR_STATIC.'/media/fonts/'.$tti.'.ttf'; 
        return 
$ffile;
    }
    
// 干扰象素
    
function _rndPixels(){ //加入干扰象素
        
for($i=0;$i<200;$i++){  
           
imagesetpixel($this->im, rand()%160 , rand()%100 , $this->rndColor());    
        }
    }
    
// 干扰线
    
function _rndLines(){ 
        
$w = $this->imw-2;
        
$h = $this->imh-2;
        
$cnt = mt_rand(5,8);
        for(
$j=2;$j<$cnt;$j++){
            
imageline($this->im, rand(2,$w),rand(2,$h),rand(2,$w),rand(2,$h), $this->rndColor()
            ); 
//18
        
}
        
imagerectangle($this->im, 0, 0, $this->imw-1, $this->imh-1, $this->rndColor()); // 边框 
    
}
    
// 干扰字符
    
function _rndChars(){ 
        if(empty(
$this->ttf)){ return; }
        
$cnt = mt_rand(5,10); //《!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~》// All:32 '+','-',
        
$chars = array('!',"'",'(',')',',','/',";","?","^","`","~");
        for(
$i=1; $i<=$cnt; $i++){
            
imagestring($this->im,mt_rand(1,5),mt_rand(1,$this->imw),mt_rand(1,$this->imh),$chars[mt_rand(0,4)],$this->rndColor());
        }
    }
    
// 雪花
    
function _rndSnow(){  
        for (
$i=0;$i<30;$i++) {
            
$color = imagecolorallocate($this->im,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255));
            
imagestring($this->im,mt_rand(2,5),mt_rand(0,$this->imw),mt_rand(0,$this->imh),'*',$color);
        }
    }
    
// 扭曲文字
    
public function distOrtion(){
        
$rate = floor(0.08 * $this->imh);   // 扭曲程度
        
$this->dis = imagecreatetruecolor($this->imw, $this->imh);
        
imagefill($this->dis, 0, 0, $this->bgColor);
        for (
$x = 0; $x < $this->imw; $x++) {
            for (
$y = 0; $y < $this->imh; $y++) {
                
$rgb = imagecolorat($this->im, $x, $y);
                if( (int)(
$x + sin($y / $this->imh * 2 * M_PI) * $rate) <= $this->imw && (int)($x + sin($y / $this->imh * 2 * M_PI) * $rate) >= 0 ) 
                {
                    
imagesetpixel($this->dis, (int)($x + sin($y / $this->imh * 2 * M_PI - M_PI * 0.1) * $rate) , $y, $rgb);
                }
            }
        }
        
$this->im = $this->dis;
    }
    
// *** 随机码
    
static function strRand(){
        global 
$_cbase;
        
$vimg = $_cbase['ucfg']['vimg'];
        
$type = in_array($vimg,array('0','H','K')) ? $vimg : 'K';
        
$str = basKeyid::kidRand($type,rand(4,5));
        return 
strtoupper($str);
    }
    
// 颜色表
    /*function setCtab($xTab,$xArr,$init){}*/
    //basDebug::bugLogs('vcode', $this->code, 'vcode.txt', 'file');
    
}