<?php
/**
 * This script generates a fancy credit card/ID/Passport RainbowCard with a grid of pseudorandom characters.
 * 
 * Seed used to generate the grid, column/row labelling and colors, card size, PIN block (digits only) 
 * and character set the grid can be made with, are determined by URL/GET parameters.
 * 
 * In order to work it requires GD lib extensions installed, and font files.
 * Fonts gotta be Mono Spaced, or weird things will happen. The resulting card can be sharp, or transmit diseases...
 * 
 * Author: Ariel Graneros - dalecter at hotmail dot com (aka DrLecter)
 * Last changed: 10-03-2010 11:50 GMT-3
 * 
 */

/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program 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 General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */

$lcletters="abcdefghijklmnopqrstuvwxyz";
$ucletters=strtoupper($lcletters);
$numbers="1234567890";
$symbols="!#$%&/()=+-?*[]{}";

$font="./fonts/StrLit.ttf";
$font2="./fonts/F25_Bank_Printer.ttf";

//Don't!
$width=1011;
$height=637;
$header="A B C D E F G H I J K L M N O P R S T U V W X Y Z";
$labels="ABCDEFGHIJKL";
$max_row=9;
$max_col=22;
$size=55;


/**
 * This function takes a seed string as argument
 * returning an array with the seed and an alphanumb'd, base64'd humongoustring.
 * 
 * If no seed is provided, it will use mktime+pseudorandom stringy
 * as its seed.
 *
 * @param string $word
 * @return string
 */
