#!/usr/bin/python

# rgbhsv.py
#       --copyright--                   Copyright 2012 (C) Tranzoa, Co. All rights reserved.    Warranty: You're free and on your own here. This code is not necessarily up-to-date or of public quality.
#       --url--                         http://www.tranzoa.net/tzpython/
#       --email--                       pycode is the name to send to. tranzoa.com is the place to send to.
#       --bodstamps--
#       November 25, 2012       bar
#       September 23, 2013      bar     correct namespace
#       --eodstamps--
##      \file
#       \namespace              tzpython.rgbhsv
#
#
#       Convert between RGB and HSV as borrowed from:   http://www.csgnetwork.com/csgcolorsel4.html
#
#

import  re

class   an_rgb(object) :

    def __init__(me, r, g, b) :
        me.r    = max(0, min(255, r))
        me.g    = max(0, min(255, g))
        me.b    = max(0, min(255, b))

    def to_hsv(me) :
        r   = me.r / 255.0
        g   = me.g / 255.0
        b   = me.b / 255.0

        mn  = min(r, g, b)
        mx  = max(r, g, b)
        dl  = mx - mn

        if  not dl :
            h   = 0
            s   = 0
        else    :
            s   = dl / mx
            dr  = (((mx - r) / 6.0) + (dl / 2.0)) / dl
            dg  = (((mx - g) / 6.0) + (dl / 2.0)) / dl
            db  = (((mx - b) / 6.0) + (dl / 2.0)) / dl

            if  r  == mx :
                h   = db - dg
            elif g == mx :
                h   = (1 / 3.0) + dr - db
            elif b == mx :
                h   = (2 / 3.0) + dg - dr

            if  h   < 0 :
                h  += 1
            if  h   > 1 :
                h  -= 1
            pass

        return(an_hsv(h * 360.0, s * 100.0, mx * 100.0))


    def __str__(me) :
        return("R:%u G:%u B:%u #%02x%02x%02x" % ( round(me.r), round(me.g), round(me.b), round(me.r), round(me.g), round(me.b) ) )


    #   an_rgb



class   an_hsv(object) :

    def __init__(me, h, s, v) :
        me.h    = max(0, min(360, h))
        me.s    = max(0, min(100, s))
        me.v    = max(0, min(100, v))

    def to_rgb(me) :
        h   = me.h  / 360.0
        s   = me.s  / 100.0
        v   = me.v  / 100.0
        if  not s :
            r   = v
            g   = v
            b   = v
        else    :
            h  *= 6.0
            i   = int(h)
            v1  = v * (1.0 - s)
            v2  = v * (1.0 - s * (h - i))
            v3  = v * (1.0 - s * (1.0 - (h - i)))

            if  i  == 0 :
                r   = v
                g   = v3
                b   = v1
            elif i == 1 :
                r   = v2
                g   = v
                b   = v1
            elif i == 2 :
                r   = v1
                g   = v
                b   = v3
            elif i == 3 :
                r   = v1
                g   = v2
                b   = v
            elif i == 4 :
                r   = v3
                g   = v1
                b   = v
            else    :
                r   = v
                g   = v1
                b   = v2
            pass

        return(an_rgb(r * 255.0, g * 255.0, b * 255.0))


    def __str__(me) :
        return("H:%u S:%u V:%u" % ( round(me.h), round(me.s), round(me.v), ) )


    #   an_hsv



def parse_color(s) :
    s   = s.lstrip('#').strip().lower()

    g   = re.match(r'^([0-9a-z][0-9a-z])([0-9a-z][0-9a-z])([0-9a-z][0-9a-z])$', s)
    if  g :
        c   = an_rgb(int(g.group(1), 16), int(g.group(2), 16), int(g.group(3), 16))
        oc  = c.to_hsv()

        return(c, oc)

    g   = re.search(r'^(\d+)\s*\.\s*(\d+)\s*\.\s*(\d+)$', s)
    if  g :
        c   = an_rgb(int(g.group(1)), int(g.group(2)), int(g.group(3)))
        oc  = c.to_hsv()

        return(c, oc)

    g   = re.search(r'^(\d+)\s*\,\s*(\d+)\s*\,\s*(\d+)$', s)
    if  g :
        c   = an_rgb(int(g.group(1)), int(g.group(2)), int(g.group(3)))
        oc  = c.to_hsv()

        return(c, oc)

    g   = re.search(r'^(\d+)\s*\:\s*(\d+)\s*\:\s*(\d+)$', s)
    if  g :
        c   = an_hsv(int(g.group(1)), int(g.group(2)), int(g.group(3)))
        oc  = c.to_rgb()

        return(c, oc)

    return(None, None)



help_str    = """
%s (options)    RGB__in__#web_color__or__r.g.b__or__r,g,b__form   HSV__in__h:s:v__form    ...

Options:

    --gimp  color   color       Tell Gimp Colors|Hue-Saturation values to set to change first color to second.


Convert RGB to HSV or vice versa.

HSV is in H:0..360 S:0..100 V:0..100 form.
RGB is in 0..255 form.

"""

if  __name__ == '__main__' :
    import  os
    import  sys

    import  tzlib
    import  TZCommandLineAtFile


    program_name    = sys.argv.pop(0)
    TZCommandLineAtFile.expand_at_sign_command_line_files(sys.argv)


    while True :
        oi  = tzlib.array_find(sys.argv, [ "--help", "-h", "-?", "/?", "/h", "/H" ] )
        if  oi < 0 :    break
        del sys.argv[oi]
        print help_str % ( os.path.basename(program_name), )

        sys.exit(254)


    while len(sys.argv) :
        a   = sys.argv.pop(0)

        if  a in [ "--gimp", "-g", ] :
            c1      = parse_color(sys.argv.pop(0))[0]
            c2      = parse_color(sys.argv.pop(0))[0]
            if  not isinstance(c1, an_hsv) :
                c1  = c1.to_hsv()
            if  not isinstance(c2, an_hsv) :
                c2  = c2.to_hsv()
            h       = (c2.h - c1.h)
            while h < -180 :    h  +=  360
            while h >  180 :    h  -=  360
            s       = (c2.s - c1.s)
            v       = (c2.v - c1.v)
            print "Try to convert", c1.to_rgb(), c1, "    to    ", c2.to_rgb(), c2, "    with these values:  H", round(h), "L", round(v), "S", round(s)
        else            :
            (c1, c2 )   = parse_color(a)
            if  not c1  :
                print "I do not understand %s!" % a
                sys.exit(101)

            print c1, c2

        pass

    pass


#
#
# eof
