#!/usr/bin/perl

use v5.12;
use warnings;
use lib 'lib', '../lib/';
use Test::More tests => 90;
use Test::Warn;
use Graphics::Toolkit::Color::Space::Util ':all';

my $module = 'Graphics::Toolkit::Color';
eval "use $module qw/color is_in_gamut/";

is( not( $@), 1, 'could load the module'); # say $@; exit 0;
warning_like {Graphics::Toolkit::Color->new()} {carped => qr/accepts the arguments/}, 'constructor need arguments';
is( ref Graphics::Toolkit::Color->new('red'), $module, 'method "new" accepts color names');
warning_like {Graphics::Toolkit::Color->new('red', 'green')} {carped => qr/Could not deformat/}, 'constructor needs only one color name';
#~ is( ref Graphics::Toolkit::Color->new('SVG::red'), $module, 'constructor accepts color name from a scheme');
is( ref Graphics::Toolkit::Color->new('#000'),     $module, 'short hex string with min value');
is( ref Graphics::Toolkit::Color->new('#FFFFFF'),  $module, 'long hex string with max value');
is( ref Graphics::Toolkit::Color->new('#1ab2cc'),  $module, 'long hex string with mixed uc and lc vlaues');
warning_like {Graphics::Toolkit::Color->new('#abj')}     {carped => qr/Could not deformat/}, 'short hex string has typo';
warning_like {Graphics::Toolkit::Color->new('#AABBGG')}  {carped => qr/Could not deformat/}, 'long hex string has typo';
warning_like {Graphics::Toolkit::Color->new('#AA')}      {carped => qr/Could not deformat/}, 'short hex string is too short';
warning_like {Graphics::Toolkit::Color->new('#AABF')}    {carped => qr/Could not deformat/}, 'short hex string is too long';
warning_like {Graphics::Toolkit::Color->new('#AABBF')}   {carped => qr/Could not deformat/}, 'long hex string is too short';
warning_like {Graphics::Toolkit::Color->new('#AABBFFF')} {carped => qr/Could not deformat/}, 'long hex string is too long';
is( ref Graphics::Toolkit::Color->new('rgb(0, 0, 0)'),          $module, 'CSS string format');
is( ref Graphics::Toolkit::Color->new('lab( 12.3, 5.4, 1.2)'),  $module, 'CSS string in LAB space');
warning_like {Graphics::Toolkit::Color->new('lab( 12.3, 5.4, 1.2%)')}{carped => qr/Could not deformat/}, 'CSS string with bad suffix';
is( ref Graphics::Toolkit::Color->new('YIQ:5.22,   0, -10  '), $module, 'named string in YIQ space and additional spacing');
is( ref Graphics::Toolkit::Color->new('NCol: B10,  100, 0'),   $module, 'named string in Ncol space with min and max values');
warning_like {Graphics::Toolkit::Color->new(4)}          {carped => qr/Could not deformat/}, 'constructor needs more than one number but full RGB value list';
warning_like {Graphics::Toolkit::Color->new(4,5)}        {carped => qr/Could not deformat/}, 'constructor needs more than two numbers';
is( ref Graphics::Toolkit::Color->new( 1,2,3),  $module, 'constructor got three RGB values');
is( ref Graphics::Toolkit::Color->new( 4,5,6,7),$module, 'constructor CMYK values');
warning_like {Graphics::Toolkit::Color->new(4,5,6,7,8)}  {carped => qr/Could not deformat/}, 'constructor got too many numeric values';
warning_like {Graphics::Toolkit::Color->new('%', 2, 4)}  {carped => qr/Could not deformat/}, 'first RGB value has to be number';
warning_like {Graphics::Toolkit::Color->new(1, '2a', 4)} {carped => qr/Could not deformat/}, 'second RGB value has to be number';
warning_like {Graphics::Toolkit::Color->new(1,2,'e4')}   {carped => qr/Could not deformat/}, 'third RGB value has to be number';
warning_like {Graphics::Toolkit::Color->new([4,5])}      {carped => qr/Could not deformat/}, 'constructor needs more than two numbers in an ARRAY';
is( ref Graphics::Toolkit::Color->new( [4,5,6,7]),  $module, 'constructor interprets 4 values ARRAY as CMYK tuple');
warning_like {Graphics::Toolkit::Color->new([4,5,6,7,8])}{carped => qr/Could not deformat/}, 'constructor got too many number values in ARRAY';
is( ref Graphics::Toolkit::Color->new( [1,2,3]), $module, 'constructor got three RGB numbers in an ARRAY');
is( ref Graphics::Toolkit::Color->new( ['YUV',1,2,3]), $module, 'named ARRAY in YUV space');
warning_like {Graphics::Toolkit::Color->new(['YUV',1,2])}{carped => qr/Could not deformat/}, 'named ARRAY in YUV space got not enough values';
warning_like {Graphics::Toolkit::Color->new(['YUV',1,2,3,4])}{carped => qr/Could not deformat/}, 'named ARRAY in YUV space got too many values';
is( ref Graphics::Toolkit::Color->new( ['cmyk',1,0,0,0]), $module, 'named ARRAY in CMYK space');
warning_like {Graphics::Toolkit::Color->new(['cmyk',1,0,0])}{carped => qr/Could not deformat/}, 'CMYK named ARRAY got not enough values';
warning_like {Graphics::Toolkit::Color->new(['cmyk',1,0,0,0,0])}{carped => qr/Could not deformat/}, 'CMYK named ARRAY got too much values';
warning_like {Graphics::Toolkit::Color->new(['cmk', 0,0,0])}{carped => qr/Could not deformat/}, 'named ARRAY with unknown color space name';
is( ref Graphics::Toolkit::Color->new( ['CIELCHab', 0, 0, 0]),          $module, 'long mixed case alias names work too');
is( ref Graphics::Toolkit::Color->new( ['hsb', 100.23, 0.173, .214]),   $module, 'different number shapes');
is( ref Graphics::Toolkit::Color->new( ['NCol','B10','100%','0%']),     $module, 'named ARRAY with values that need preprocessing');
is( ref Graphics::Toolkit::Color->new( ['ncol','B0','100','0']),        $module, 'try single digit string value');
is( ref Graphics::Toolkit::Color->new( OKLAB => [0,0,0] ),              $module, 'named ARRAY ref in uc oklab space');
is( ref Graphics::Toolkit::Color->new( [OKLAB => [0,0,0]] ),            $module, 'named ARRAY ref, nsted version');
is( ref Graphics::Toolkit::Color->new( 'hunterlab', [1,2,3] ),          $module, 'named ARRAY ref in lc hunterlab space');
warning_like {Graphics::Toolkit::Color->new({ })}{carped => qr/Could not deformat/}, 'HASH needs keys (axis names)';
warning_like {Graphics::Toolkit::Color->new({r=> 1 })}{carped => qr/Could not deformat/}, 'one HASH key is not enough';
warning_like {Graphics::Toolkit::Color->new( r=> 1 )}{carped => qr/Could not deformat/}, 'one key withouth HASH ref (curly braces) is not enough';
warning_like {Graphics::Toolkit::Color->new({r=> 1, g=>2 })}{carped => qr/Could not deformat/}, 'two HASH keys are not enough';
warning_like {Graphics::Toolkit::Color->new( r=> 1, g=>2 )}{carped => qr/Could not deformat/}, 'two keys withouth HASH ref (curly braces) are not enough';
is( ref Graphics::Toolkit::Color->new( {r => 0, g => 0, b => 0 }),         $module, 'RGB short HASH');
is( ref Graphics::Toolkit::Color->new( r => 0, g => 0, b => 0 ),           $module, 'RGB short axis name HASH without ref (curly braces)');
is( ref Graphics::Toolkit::Color->new( red => 0, G => 0, b => 0 ),         $module, 'can mix long and short, lc and uc axis names');
warning_like {Graphics::Toolkit::Color->new({r => 0, g => 0, b => 0, y=> 1 })}{carped => qr/Could not deformat/}, 'too many HASH keys';
warning_like {Graphics::Toolkit::Color->new( r => 0, g => 0, b => 0, y=> 1)}  {carped => qr/Could not deformat/}, 'too many keys without HASH';
is( ref Graphics::Toolkit::Color->new( c => 0, m => 0, k => 0, y=> 1),     $module, 'CMYK hash');
warning_like {Graphics::Toolkit::Color->new(c => 0, m => 0, kkey => 0, y=> 1)}{carped => qr/Could not deformat/}, 'one key has typo';
warning_like {Graphics::Toolkit::Color->new( c => 0, m => 0, k=> 1)}          {carped => qr/Could not deformat/}, 'one CMYK key is missing';
is( ref Graphics::Toolkit::Color->new( luma => 0, Pb => 0, Pr=> .5),       $module, 'YPbPr hash');
is( ref Graphics::Toolkit::Color->new( 'L*' => 0, 'a*' => '100','b*'=> .5),$module, 'LAB hash');
is( ref Graphics::Toolkit::Color->new( 'L*'=> 0, 'a*'=> '10e0', 'b*'=> .5),$module, 'accepts scientific notation in numbers');
is( ref Graphics::Toolkit::Color->new( l => 0,  chroma => '0',  hue => 0), $module, 'CIELCHuv hash');
warning_like {Graphics::Toolkit::Color->new( l => "0%",  c => '0',  hue => 0)}          {carped => qr/Could not deformat/}, 'CIELCHuv Hash with bad value suffix';
is( ref Graphics::Toolkit::Color->new( h => "0",  w => '0',  b => 0),      $module, 'HWB hash');
is( ref Graphics::Toolkit::Color->new( h=> "R100",w => '0%', b=> '100%'),  $module, 'NCol hash');
is( ref Graphics::Toolkit::Color->new( Y => 0, U => 0, V => 100),          $module, 'YPbPr short hash');
is( ref Graphics::Toolkit::Color->new( X => 0, Y => 0, Z => 0),            $module, 'XYZ short hash (has no long names)');
is( ref Graphics::Toolkit::Color->new( X => 0, Y => 0, Z => 0),            $module, 'XYZ short hash (has no long names)');
is( ref Graphics::Toolkit::Color->new( color => [4,5,6], range => 10),     $module, 'use color/range arguments for cutom ranged color');
is( ref Graphics::Toolkit::Color->new( range => 10, color => [4,5,6] ),    $module, 'args work in reverse order too');
is( ref Graphics::Toolkit::Color->new( color=> [4,5,6], range=>{r=>10, g=> 20, b => 6} ),    $module, 'custom range definition via hash');
is( ref Graphics::Toolkit::Color->new( raw => 10, color => [4,5,6] ),      $module, 'do not clamp values');
warning_like {Graphics::Toolkit::Color->new( raw => 10, range => [4,5,6])}          {carped => qr/Could not deformat/}, 'constructor with arguments but no color definition';
warning_like {Graphics::Toolkit::Color->new( color => 'green', color => [4,5,6])}   {carped => qr/got an argument twice/}, 'GTC checks for argument duplication';

