#############################################################################
# Convert.pm
# Color conversion stuff
####
#                 needs: Graphics::ColorObject
#        debian pkgname: libgraphics-colorobject-perl
#############################################################################
package Color::Convert;

# Graphics::ColorObject -- Official Perl Libraries for color conversion
use Graphics::ColorObject;

require Exporter;

our @ISA = 'Exporter';

our @EXPORT = qw{
    magentaIsolate yellowIsolate cyanIsolate primaryOpposite
    rgbTOhsv rgbTOhhsv rgbTOcmyk rgbTOlab
    colorOpposite wheelComplement percentTint percentShade
};

our @EXPORT_OK = qw{
    rgbTOcmy distance rgb_xyz
};

sub magentaIsolate
{
    my ( $r, $g, $b ) = @_;

    return ( $r, 0, $b );
}

sub yellowIsolate
{
    my ( $r, $g, $b ) = @_;

    return ( $r, $g, 0 );
}

sub cyanIsolate
{
    my ( $r, $g, $b ) = @_;

    return ( 0, $g, $b );
}

sub primaryOpposite
{
    my ( $r, $g, $b ) = @_;

    foreach my $c ( $r, $g, $b ) {
        if ( 128 >= $c ) {
            $c = 255;
        }
        else {
            $c = 0;
        }
    }

    return ( $r, $g, $b );
}

sub rgbTOhsv
{
    my ( $r, $g, $b ) = @_;

    my $clr = Graphics::ColorObject->new_RGB255([$r, $g, $b]);

    return @{ $clr->as_HSV() };
}

# As above, but also output h as a percentage (instead of degrees)
sub rgbTOhhsv
{
    my ( $r, $g, $b ) = @_;

    my ( $h, $s, $v ) = rgbTOhsv($r, $g, $b);
    my $h_perc = 0;
    if ( 0 != $h ) {
        $h_perc = ( $h / 360 );
    }

    return ( $h, (100*$h_perc), $s, $v );
}

sub rgbTOcmy
{
    my ( $r, $g, $b ) = @_;

    my $clr = Graphics::ColorObject->new_RGB255([$r, $g, $b]);

    return @{ $clr->as_CMY() };
}

sub rgbTOcmyk
{
    my ( $r, $g, $b ) = @_;

    my $clr = Graphics::ColorObject->new_RGB255([$r, $g, $b]);

    return @{ $clr->as_CMYK() };
}

# Ported from color-namer.js (github user zeke, MIT License)
# Euclidean distance
sub distance
{
    my ( $aL, $aA, $aB, $bL, $bA, $bB ) = @_;
    my $sum = 0;
    $sum += ( $aL - $bL ) ** 2;
    $sum += ( $aA - $bA ) ** 2;
    $sum += ( $aB - $bB ) ** 2;
    return sqrt($sum);
}

sub rgbTOlab
{
    my ( $r, $g, $b ) = @_;

    my $clr = Graphics::ColorObject->new_RGB255([$r, $g, $b]);

    return @{ $clr->as_Lab() };
}

sub rgb_xyz
{
    my ( $r, $g, $b ) = @_;

    my $clr = Graphics::ColorObject->new_RGB255([$r, $g, $b]);

    return @{ $clr->as_XYZ() };
}


sub colorOpposite
{
    my ( $r, $g, $b ) = @_;

    foreach my $c ( $r, $g, $b ) {
        $c = 255 - $c;
    }

    return ( $r, $g, $b );
}


sub wheelComplement
{
    my ( $r, $g, $b ) = @_;

    my ( $h, $s, $v ) = rgbTOhsv($r, $g, $b);

    $h -= 180;
    if ( 0 > $h ) {
        $h += 360;
    }

    my $clr = Graphics::ColorObject->new_HSV([$h, $s, $v]);

    return @{ $clr->as_RGB255() };

### Original function.
#    my ( $r, $g, $b ) = @_;
#
#    my $max = ( $r>$g?$r:$g );
#    $max = ( $max>$b?$max:$b );
#    my $min = ( $r<$g?$r:$g );
#    $min = ( $min<$b?$min:$b );
#    my $rng = $max - $min;
#
#    if ( 0 == $rng ) {
#        # No color (greyscale) just return original.
#    }
#    else {
#        foreach my $c ( $r, $g, $b ) {
#            my $i = $c - $min;
#            $c = $min + ($rng - $i);
#        }
#    }
#
#    return ( $r, $g, $b );
}


sub percentTint
{
    my $percent = shift;
    $percent = 100 - $percent;
    my ( $r, $g, $b ) = @_;

    foreach my $c ( $r, $g, $b ) {
        $c = $c + int( ( 255 - $c ) * ( $percent / 100 ) );
    }

    return ( $r, $g, $b );
}


sub percentShade
{
    my $percent = shift;
    my ( $r, $g, $b ) = @_;

    foreach my $c ( $r, $g, $b ) {
        $c = int( $c * ( $percent / 100 ) );
    }

    return ( $r, $g, $b );
}

1;
# EOF Convert.pm
