<?php
namespace app\helpers;

class Avatar
{
	private static 	$spriteZ=128;
    public static function get( $id, $size )
    {

		$csh=hexdec(substr($id,0,1)); // corner sprite shape
		$ssh=hexdec(substr($id,1,1)); // side sprite shape
		$xsh=hexdec(substr($id,2,1))&7; // center sprite shape

		$cro=hexdec(substr($id,3,1))&3; // corner sprite rotation
		$sro=hexdec(substr($id,4,1))&3; // side sprite rotation
		$xbg=hexdec(substr($id,5,1))%2; // center sprite background

		/* corner sprite foreground color */
		$cfr=hexdec(substr($id,6,2));
		$cfg=hexdec(substr($id,8,2));
		$cfb=hexdec(substr($id,10,2));

		/* side sprite foreground color */
		$sfr=hexdec(substr($id,12,2));
		$sfg=hexdec(substr($id,14,2));
		$sfb=hexdec(substr($id,16,2));

		/* final angle of rotation */
		$angle=hexdec(substr($id,18,2));

		/* size of each sprite */

		/* start with blank 3x3 identicon */
		$identicon=imagecreatetruecolor(self::$spriteZ*3,self::$spriteZ*3);
		imageantialias($identicon,TRUE);

		/* assign white as background */
		$bg=imagecolorallocate($identicon,255,255,255);
		imagefilledrectangle($identicon,0,0,self::$spriteZ,self::$spriteZ,$bg);


		/* generate corner sprites */

		$corner=self::getsprite($csh,$cfr,$cfg,$cfb,$cro);
		imagecopy($identicon,$corner,0,0,0,0,self::$spriteZ,self::$spriteZ);
		$corner=imagerotate($corner,1,$bg);
		imagecopy($identicon,$corner,0,self::$spriteZ*2,0,0,self::$spriteZ,self::$spriteZ);
		$corner=imagerotate($corner,1,$bg);
		imagecopy($identicon,$corner,self::$spriteZ*2,self::$spriteZ*2,0,0,self::$spriteZ,self::$spriteZ);
		$corner=imagerotate($corner,1,$bg);
		imagecopy($identicon,$corner,self::$spriteZ*2,0,0,0,self::$spriteZ,self::$spriteZ);

		/* generate side sprites */
		$side=self::getsprite($ssh,$sfr,$sfg,$sfb,$sro);
		imagecopy($identicon,$side,self::$spriteZ,0,0,0,self::$spriteZ,self::$spriteZ);
		$side=imagerotate($side,1,$bg);
		imagecopy($identicon,$side,0,self::$spriteZ,0,0,self::$spriteZ,self::$spriteZ);
		$side=imagerotate($side,1,$bg);
		imagecopy($identicon,$side,self::$spriteZ,self::$spriteZ*2,0,0,self::$spriteZ,self::$spriteZ);
		$side=imagerotate($side,90,$bg);
		imagecopy($identicon,$side,self::$spriteZ*2,self::$spriteZ,0,0,self::$spriteZ,self::$spriteZ);

		/* generate center sprite */
		$center=self::getcenter($xsh,$cfr,$cfg,$cfb,$sfr,$sfg,$sfb,$xbg);
		imagecopy($identicon,$center,self::$spriteZ,self::$spriteZ,0,0,self::$spriteZ,self::$spriteZ);

		// $identicon=imagerotate($identicon,$angle,$bg);

		/* make white transparent */
		imagecolortransparent($identicon,$bg);

		/* create blank image according to specified dimensions */
		$resized=imagecreatetruecolor($size,$size);
		imageantialias($resized,TRUE);
		imagealphablending($resized, true);

		/* assign white as background */
		$bg=imagecolorallocate($resized,255,255,255);
		imagefilledrectangle($resized,0,0,$size,$size,$bg);

		/* resize identicon according to specification */
		imagecopyresampled($resized,$identicon,0,0,(imagesx($identicon)-self::$spriteZ*3)/2,(imagesx($identicon)-self::$spriteZ*3)/2,$size,$size,self::$spriteZ*3,self::$spriteZ*3);

		//imagefilter($resized,  IMG_FILTER_MEAN_REMOVAL, 1);
//		imagefilter($resized,  IMG_FILTER_SMOOTH, 0.1);
//		imagefilter($resized,  IMG_FILTER_SELECTIVE_BLUR, 1);



		//create masking
		/*
		 *    $newwidth = $size;
		 *    $newheight = $newwidth;
		 *    $mask = imagecreatetruecolor($newwidth, $newheight);
		 *    $transparent = imagecolorallocate($mask, 255, 0, 0);
		 *    imagecolortransparent($mask,$transparent);
		 *    imagefilledellipse($mask, $newwidth/2, $newheight/2, $newwidth, $newheight, $transparent);
		 *    $red = imagecolorallocate($mask, 0, 0, 0);
		 *    imagecopymerge($resized, $mask, 0, 0, 0, 0, $newwidth, $newheight, 100);
		 *    imagecolortransparent($resized,$red);
		 *    imagefill($resized, 0, 0, $red);
		 */
		/* make white transparent */
		//imagecolortransparent($resized,$bg);

		/* and finally, send to standard output */
		//header("Content-Type: image/png");
		ob_start();
			imagepng($resized);
		return ob_get_clean();

	}