is( ref color( Y => 0, U => 0, V => 100),          $module, 'short named constructor method');
warning_like {color( )}            {carped => qr/without color definition/}, '"color" routine needs arguments';
warning_like {color( 1,1 )}        {carped => qr/Could not deformat/}, 'two numeric values are not enough';
warning_like {color( 1,1,1,1,1 )}  {carped => qr/Could not deformat/}, 'five numeric values are too much';
is( ref color( 1,1,1,1),                           $module, 'four values are seen as CMYK');
is( ref color( '#0000ff' ),                        $module, 'can also recieve lc hex sting');
is( ref color( [1,2,3] ),                          $module, 'ARRAY ref');
is( ref color( {l => 50, c => 12.4, h => .6} ),    $module, 'LCH short axis name HASH');
is( ref color( {hue => 0, whiteness => '0%', blackness => '100%'} ), $module, 'HWB long axis name HASH');

warning_like {is_in_gamut()}  {carped => qr/without color definition/}, 'can not call "is_in_gamut" routine without any color';
is( is_in_gamut(0,0,0),                1, 'is_in_gamut detect RGB black in list format as valid color');
is( is_in_gamut([255,255,255]),        1, 'is_in_gamut detect RGB white in ARRAY format as valid color');
is( is_in_gamut(RGB => [255,255,256]), 0, 'is_in_gamut routine detected out of range RGB color');
is( is_in_gamut({c => 1, m => 1, y => 1, k => 1,}), 1, 'is_in_gamut takes also HASH format');
is( is_in_gamut('hsl: 10,10,10'),      1, 'is_in_gamut detected normal HSL color');
is( is_in_gamut('hsl: -10,10,10'),     1, 'is_in_gamut ignores out of range values on cylindrical axis');
is( is_in_gamut('hsl: 10,-10,10'),     0, 'is_in_gamut detecteds out of value in HSL color');

exit 0;
