"""Pynche -- The PYthon Natural Color and Hue Editor.

Contact: %(AUTHNAME)s
Email:   %(AUTHEMAIL)s
Version: %(__version__)s

Pynche is based largely on a similar color editor I wrote years ago for the
SunView window system.  That editor was called ICE: the Interactive Color
Editor.  I'd always wanted to port the editor to X but didn't feel like
hacking X and C code to do it.  Fast forward many years, to where Python +
Tkinter provides such a nice programming environment, with enough power, that
I finally buckled down and implemented it.  I changed the name because these
days, too many other systems have the acronym `ICE'.

This program currently requires Python 2.2 with Tkinter.

Usage: %(PROGRAM)s [-d file] [-i file] [-X] [-v] [-h] [initialcolor]

Where:
    --database file
    -d file
        Alternate location of a color database file

    --initfile file
    -i file
        Alternate location of the initialization file.  This file contains a
        persistent database of the current Pynche options and color.  This
        means that Pynche restores its option settings and current color when
        it restarts, using this file (unless the -X option is used).  The
        default is ~/.pynche

    --ignore
    -X
        Ignore the initialization file when starting up.  Pynche will still
        write the current option settings to this file when it quits.

    --version
    -v
        print the version number and exit

    --help
    -h
        print this message

    initialcolor
        initial color, as a color name or #RRGGBB format
"""

__version__ = '1.4.1'

import sys
import os
import getopt
import ColorDB

from PyncheWidget import PyncheWidget
from Switchboard import Switchboard
from StripViewer import StripViewer
from ChipViewer import ChipViewer
from TypeinViewer import TypeinViewer



PROGRAM = sys.argv[0]
AUTHNAME = 'Barry Warsaw'
AUTHEMAIL = 'barry@python.org'

# Default locations of rgb.txt or other textual color database
RGB_TXT = [
    # Solaris OpenWindows
    '/usr/openwin/lib/rgb.txt',
    # Linux
    '/usr/lib/X11/rgb.txt',
    # The X11R6.4 rgb.txt file
    os.path.join(sys.path[0], 'X/rgb.txt'),
    # add more here
    ]



# Do this because PyncheWidget.py wants to get at the interpolated docstring
# too, for its Help menu.
def docstring():
    return __doc__ % globals()


def usage(code, msg=''):
    print docstring()
    if msg:
        print msg
    sys.exit(code)



def initial_color(s, colordb):
    # function called on every color
    def scan_color(s, colordb=colordb):
        try:
            r, g, b = colordb.find_byname(s)
        except ColorDB.BadColor:
            try:
                r, g, b = ColorDB.rrggbb_to_triplet(s)
            except ColorDB.BadColor:
                return None, None, None
        return r, g, b
    #
    # First try the passed in color
    r, g, b = scan_color(s)
    if r is None:
        # try the same color with '#' prepended, since some shells require
        # this to be escaped, which is a pain
        r, g, b = scan_color('#' + s)
    if r is None:
        print 'Bad initial color, using gray50:', s
        r, g, b = scan_color('gray50')
    if r is None:
        usage(1, 'Cannot find an initial color to use')
        # does not return
    return r, g, b



def build(master=None, initialcolor=None, initfile=None, ignore=None,
          dbfile=None):
    # create all output widgets
    s = Switchboard(not ignore and initfile)
    # defer to the command line chosen color database, falling back to the one
    # in the .pynche file.
    if dbfile is None:
        dbfile = s.optiondb().get('DBFILE')
    # find a parseable color database
    colordb = None
    files = RGB_TXT[:]
    if dbfile is None:
        dbfile = files.pop()
    while colordb is None:
        try:
            colordb = ColorDB.get_colordb(dbfile)
        except (KeyError, IOError):
            pass
        if colordb is None:
            if not files:
                break
            dbfile = files.pop(0)
    if not colordb:
        usage(1, 'No color database file found, see the -d option.')
    s.set_colordb(colordb)

    # create the application window decorations
    app = PyncheWidget(__version__, s, master=master)
    w = app.window()

    # these built-in viewers live inside the main Pynche window
    s.add_view(StripViewer(s, w))
    s.add_view(ChipViewer(s, w))
    s.add_view(TypeinViewer(s, w))

    # get the initial color as components and set the color on all views.  if
    # there was no initial color given on the command line, use the one that's
    # stored in the option database
    if initialcolor is None:
        optiondb = s.optiondb()
        red = optiondb.get('RED')
        green = optiondb.get('GREEN')
        blue = optiondb.get('BLUE')
        # but if there wasn't any stored in the database, use grey50
        if red is None or blue is None or green is None:
            red, green, blue = initial_color('grey50', colordb)
    else:
        red, green, blue = initial_color(initialcolor, colordb)
    s.update_views(red, green, blue)
    return app, s


def run(app, s):
    try:
        app.start()
    except KeyboardInterrupt:
        pass



def main():
    try:
        opts, args = getopt.getopt(
            sys.argv[1:],
            'hd:i:Xv',
            ['database=', 'initfile=', 'ignore', 'help', 'version'])
    except getopt.error, msg:
        usage(1, msg)

    if len(args) == 0:
        initialcolor = None
    elif len(args) == 1:
        initialcolor = args[0]
    else:
        usage(1)

    ignore = False
    dbfile = None
    initfile = os.path.expanduser('~/.pynche')
    for opt, arg in opts:
        if opt in ('-h', '--help'):
            usage(0)
        elif opt in ('-v', '--version'):
            print """\
Pynche -- The PYthon Natural Color and Hue Editor.
Contact: %(AUTHNAME)s
Email:   %(AUTHEMAIL)s
Version: %(__version__)s""" % globals()
            sys.exit(0)
        elif opt in ('-d', '--database'):
            dbfile = arg
        elif opt in ('-X', '--ignore'):
            ignore = True
        elif opt in ('-i', '--initfile'):
            initfile = arg

    app, sb = build(initialcolor=initialcolor,
                    initfile=initfile,
                    ignore=ignore,
                    dbfile=dbfile)
    run(app, sb)
    sb.save_views()



if __name__ == '__main__':
    main()