function generate($word=NULL
{
    
$algos=array('sha512','whirlpool','snefru','gost');
    
$site_seed=get_rand_id(100);
    if (
strlen($word)>220)
        
$word=substr($word,0,220);
    if (
$word==NULL)
        
$word=mktime().$site_seed;
    
$results = array();
    foreach(
$algos as $algo)
        {
        
$data hash($algo$wordtrue);
        
$results[] = $data;
        }
    
sort($results);
    
$string=base64_encode(implode('',$results));
    return array(
$word,str_ireplace(array("+","=","/"),"",$string));
    }
/**
 * rounded fancy borders
 *
 * @param image handle $im
 * @param int $x
 * @param int $y
 * @param int $cx
 * @param int $cy
 * @param int $rad
 * @param img color $col
 */

function imagefillroundedrect($im,$x,$y,$cx,$cy,$rad,$col)
{
    
imagefilledrectangle($im,$x,$y+$rad,$cx,$cy-$rad,$col);
    
imagefilledrectangle($im,$x+$rad,$y,$cx-$rad,$cy,$col);
    
$dia $rad*2;
    
imagefilledellipse($im$x+$rad$y+$rad$rad*2$dia$col);
    
imagefilledellipse($im$x+$rad$cy-$rad$rad*2$dia$col);
    
imagefilledellipse($im$cx-$rad$cy-$rad$rad*2$dia$col);
    
imagefilledellipse($im$cx-$rad$y+$rad$rad*2$dia$col);
}

/**
 * Generate pseudorandom string consisting of letters and numbers
 *
 * @param int $length
 * @return string
 */
function get_rand_id($length)
{
global 
$lcletters$ucletters,$numbers;
$s=$lcletters.$ucletters.$numbers;
  if(
$length>0)
  { 
  
$rand_id="";
   for(
$i=1$i<=$length$i++)
   {
   
mt_srand((double)microtime() * 1000000);
   
$num mt_rand(1,strlen($s)-1);
   
$rand_id .= $s[$num];
   }
  }
return 
$rand_id;
}

/**
 * Main: Parameters
 */
$hmode=@$_GET['hmode'];
$vmode=@$_GET['vmode'];
$cmode=@$_GET['cmode'];
$smode=@$_GET['smode'];
$tmode=(isset($_GET['tmode'])?TRUE:FALSE);
$umode=(isset($_GET['umode'])?TRUE:FALSE);
$seed=@$_GET['seed'];
if (!
is_numeric($hmode))
    
$hmode=1;
if (!
is_numeric($vmode))
    
$vmode=1;
if (!
is_numeric($cmode))
    
$cmode=1;
if (!
is_numeric($smode))
    
$smode=1;
if (
$smode==1)
    {
    
$width=856;
    
$height=539;
    }
elseif (
$smode==2)
    {
    
$width=1050;
    
$height=740;
    }
elseif (
$smode==3)
    {
    
$width=1250;
    
$height=880;
    }

$fontsize=(int)$width/50;
$size=(int)$height/12;
$spacer_1=(int)$width/12;

//whydoesthegoddamngdthinghavesolongfunctionames
$image imagecreatetruecolor($width,$height);
$white imagecolorallocate($image255255255);
$gray  imagecolorallocate($image192192192);
$red imagecolorallocate($image255192192);
$green imagecolorallocate($image192255192);
$yellow imagecolorallocate($image255255192);
$blue imagecolorallocate($image192192255);
$magenta imagecolorallocate($image255192255);
$cian imagecolorallocate($image192255255);
$orange imagecolorallocate($image255204153);
$caki imagecolorallocate($image,192,192,153 );
$black imagecolorallocate($image000);
//$ = imagecolorallocate($image, ); //moar?
$colors=array($red,$orange,$yellow,$white,$green,$cian,$blue,$magenta,$gray);

imagefilledrectangle($image,0,0,$width,$height,$white);
imagefillroundedrect($image,0,0,$width,$height,30,$black);
imagefillroundedrect($image,3,3,$width-4,$height-4,26,$white);

$card_content=generate($seed);

if (
$hmode==1)
    
$header="A E I O U A E I O U A E I O U A E I O U A E I O U A";
elseif (
$hmode==2)
    
$header="0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9";
elseif (
$hmode==3)
    
$header="A B C D E F G H I J K L M N Ñ O P Q R S T U V W X Y Z";
elseif (
$hmode==4)
    
$header="a b c d e f g h i j k l m n ñ o p q r s t u v w x y z";
elseif (
$hmode==5)
    
$header="0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5";
elseif (
$hmode==6)
    
$header="000102030405060708090A0B0C0D0E0F10111213141516171819";
elseif (
$hmode==7)
    
$header="";
elseif (
$hmode==8)
    
$header="1 3 5 7 9 111315171921232527293133353739414345474951";
elseif (
$hmode==9)
    
$header="2 4 6 8 101214161820222426283032343638404244464850";
elseif (
$hmode==10)
    
$header="3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0 2 8 8 4 1 9 7 1 6 9 3 9 9 3 7 5 1 0 ";
elseif (
$hmode==12)
    
$header="B C D F G H J K L M N P Q R S T V W X Y Z B C D F G H J K L M N P Q R S T V W X Y Z";
//@TODO
//"α β γ δ ε ζ η θ ι κ λ μ ν ξ π ρ ς σ τ υ φ χ ψ ω";
if ($vmode==1)
    
$labels=array("----","---x","--w-","--wx","-r--","-r-x","-rw-","s---","s--x");
elseif (
$vmode==2)
    
$labels=array("  I"," II","III"," IV","  V"," VI","VII"," IX","  X");
elseif (
$vmode==3)
    
$labels=range(0,9);
elseif (
$vmode==4)
    
$labels=array(0,1,1,2,3,5,8,13,21,34,55,89);
elseif (
$vmode==5)
    
$labels=array(4,8,15,16,23,42,108,540,7200);
elseif (
$vmode==6)
    
$labels=array("0000","0001","0010","0011","0100","0101","0110","0111","1000");
elseif (
$vmode==7)
    
$labels=array_fill(011"");
elseif (
$vmode==8)
    
$labels=range(1,20,2);
elseif (
$vmode==9)
    
$labels=range(2,20,2);
elseif (
$vmode==10)
    
$labels="314159265358979323";
elseif (
$vmode==11)
    
$labels=array(2,3,5,7,11,13,17,19,23,29);
elseif (
$vmode==12)
    
$labels=array(1,4,9,16,25,36,49,64,81,100);
elseif (
$vmode==13)
    
$labels=array(1,2,4,8,16,32,64,128,256,512,1024);
elseif (
$vmode==15)
    
$labels="AEIOUAEIOU";
//...and I wasn't hi while doing these things, AFAICR
if ($cmode=="1")
    
shuffle($colors);
elseif (
$cmode=="2")
    
$colors=array($white,$yellow,$orange,$red,$magenta,$green,$cian,$blue,$gray);
elseif (
$cmode=="3")
    
$colors=array($gray,$white,$gray,$white,$gray,$white,$gray,$white,$gray,$white);
elseif (
$cmode=="4")
    
$colors=array($white,$white,$white,$white,$white,$white,$white,$white,$white,$white);
//@TODO: there will be always someone asking for more ways to mangle it, I give up here for now

$rows=$cols=0;
reset($colors);
//12 > 42 8)
imagettftext($image,$fontsize,0,$spacer_1+2,$spacer_1+$size-12,$black,$font,substr($header,0,$max_col*2));
imagettftext($image,$fontsize-2,0,33,$fontsize+1,$black,$font2,wordwrap($card_content[0],55,"\n",true));
while(
$rows<$max_row)
    {
    
$line="";
    
$rows++;
    
imagefilledrectangle($image4$spacer_1+$size*$rows$width-6$spacer_1+$size+($size*$rows), current($colors));
    
next($colors);
    while(
$cols<$max_col)
        {
        
$cols++;
        if (
$umode==TRUE && (in_array($cols,array(5,10,18)))) //y 5, 10 and 18? U'll sht bricks when u know y
            
$card_content[1][$cols*$rows]=strtr($card_content[1][$cols*$rows],$lcletters.$ucletters."0123456789",str_repeat($symbols,5)); //don't ask why didnt $numbers come up here, it's too late now
        
$line.=$card_content[1][$cols*$rows]." ";
        }
    if (
$rows>&& $tmode==TRUE)
        
$line=strtr($line,$lcletters.$ucletters.$symbols,str_repeat($numbers,8));
    
imagettftext($image,$fontsize-4,0,12,$spacer_1+$size*($rows+1)-12,$black,$font,$labels[$rows-1]);
    
imagettftext($image,$fontsize,0,$spacer_1+2,$spacer_1+$size*($rows+1)-12,$black,$font,$line);
    
$cols=0;
    }

header('Content-type: image/png');
imagepng($image);
//and just like during the iconoclasm
imagedestroy($image);
?>