	public static function getsprite($shape,$R,$G,$B,$rotation) {
	//	global self::$spriteZ;
		$sprite=imagecreatetruecolor(self::$spriteZ,self::$spriteZ);
		imageantialias($sprite,TRUE);
		$fg=imagecolorallocate($sprite,$R,$G,$B);
		$bg=imagecolorallocate($sprite,255,255,255);
		imagefilledrectangle($sprite,0,0,self::$spriteZ,self::$spriteZ,$bg);
		switch($shape) {
			case 0: // triangle
				$shape=array(
					0.5,1,
				 1,0,
				 1,1
				);
				break;
			case 1: // parallelogram
				$shape=array(
					0.5,0,
				 1,0,
				 0.5,1,
				 0,1
				);
				break;
			case 2: // mouse ears
				$shape=array(
					0.5,0,
				 1,0,
				 1,1,
				 0.5,1,
				 1,0.5
				);
				break;
			case 3: // ribbon
				$shape=array(
					0,0.5,
				 0.5,0,
				 1,0.5,
				 0.5,1,
				 0.5,0.5
				);
				break;
			case 4: // sails
				$shape=array(
					0,0.5,
				 1,0,
				 1,1,
				 0,1,
				 1,0.5
				);
				break;
			case 5: // fins
				$shape=array(
					1,0,
				 1,1,
				 0.5,1,
				 1,0.5,
				 0.5,0.5
				);
				break;
			case 6: // beak
				$shape=array(
					0,0,
				 1,0,
				 1,0.5,
				 0,0,
				 0.5,1,
				 0,1
				);
				break;
			case 7: // chevron
				$shape=array(
					0,0,
				 0.5,0,
				 1,0.5,
				 0.5,1,
				 0,1,
				 0.5,0.5
				);
				break;
			case 8: // fish
				$shape=array(
					0.5,0,
				 0.5,0.5,
				 1,0.5,
				 1,1,
				 0.5,1,
				 0.5,0.5,
				 0,0.5
				);
				break;
			case 9: // kite
				$shape=array(
					0,0,
				 1,0,
				 0.5,0.5,
				 1,0.5,
				 0.5,1,
				 0.5,0.5,
				 0,1
				);
				break;
			case 10: // trough
				$shape=array(
					0,0.5,
				 0.5,1,
				 1,0.5,
				 0.5,0,
				 1,0,
				 1,1,
				 0,1
				);
				break;
			case 11: // rays
				$shape=array(
					0.5,0,
				 1,0,
				 1,1,
				 0.5,1,
				 1,0.75,
				 0.5,0.5,
				 1,0.25
				);
				break;
			case 12: // double rhombus
				$shape=array(
					0,0.5,
				 0.5,0,
				 0.5,0.5,
				 1,0,
				 1,0.5,
				 0.5,1,
				 0.5,0.5,
				 0,1
				);
				break;
			case 13: // crown
				$shape=array(
					0,0,
				 1,0,
				 1,1,
				 0,1,
				 1,0.5,
				 0.5,0.25,
				 0.5,0.75,
				 0,0.5,
				 0.5,0.25
				);
				break;
			case 14: // radioactive
				$shape=array(
					0,0.5,
				 0.5,0.5,
				 0.5,0,
				 1,0,
				 0.5,0.5,
				 1,0.5,
				 0.5,1,
				 0.5,0.5,
				 0,1
				);
				break;
			default: // tiles
				$shape=array(
					0,0,
				 1,0,
				 0.5,0.5,
				 0.5,0,
				 0,0.5,
				 1,0.5,
				 0.5,1,
				 0.5,0.5,
				 0,1
				);
				break;
		}
		/* apply ratios */
		for ($i=0;$i<count($shape);$i++)
			$shape[$i]=$shape[$i]*self::$spriteZ;
		imagefilledpolygon($sprite,$shape,count($shape)/2,$fg);
		/* rotate the sprite */
		for ($i=0;$i<$rotation;$i++)
			$sprite=imagerotate($sprite,90,$bg);
		return $sprite;
	}

