#!/usr/bin/python

#
# Copyright (c) 2002, 2003 Art Haas
#
# This file is part of PythonCAD.
# 
# PythonCAD is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# PythonCAD is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with PythonCAD; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#
# main routine to start GTK-based pycad
#

import getopt
import sys
import os

import pygtk
pygtk.require('2.0')
import gtk

import Generic.globals
import Interface.Gtk.gtkimage
import Interface.Gtk.gtkpycad
import Generic.image
import Generic.imageio
import Generic.fileio
import Generic.selections
import Generic.preferences
import Generic.color
import Generic.linetype
import Generic.style
import Generic.segment
import Generic.circle
import Generic.leader
import Generic.polyline
import Generic.segjoint
import Generic.conobject
import Generic.baseobject
import Generic.dimension
import Generic.units
import Generic.layer

#
# set up global variables ...
#

Generic.globals.imagelist = []
Generic.globals.prefs = Generic.baseobject.LockedDict(str)
Generic.globals.colors = Generic.baseobject.TypedDict(Generic.color.Color,
                                                      Generic.color.Color)
Generic.globals.linetypes = Generic.baseobject.TypedDict(Generic.linetype.Linetype, Generic.linetype.Linetype)
Generic.globals.styles = Generic.baseobject.TypedDict(Generic.style.Style,
                                                      Generic.style.Style)
# Generic.globals.dimstyles = Generic.baseobject.TypedDict(str)
Generic.globals.dimstyles = []

Generic.globals.selectobj = Generic.selections.Selection()

def get_image_and_layer(eid):
    """

get_image_and_layer(eid)    
    """
    for _image in Generic.globals.imagelist:
        _layer = _image.findLayerWithObject(_eid)
        if _layer is not None:
            return _image, _layer
    return None, None

def get_image(layer):
    """Find the image containing a Layer.

get_image(layer)

This function returns an Image instance or None.
    """
    if not isinstance(layer, Generic.layer.Layer):
        raise TypeError, "Invalid layer: " + `layer`
    _l = layer
    _p = _l.getParent()
    while _p is not None:
        _l = _p
        _p = _l.getParent()
    for _image in Generic.globals.imagelist:
        if _image.getTopLayer() is _l:
            return _image
    return None
        
def _initialize_booleans():
    Generic.globals.prefs['HIGHLIGHT_POINTS'] = True
    Generic.globals.prefs['AUTOSPLIT'] = False

def _initialize_sizes():
    Generic.globals.prefs['CHAMFER_LENGTH'] = 1.0
    Generic.globals.prefs['FILLET_RADIUS'] = 1.0
    Generic.globals.prefs['UNITS'] = Generic.units.MILLIMETERS
    Generic.globals.prefs['LEADER_ARROW_SIZE'] = 1.0

def _initialize_image_colors():
    _color = Generic.color.get_color(80, 140, 210) # blueish/purpleish
    Generic.globals.prefs['INACTIVE_LAYER_COLOR'] = _color
    _color = Generic.color.get_color(0, 0, 0) # black
    Generic.globals.prefs['BACKGROUND_COLOR'] = _color
    _color = Generic.color.get_color(255, 255, 0) # yellow
    Generic.globals.prefs['SINGLE_POINT_COLOR'] = _color
    _color = Generic.color.get_color(0, 255, 255) # cyan
    Generic.globals.prefs['MULTI_POINT_COLOR'] = _color