	/* generate sprite for center block */
	public static function getcenter($shape,$fR,$fG,$fB,$bR,$bG,$bB,$usebg) {
	//	global self::$spriteZ;
		$sprite=imagecreatetruecolor(self::$spriteZ,self::$spriteZ);
		imageantialias($sprite,TRUE);
		$fg=imagecolorallocate($sprite,$fR,$fG,$fB);
		/* make sure there's enough contrast before we use background color of side sprite */
		if ($usebg>0 && (abs($fR-$bR)>127 || abs($fG-$bG)>127 || abs($fB-$bB)>127))
			$bg=imagecolorallocate($sprite,$bR,$bG,$bB);
		else
			$bg=imagecolorallocate($sprite,255,255,255);
		imagefilledrectangle($sprite,0,0,self::$spriteZ,self::$spriteZ,$bg);
		switch($shape) {
			case 0: // empty
				$shape=array();
				break;
			case 1: // fill
				$shape=array(
					0,0,
				 1,0,
				 1,1,
				 0,1
				);
				break;
			case 2: // diamond
				$shape=array(
					0.5,0,
				 1,0.5,
				 0.5,1,
				 0,0.5
				);
				break;
			case 3: // reverse diamond
				$shape=array(
					0,0,
				 1,0,
				 1,1,
				 0,1,
				 0,0.5,
				 0.5,1,
				 1,0.5,
				 0.5,0,
				 0,0.5
				);
				break;
			case 4: // cross
				$shape=array(
					0.25,0,
				 0.75,0,
				 0.5,0.5,
				 1,0.25,
				 1,0.75,
				 0.5,0.5,
				 0.75,1,
				 0.25,1,
				 0.5,0.5,
				 0,0.75,
				 0,0.25,
				 0.5,0.5
				);
				break;
			case 5: // morning star
				$shape=array(
					0,0,
				 0.5,0.25,
				 1,0,
				 0.75,0.5,
				 1,1,
				 0.5,0.75,
				 0,1,
				 0.25,0.5
				);
				break;
			case 6: // small square
				$shape=array(
					0.33,0.33,
				 0.67,0.33,
				 0.67,0.67,
				 0.33,0.67
				);
				break;
			case 7: // checkerboard
				$shape=array(
					0,0,
				 0.33,0,
				 0.33,0.33,
				 0.66,0.33,
				 0.67,0,
				 1,0,
				 1,0.33,
				 0.67,0.33,
				 0.67,0.67,
				 1,0.67,
				 1,1,
				 0.67,1,
				 0.67,0.67,
				 0.33,0.67,
				 0.33,1,
				 0,1,
				 0,0.67,
				 0.33,0.67,
				 0.33,0.33,
				 0,0.33
				);
				break;
		}
		/* apply ratios */
		for ($i=0;$i<count($shape);$i++)
			$shape[$i]=$shape[$i]*self::$spriteZ;
		if (count($shape)>0)
			imagefilledpolygon($sprite,$shape,count($shape)/2,$fg);
		return $sprite;
	}


}