def _initialize_styles():
    _color = Generic.color.get_color(0xff, 0xff, 0xff) # white
    _lt = Generic.linetype.get_linetype_by_dashes(None)
    _style = Generic.style.Style(u'Solid White Line', _lt, _color, 1.0)
    Generic.globals.styles[_style] = _style
    Generic.globals.prefs['LINE_STYLE'] = _style
    Generic.globals.prefs['LINE_COLOR'] = _style.getColor()
    Generic.globals.prefs['LINE_TYPE'] = _style.getLinetype()
    Generic.globals.prefs['LINE_THICKNESS'] = _style.getThickness()
    #
    # set this style as the class default for the "real" drawing entities
    #
    # fixme: this should be done with a classmethod or some sort of
    # function ...
    #
    Generic.segment.Segment.__defstyle = _style
    Generic.circle.Circle.__defstyle = _style
    Generic.leader.Leader.__defstyle = _style
    Generic.polyline.Polyline.__defstyle = _style
    Generic.segjoint.SegJoint.__defstyle = _style
    #
    _color = Generic.color.get_color(0, 0, 0) # black
    _style = Generic.style.Style(u'Solid Black Line', _lt, _color, 1.0)
    Generic.globals.styles[_style] = _style
    _color = Generic.color.get_color(0xff, 0, 0) # red
    _lt = Generic.linetype.get_linetype_by_dashes([4, 1])
    _style = Generic.style.Style(u'Dashed Red Line', _lt, _color, 1.0)
    Generic.globals.styles[_style] = _style
    _color = Generic.color.get_color(0, 0xff, 0) # green
    _style = Generic.style.Style(u'Dashed Green Line', _lt, _color, 1.0)
    Generic.globals.styles[_style] = _style
    _color = Generic.color.get_color(0, 0, 0xff) # blue
    _style = Generic.style.Style(u'Dashed Blue Line', _lt, _color, 1.0)
    Generic.globals.styles[_style] = _style
    _color = Generic.color.get_color(0xff, 0xff, 0) # yellow
    _lt = Generic.linetype.get_linetype_by_dashes([8, 2])
    _style = Generic.style.Style(u'Dashed Yellow Line', _lt, _color, 1.0)
    Generic.globals.styles[_style] = _style
    _color = Generic.color.get_color(0xff, 0, 0xff) # violet
    _style = Generic.style.Style(u'Dashed Violet Line', _lt, _color, 1.0)
    Generic.globals.styles[_style] = _style
    _color = Generic.color.get_color(0, 0xff, 0xff) # cyan
    _style = Generic.style.Style(u'Dashed Cyan Line', _lt, _color, 1.0)
    Generic.globals.styles[_style] = _style
    #
    # define and set a construction line style
    #
    _color = Generic.color.get_color(0xff, 0, 0) # red
    _lt = Generic.linetype.Linetype(u'Construction Lines', [2, 2])
    _style = Generic.style.Style(u'Construction Objects', _lt, _color, 0.0)
    Generic.conobject.ConstructionObject.__defstyle = _style
    #
    # define and add the default text style and use values in the
    # text style to define various global key/value pairs
    #
    _white = Generic.color.get_color(0xff, 0xff, 0xff)
    _ts = Generic.text.TextStyle(u'Default Text Style', color=_white)
    Generic.globals.prefs['TEXT_STYLE'] = _ts
    Generic.globals.prefs['FONT_COLOR'] = _ts.getColor()
    Generic.globals.prefs['FONT_SIZE'] = _ts.getSize()
    Generic.globals.prefs['FONT_WEIGHT'] = _ts.getWeight()
    Generic.globals.prefs['FONT_STYLE'] = _ts.getStyle()
    Generic.globals.prefs['FONT_FAMILY'] = _ts.getFamily()
    #
    # define and add the default dimension style and use the
    # values in that style to define various global preference
    # key/value pairs
    #
    _dsdict = {}
    _dsdict['DIM_PRIMARY_FONT_COLOR'] = _white
    _dsdict['DIM_SECONDARY_FONT_COLOR'] = _white
    _dimcolor = Generic.color.get_color(255, 165, 0) # orangeish
    _dsdict['DIM_COLOR'] = _dimcolor
    _ds = Generic.dimension.DimStyle(u'Default DimStyle', _dsdict)
    Generic.globals.dimstyles.append(_ds)
    Generic.globals.prefs['DIM_STYLE'] = _ds
    for _key in _ds.getOptions():
        _value = _ds.getOption(_key)
        Generic.globals.prefs[_key] = _value
    
def _initialize_linetypes():
    _lt = Generic.linetype.Linetype(u'Solid') # solid
    Generic.globals.linetypes[_lt] = _lt
    _lt = Generic.linetype.Linetype(u'Dash1', [4, 1]) # dashed line
    Generic.globals.linetypes[_lt] = _lt
    _lt = Generic.linetype.Linetype(u'Dash2', [8, 2]) # dashed line
    Generic.globals.linetypes[_lt] = _lt
    _lt = Generic.linetype.Linetype(u'Dash3', [12, 2]) # dashed line
    Generic.globals.linetypes[_lt] = _lt
    _lt = Generic.linetype.Linetype(u'Dash4', [10, 2, 2, 2]) # dashed line
    Generic.globals.linetypes[_lt] = _lt
    _lt = Generic.linetype.Linetype(u'Dash5', [15, 5, 5, 5]) # dashed line
    Generic.globals.linetypes[_lt] = _lt

def _initialize_colors():
    _color = Generic.color.Color(255, 0, 0) # red
    Generic.globals.colors[_color] = _color
    _color = Generic.color.Color(0, 255, 0) # green
    Generic.globals.colors[_color] = _color
    _color = Generic.color.Color(0, 0, 255) # blue
    Generic.globals.colors[_color] = _color
    _color = Generic.color.Color(255, 0, 255) # violet
    Generic.globals.colors[_color] = _color
    _color = Generic.color.Color(255, 255, 0) # yellow
    Generic.globals.colors[_color] = _color
    _color = Generic.color.Color(0, 255, 255) # cyan
    Generic.globals.colors[_color] = _color
    _color = Generic.color.Color(255, 255, 255) # white
    Generic.globals.colors[_color] = _color
    _color = Generic.color.Color(0, 0, 0) # black
    Generic.globals.colors[_color] = _color

def _initialize_globals():
    _initialize_colors()
    _initialize_linetypes()
    _initialize_styles()
    _initialize_image_colors()
    _initialize_sizes()
    _initialize_booleans()
    
def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
    except getopt.GetoptError, e:
        sys.stderr.write("Error: %s\n" % e)
        sys.exit(1)
    for o, a in opts:
        if o in ("-h", "--help"):
            sys.stdout.write("No help yet! Sorry ...\n")
            sys.exit()
    #
    # load up global and user preferences
    #

    _initialize_globals()
    Generic.preferences.initialize_prefs()
    Generic.preferences.load_global_prefs()
    _user_flag = Generic.globals.prefs['USER_PREFS']
    if _user_flag:
        Generic.preferences.load_user_prefs()
    Generic.globals.prefs.lock() # the globals are now set

    #
    # open any drawings passed as arguments. This code needs
    # to be much more robust ...
    #

    assert 'BACKGROUND_COLOR' in Generic.globals.prefs, "BACKGROUND_COLOR missing"
    _background = Generic.globals.prefs['BACKGROUND_COLOR']
    for arg in args:
        if os.path.exists(arg):
            sys.stdout.write("Opening '%s'\n" % arg)
            try:
                imfile = Generic.fileio.CompFile(arg, "r")
            except IOError, e:
                sys.stderr.write("Can't open '%s'! %s" % (arg, e))
                continue
            img = Interface.Gtk.gtkimage.GTKImage()
            try:
                Generic.imageio.load_image(img, imfile)
                fname = os.path.realpath(arg)
                img.setFilename(fname)
                img.getWindow().set_title(os.path.basename(fname))
                Interface.Gtk.gtkpycad.add_image(img)
                img.window.show_all()
                if img.getOption('BACKGROUND_COLOR') == _background:
                    img.setOption('BACKGROUND_COLOR', _background)
                img.fitImage()
            finally:
                imfile.close()
        else:
            sys.stderr.write("Can't find file '%s' - Skipping ...\n" % arg)
    if not len(Generic.globals.imagelist):
        img = Interface.Gtk.gtkimage.GTKImage()
        Interface.Gtk.gtkpycad.add_image(img)
        img.window.show_all()
        img.setOption('BACKGROUND_COLOR', _background)        
    gtk.main()

if __name__ == '__main__':
    _major, _minor, _micro = gtk.pygtk_version
    if ((_major < 2) and
        (_minor < 100) and #
        (_micro < 16)):
        print """
The PyGTK version you are using needs to be upgraded to
a newer version. Changes in the PyGTK code have required
the addition of some compatibility code in PythonCAD,
but these changes are temporary and will be removed in
a future PythonCAD release. Please upgrade your PyGTK
module to version 1.99.16 (at least), or retrieve and
build the PyGTK module from the CVS archive.
"""
    main()
