#
# Copyright (c) 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
#
#
# This code handles loading the global and user preference
# files
#

import imp
import string
import sys
import os

import globals
import units
import text
import color
import linetype
import style
import dimension

#
# global variables
#

pref_file = '/etc/pythoncad/prefs.py'

#

def _test_font_weight(val):
    _weight = None
    if isinstance(val, str):
        _uval = string.upper(val)
        if _uval == 'NORMAL':
            _weight = text.NORMAL
        elif _uval == 'LIGHT':
            _weight = text.LIGHT
        elif _uval == 'BOLD':
            _weight = text.BOLD
        elif _uval == 'HEAVY':
            _weight = text.HEAVY
        else:
            sys.stderr.write("Invalid font weight: '%s'\n" % val)
    else:
        sys.stderr.write("invalid font weight: '" + str(val) + "'\n")
    return _weight

def _test_font_style(val):
    _style = None
    if isinstance(val, str):
        _uval = string.upper(val)
        if _uval == 'NORMAL':
            _style = text.NORMAL
        elif _uval == 'OBLIQUE':
            _style = text.OBLIQUE
        elif _uval == 'ITALIC':
            _uval = text.ITALIC
        else:
            sys.stderr.write("Invalid font style: '%s'\n" % val)
    else:
        sys.stderr.write("Invalid font style: '" + str(val) + "'\n")
    return _style

def _test_color(val):
    _color = None
    try:
        _color = color.Color(val)
    except:
        sys.stderr.write("Invalid color: '%s'\n" % val)
    return _color

def _test_dim_position(val):
    _pos = None
    if isinstance(val, str):
        _uval = string.upper(val)
        if _uval == 'SPLIT':
            _pos = dimension.Dimension.SPLIT
        elif _uval == 'ABOVE':
            _pos = dimension.Dimension.ABOVE
        elif _uval == 'BELOW':
            _pos = dimension.Dimension.BELOW
        else:
            sys.stderr.write("Invalid dimension position: '%s'\n" % val)
    else:
        sys.stderr.write("Invalid dimension position: '" + str(val) + "'\n")
    return _pos

def _test_dim_endpoint(val):
    _ept = None
    if val is not None:
        if isinstance(val, str):
            _uval = string.upper(val)
            if _uval == 'NO_ENDPOINT' or _uval == 'NONE':
                _ept = dimension.Dimension.NO_ENDPOINT
            elif _uval == 'ARROW':
                _ept = dimension.Dimension.ARROW
            elif _uval == 'FILLED_ARROW':
                _ept = dimension.Dimension.FILLED_ARROW
            elif _uval == 'SLASH':
                _ept = dimension.Dimension.SLASH
            elif _uval == 'CIRCLE':
                _ept = dimension.Dimension.CIRCLE
            else:
                sys.stderr.write("Invalid dimension endpoint: '%s'\n" % val)
        else:
            sys.stderr.write("Invalid dimension endpoint: '" + str(val) + "'\n")
    return _ept

def _test_units(val):
    _unit = None
    if isinstance(val, str):
        _uval = string.upper(val)
        if _uval == 'MILLIMETERS':
            _unit = units.MILLIMETERS
        elif _uval == 'MICROMETERS':
            _unit = units.MICROMETERS
        elif _uval == 'METERS':
            _unit = units.METERS
        elif _uval == 'KILOMETERS':
            _unit = units.KILOMETERS
        elif _uval == 'INCHES':
            _unit = units.INCHES
        elif _uval == 'FEET':
            _unit = units.FEET
        elif _uval == 'YARDS':
            _unit = units.YARDS
        elif _uval == 'MILES':
            _unit = units.MILES
        else:
            sys.stderr.write("Invalid unit: '%s'\n" % val)
    else:
        sys.stderr.write("Invalid unit: '" + str(val) + "'\n")
    return _unit

def _test_boolean(val):
    _bool = None
    if val is True or val is False:
        _bool = val
    else:
        sys.stderr.write("Invalid boolean flag: '%s'\n" % val)
    return _bool

def _test_float(val):
    _float = None
    if isinstance(val, float):
        _float = val
    else:
        try:
            _float = float(val)
        except:
            sys.stderr.write("Invalid float value: '%s'\n" % val)
    return _float

def _test_int(val):
    _int = None
    if isinstance(val, int):
        _int = val
    else:
        try:
            _int = int(val)
        except:
            sys.stderr.write("Invalid integer value: '%s'\n" % val)
    return _int

def _test_unicode(val):
    _uni = None
    if isinstance(val, unicode):
        _uni = val
    else:
        try:
            _uni = unicode(val)
        except:
            sys.stderr.write("Invalid unicode string: '%s'\n" % val)
    return _uni

def initialize_prefs():
    """This method sets the initial default value for image variables.

initialize_prefs()
    """
    #
    # default dimension parameters
    #
    _dimstyles = []
    globals.prefs['DIMSTYLES'] = _dimstyles
    globals.prefs['DEFAULT_DIMSTYLE'] = None
    #
    # drawing and text parameters
    #
    globals.prefs['TEXTSTYLES'] = []
    globals.prefs['DEFAULT_TEXTSTYLE'] = None
    #
    # miscellaneous things
    #
    globals.prefs['USER_PREFS'] = True
    #
    # colors
    #
    # these will be replaced ...
    #
    _colors = []
    _red = color.Color(255,0,0)
    _colors.append(_red)
    _green = color.Color(0,255,0)
    _colors.append(_green)
    _blue = color.Color(0,0,255)
    _colors.append(_blue)
    _violet = color.Color(255,0,255)
    _colors.append(_violet)
    _yellow = color.Color(255,255,0)
    _colors.append(_yellow)
    _cyan = color.Color(0,255,255)
    _colors.append(_cyan)
    _white = color.Color(255,255,255)
    _colors.append(_white)
    _black = color.Color(0,0,0)
    _colors.append(_black)
    globals.prefs['COLORS'] = _colors
    #
    # linetypes
    #
    # these will be replaced
    #
    _linetypes = []
    _solid = linetype.Linetype(u'Solid')
    _linetypes.append(_solid)
    _dash1 = linetype.Linetype(u'Dash1', [4,1])
    _linetypes.append(_dash1)
    _dash2 = linetype.Linetype(u'Dash2', [8,2])
    _linetypes.append(_dash2)
    _dash3 = linetype.Linetype(u'Dash3', [12,2])
    _linetypes.append(_dash3)
    _dash4 = linetype.Linetype(u'Dash4', [10,2,2,2])
    _linetypes.append(_dash4)
    _dash5 = linetype.Linetype(u'Dash5', [15,5,5,5])
    _linetypes.append(_dash5)
    globals.prefs['LINETYPES'] = _linetypes
    #
    # line styles
    #
    # these will be replaced
    #
    _styles = []
    _st = style.Style('Solid White Line', _solid, _white, 1.0)
    globals.prefs['STANDARD_STYLE'] = 'Solid White Line'
    _styles.append(_st)
    _st = style.Style('Solid Black Line', _solid, _black, 1.0)
    _styles.append(_st)
    _st = style.Style('Dashed Red Line', _dash1, _red, 1.0)
    _styles.append(_st)
    _st = style.Style('Dashed Green Line', _dash1, _green, 1.0)
    _styles.append(_st)
    _st = style.Style('Dashed Blue Line', _dash1, _blue, 1.0)
    _styles.append(_st)
    _st = style.Style('Dashed Yellow Line', _dash2, _yellow, 1.0)
    _styles.append(_st)
    _st = style.Style('Dashed Violet Line', _dash2, _violet, 1.0)
    _styles.append(_st)
    _st = style.Style('Dashed Cyan Line', _dash2, _cyan, 1.0)
    _styles.append(_st)
    globals.prefs['STYLES'] = _styles
    globals.prefs['DEFAULT_STYLE'] = 'Solid White Line'

#
# validate the available options and set them if they seem alright
#

def _set_units(prefmod):
    _unit = _test_units(prefmod.units)
    if _unit is not None:
        globals.prefs['UNITS'] = _unit

def _set_user_prefs(prefmod):
    _flag = _test_boolean(prefmod.user_prefs)
    if _flag is not None:
        globals.prefs['USER_PREFS'] = _flag

def _set_primary_font_family(prefmod):
    _family = prefmod.primary_font_family
    globals.prefs['DIM_PRIMARY_FONT_FAMILY'] = _family # needs a test ...

def _set_primary_font_size(prefmod):
    _size = _test_int(prefmod.primary_font_size)
    if _size is not None:
        if _size > 0:
            globals.prefs['DIM_PRIMARY_FONT_SIZE'] = _size
        else:
            sys.stderr.write("Invalid primary font size: %d\n" % _size)

def _set_primary_font_weight(prefmod):
    _weight = _test_font_weight(prefmod.primary_font_weight)
    if _weight is not None:
        globals.prefs['DIM_PRIMARY_FONT_WEIGHT'] = _weight

def _set_primary_font_style(prefmod):
    _style = _test_font_style(prefmod.primary_font_style)
    if _style is not None:
        globals.prefs['DIM_PRIMARY_FONT_STYLE'] = _style

def _set_primary_font_color(prefmod):
    _color = _test_color(prefmod.primary_font_color)
    if _color is not None:
        _r, _g, _b = _color.getColors()
        _color = color.get_color(_r, _g, _b)
        globals.prefs['DIM_PRIMARY_FONT_COLOR'] = _color
        _colors = globals.prefs['COLORS']
        if _color not in _colors:
            _colors.append(_color)

def _set_primary_prefix(prefmod):
    _prefix = _test_unicode(prefmod.primary_prefix)
    if _prefix is not None:
        globals.prefs['DIM_PRIMARY_PREFIX'] = _prefix

def _set_primary_suffix(prefmod):
    _suffix = _test_unicode(prefmod.primary_suffix)
    if _suffix is not None:
        globals.prefs['DIM_PRIMARY_SUFFIX'] = _suffix

def _set_primary_precision(prefmod):
    _prec = _test_int(prefmod.primary_precision)
    if _prec is not None:
        if _prec < 0 or _prec > 15:
            sys.stderr.write("Invalid primary dimension precision: %d\n" % _prec)
        else:
            globals.prefs['DIM_PRIMARY_PRECISION'] = _prec

def _set_primary_units(prefmod):
    _unit = _test_units(prefmod.primary_units)
    if _unit is not None:
        globals.prefs['DIM_PRIMARY_UNITS'] = _unit

def _set_primary_print_zero(prefmod):
    _flag = _test_boolean(prefmod.primary_print_zero)
    if _flag is not None:
        globals.prefs['DIM_PRIMARY_LEADING_ZERO'] = _flag

def _set_primary_trail_decimal(prefmod):
    _flag = _test_boolean(prefmod.primary_trailing_decimal)
    if _flag is not None:
        globals.prefs['DIM_PRIMARY_TRAILING_DECIMAL'] = _flag

def _set_secondary_font_family(prefmod):
    _family = prefmod.secondary_font_family
    globals.prefs['DIM_SECONDARY_FONT_FAMILY'] = _family # needs a test ...

def _set_secondary_font_size(prefmod):
    _size = _test_int(prefmod.secondary_font_size)
    if _size is not None:
        if _size > 0:
            globals.prefs['DIM_SECONDARY_FONT_SIZE'] = _size
        else:
            sys.stderr.write("Invalid secondary dimension size: %d\n" % _size)

def _set_secondary_font_weight(prefmod):
    _weight = _test_font_weight(prefmod.secondary_font_weight)
    if _weight is not None:
        globals.prefs['DIM_SECONDARY_FONT_WEIGHT'] = _weight

def _set_secondary_font_style(prefmod):
    _style = _test_font_style(prefmod.secondary_font_style)
    if _style is not None:
        globals.prefs['DIM_SECONDARY_FONT_STYLE'] = _style

def _set_secondary_font_color(prefmod):
    _color = _test_color(prefmod.secondary_font_color)
    if _color is not None:
        _r, _g, _b = _color.getColors()
        _color = color.get_color(_r, _g, _b)
        globals.prefs['DIM_SECONDARY_FONT_COLOR'] = _color
        _colors = globals.prefs['COLORS']
        if _color not in _colors:
            _colors.append(_color)

def _set_secondary_prefix(prefmod):
    _prefix = _test_unicode(prefmod.secondary_prefix)
    if _prefix is not None:
        globals.prefs['DIM_SECONDARY_PREFIX'] = _prefix

def _set_secondary_suffix(prefmod):
    _suffix = _test_unicode(prefmod.secondary_suffix)
    if _suffix is not None:
        globals.prefs['DIM_SECONDARY_SUFFIX'] = _suffix

def _set_secondary_precision(prefmod):
    _prec = _test_int(prefmod.secondary_precision)
    if _prec is not None:
        if _prec < 0 or _prec > 15:
            sys.stderr.write("Invalid secondary dimension precision: %d\n" % _prec)
        else:
            globals.prefs['DIM_SECONDARY_PRECISION'] = _prec

def _set_secondary_units(prefmod):
    _unit = _test_units(prefmod.secondary_units)
    if _unit is not None:
        globals.prefs['DIM_SECONDARY_UNITS'] = _unit

def _set_secondary_print_zero(prefmod):
    _flag = _test_boolean(prefmod.secondary_print_zero)
    if _flag is not None:
        globals.prefs['DIM_SECONDARY_LEADING_ZERO'] = _flag

def _set_secondary_trail_decimal(prefmod):
    _flag = _test_boolean(prefmod.secondary_trailing_decimal)
    if _flag is not None:
        globals.prefs['DIM_SECONDARY_TRAILING_DECIMAL'] = _flag

def _set_dim_offset(prefmod):
    _offset = _test_float(prefmod.dim_offset)
    if _offset is not None:
        if _offset < 0.0:
            sys.stderr.write("Invalid dimension offset: %g\n" % _offset)
        else:
            globals.prefs['DIM_OFFSET'] = _offset

def _set_dim_extension(prefmod):
    _ext = _test_float(prefmod.dim_extension)
    if _ext is not None:
        if _ext < 0.0:
            sys.stderr.write("Invalid dimension extension: %g\n" % _ext)
        else:
            globals.prefs['DIM_EXTENSION'] = _ext

def _set_dim_color(prefmod):
    _color = _test_color(prefmod.dim_color)
    if _color is not None:
        _r, _g, _b = _color.getColors()
        _color = color.get_color(_r, _g, _b)
        globals.prefs['DIM_COLOR'] = _color
        _colors = globals.prefs['COLORS']
        if _color not in _colors:
            _colors.append(_color)

def _set_dim_position(prefmod):
    _pos = _test_dim_position(prefmod.dim_position)
    if _pos is not None:
        globals.prefs['DIM_POSITION'] = _pos

def _set_dim_endpoint(prefmod):
    _ept = _test_dim_endpoint(prefmod.dim_endpoint)
    if _ept is not None:
        globals.prefs['DIM_ENDPOINT'] = _ept

def _set_dim_endpoint_size(prefmod):
    _epsize = _test_float(prefmod.dim_endpoint_size)
    if _epsize is not None:
        if _epsize < 0.0:
            sys.stderr.write("Invalid endpoint size: %g\n" % _epsize)
        else:
            globals.prefs['DIM_ENDPOINT_SIZE'] = _epsize

def _set_dim_dual_mode(prefmod):
    _flag = _test_boolean(prefmod.dim_dual_mode)
    if _flag is not None:
        globals.prefs['DIM_DUAL_MODE'] = _flag

def _set_radial_dim_primary_prefix(prefmod):
    _prefix = _test_unicode(prefmod.radial_dim_primary_prefix)
    if _prefix is not None:
        globals.prefs['RADIAL_DIM_PRIMARY_PREFIX'] = _prefix

def _set_radial_dim_primary_suffix(prefmod):
    _suffix = _test_unicode(prefmod.radial_dim_primary_suffix)
    if _suffix is not None:
        globals.prefs['RADIAL_DIM_PRIMARY_SUFFIX'] = _suffix

def _set_radial_dim_secondary_prefix(prefmod):
    _prefix = _test_unicode(prefmod.radial_dim_secondary_prefix)
    if _prefix is not None:
        globals.prefs['RADIAL_DIM_SECONDARY_PREFIX'] = _prefix

def _set_radial_dim_secondary_suffix(prefmod):
    _suffix = _test_unicode(prefmod.radial_dim_secondary_suffix)
    if _suffix is not None:
        globals.prefs['RADIAL_DIM_SECONDARY_SUFFIX'] = _suffix

def _set_radial_dim_dia_mode(prefmod):
    _flag = _test_boolean(prefmod.radial_dim_dia_mode)
    if _flag is not None:
        globals.prefs['RADIAL_DIM_DIA_MODE'] = _flag

def _set_angular_dim_primary_prefix(prefmod):
    _prefix = _test_unicode(prefmod.angular_dim_primary_prefix)
    if _prefix is not None:
        globals.prefs['ANGULAR_DIM_PRIMARY_PREFIX'] = _prefix

def _set_angular_dim_primary_suffix(prefmod):
    _suffix = _test_unicode(prefmod.angular_dim_primary_suffix)
    if _suffix is not None:
        globals.prefs['ANGULAR_DIM_PRIMARY_SUFFIX'] = _suffix

def _set_angular_dim_secondary_prefix(prefmod):
    _prefix = _test_unicode(prefmod.angular_dim_secondary_prefix)
    if _prefix is not None:
        globals.prefs['ANGULAR_DIM_SECONDARY_PREFIX'] = _prefix

def _set_angular_dim_secondary_suffix(prefmod):
    _suffix = _test_unicode(prefmod.angular_dim_secondary_suffix)
    if _suffix is not None:
        globals.prefs['ANGULAR_DIM_SECONDARY_SUFFIX'] = _suffix

def _set_font_family(prefmod):
    _family = prefmod.font_family
    globals.prefs['FONT_FAMILY'] = _family

def _set_font_style(prefmod):
    _style = _test_font_style(prefmod.font_style)
    if _style is not None:
        globals.prefs['FONT_STYLE'] = _style

def _set_font_weight(prefmod):
    _weight = _test_font_weight(prefmod.font_weight)
    if _weight is not None:
        globals.prefs['FONT_WEIGHT'] = _weight

def _set_font_size(prefmod):
    _size = _test_int(prefmod.font_size)
    if _size is not None:
        if _size > 0:
            globals.prefs['FONT_SIZE'] = _size
        else:
            sys.stderr.write("Invalid font size: %d\n" % _size)

def _set_font_color(prefmod):
    _color = _test_color(prefmod.font_color)
    if _color is not None:
        _r, _g, _b = _color.getColors()
        _color = color.get_color(_r, _g, _b)
        globals.prefs['FONT_COLOR'] = _color
        _colors = globals.prefs['COLORS']
        if _color not in _colors:
            _colors.append(_color)

def _set_chamfer_length(prefmod):
    _length = _test_float(prefmod.chamfer_length)
    if _length is not None:
        if _length < 0.0:
            sys.stderr.write("Invalid chamfer length: %g\n" % _length)
        else:
            globals.prefs['CHAMFER_LENGTH'] = _length

def _set_fillet_radius(prefmod):
    _radius = _test_float(prefmod.fillet_radius)
    if _radius is not None:
        if _radius < 0.0:
            sys.stderr.write("Invalid fillet radius: %g\n" % _radius)
        else:
            globals.prefs['FILLET_RADIUS'] = _radius

def _set_line_color(prefmod):
    _color = _test_color(prefmod.line_color)
    if _color is not None:
        _r, _g, _b = _color.getColors()
        _color = color.get_color(_r, _g, _b)
        globals.prefs['LINE_COLOR'] = _color
        _colors = globals.prefs['COLORS']
        if _color not in _colors:
            _colors.append(_color)

def _set_line_thickness(prefmod):
    _t = _test_float(prefmod.line_thickness)
    if _t is not None:
        if _t < 0.0:
            sys.stderr.write("Invalid line thickness: %g\n" % _thickness)
        else:
            globals.prefs['LINE_THICKNESS'] = _t

def _set_highlight_points(prefmod):
    _flag = _test_boolean(prefmod.highlight_points)
    if _flag is not None:
        globals.prefs['HIGHLIGHT_POINTS'] = _flag

def _set_inactive_layer_color(prefmod):
    _color = _test_color(prefmod.inactive_layer_color)
    if _color is not None:
        _r, _g, _b = _color.getColors()
        _color = color.get_color(_r, _g, _b)
        globals.prefs['INACTIVE_LAYER_COLOR'] = _color

def _set_background_color(prefmod):
    _color = _test_color(prefmod.background_color)
    if _color is not None:
        _r, _g, _b = _color.getColors()
        _color = color.get_color(_r, _g, _b)
        globals.prefs['BACKGROUND_COLOR'] = _color

def _set_single_point_color(prefmod):
    _color = _test_color(prefmod.single_point_color)
    if _color is not None:
        _r, _g, _b = _color.getColors()
        _color = color.get_color(_r, _g, _b)
        globals.prefs['SINGLE_POINT_COLOR'] = _color

def _set_multi_point_color(prefmod):
    _color = _test_color(prefmod.multi_point_color)
    if _color is not None:
        _r, _g, _b = _color.getColors()
        _color = color.get_color(_r, _g, _b)
        globals.prefs['MULTI_POINT_COLOR'] = _color

def _set_autosplit(prefmod):
    _flag = _test_boolean(prefmod.autosplit)
    if _flag is not None:
        globals.prefs['AUTOSPLIT'] = _flag

def _set_leader_arrow_size(prefmod):
    _size = _test_float(prefmod.leader_arrow_size)
    if _size is not None:
        if _size < 0.0:
            sys.stderr.write("Invalid leader arrow size: %g\n" % _size)
        else:
            globals.prefs['LEADER_ARROW_SIZE'] = _size

def _set_linetypes(prefmod):
    _ltlist = prefmod.linetypes
    _linetypes = globals.prefs['LINETYPES']
    if isinstance(_ltlist, list):
        for _obj in _ltlist:
            if not isinstance(_obj, tuple):
                sys.stderr.write("Invalid linetype tuple: '" + str(_obj) + "'\n")
                continue
            if len(_obj) != 2:
                sys.stderr.write("Invalid linetype tuple: '" + str(_obj) + "'\n")
                continue
            _name, _dlist = _obj
            try:
                _linetype = linetype.Linetype(_name, _dlist)
                if _linetype not in _linetypes:
                    _linetypes.append(_linetype)
            except:
                sys.stderr.write("Invalid linetype: '" + str(_obj) + "'\n")
    else:
        sys.stderr.write("Invalid line type list: '" + str(_ltlist) + "'\n")

def _set_colors(prefmod):
    _clist = prefmod.colors
    if isinstance(_clist, list):
        for _obj in _clist:
            _color = None
            if isinstance(_obj, str):
                _color = _test_color(_obj)
            elif isinstance(_obj, tuple):
                if len(_obj) != 3:
                    sys.stderr.write("Invalid color: '" + str(_obj) + "'\n")
                    continue
                _r, _g, _b = _obj
                try:
                    _color = color.Color(_r, _g, _b)
                except:
                    sys.stderr.write("Invalid color: '" + str(_obj) + "'\n")
                    continue
            if _color is not None and _color not in globals.colors:
                globals.colors[_color] = _color
    else:
        sys.stderr.write("Invalid color list: '" + str(_clist) + "'\n")

def _set_styles(prefmod):
    _slist = prefmod.styles
    _styles = globals.prefs['STYLES']
    _linetypes = globals.prefs['LINETYPES']
    if isinstance(_slist, list):
        for _obj in _slist:
            if not isinstance(_obj, tuple):
                sys.stderr.write("Invalid style entry: '" + str(_obj) + "'\n")
                continue
            if len(_obj) != 4:
                sys.stderr.write("Invalid style entry: '" + str(_obj) + "'\n")
                continue
            _name, _lt, _col, _th = _obj
            if not isinstance(_name, (str, unicode)):
                sys.stderr.write("Invalid style name: '" + str(_name) + "'\n")
                continue
            if not isinstance(_name, unicode):
                _name = unicode(_obj[0])
            if not isinstance(_lt, tuple):
                sys.stderr.write("Invalid style linetype: '" + str(_lt) + "'\n")
                continue
            if len(_lt) != 2:
                sys.stderr.write("Invalid style linetype: '" + str(_lt) + "'\n")
                continue
            try:
                _name, _dlist = _lt
                _linetype = linetype.Linetype(_name, _dlist)
            except:
                sys.stderr.write("Invalid style linetype: '" + str(_lt) + "'\n")
                continue
            _color = _test_color(_col)
            if _color is None:
                continue
            _r, _g, _b = _color.getColors()
            _color = color.get_color(_r, _g, _b)
            _thickness = _test_float(_th)
            if _thickness is None:
                continue
            try:
                _style = style.Style(_name, _linetype, _color, _thickness)
                if _style not in _styles:
                    _styles.append(_style)
                if _linetype not in _linetypes:
                    _linetypes.append(_linetype)
            except:
                sys.stderr.write("Invalid style: '" + str(_obj) + "'\n")
    else:
        sys.stderr.write("Invalid style list: '" + str(_slist) + "'\n")


def _set_default_style(prefmod):
    _dstyle = prefmod.default_style
    if isinstance(_dstyle, (str, unicode)):
        globals.prefs['DEFAULT_STYLE'] = _dstyle
    elif _dstyle is None:
        pass # accept the default
    else:
        sys.stderr.write("Invalid default style: '" + str(_dstyle) + "'\n")

def _test_dimstyle_opt(key, value):
    _val = None
    if (key == 'DIM_COLOR' or
        key == 'DIM_PRIMARY_FONT_COLOR' or
        key == 'DIM_SECONDARY_FONT_COLOR'):
        _color = None
        if isinstance(value, str):
            try:
                _color = color.Color(value)
            except:
                sys.stderr.write("Invalid dimension style color: '" + value + "'\n")
        elif isinstance(value, tuple):
            if len(value) == 3:
                _r, _g, _b = value
                try:
                    _color = color.Color(_r, _g, _b)
                except:
                    sys.stderr.write("Invalid dimension style color: '" + value + "'\n")
            else:
                sys.stderr.write("Invalid dimension style color: '" + value + "'\n")
        else:
            sys.stderr.write("Invalid dimension style color: '" + value + "'\n")
        if _color is not None:
            _r, _g, _b = _color.getColors()
            _val = color.get_color(_r, _g, _b)
    elif (key == 'DIM_PRIMARY_FONT_FAMILY' or
          key == 'DIM_SECONDARY_FONT_FAMILY'):
        if isinstance(value, str):
            _val = value
        else:
            sys.stderr.write("Invalid dimension style font family: '" + str(value) + "'\n")
    elif (key == 'DIM_OFFSET' or
          key == 'DIM_ENDPOINT_SIZE' or
          key == 'DIM_EXTENSION'):
        _fval = _test_float(value)
        if _fval is not None:
            if _fval < 0.0:
                sys.stderr.write("Invalid dimension style float value: '" + str(value) + "'\n")
            else:
                _val = _fval
    elif (key == 'DIM_PRIMARY_PRECISION' or
          key == 'DIM_SECONDARY_PRECISION' or
          key == 'DIM_PRIMARY_FONT_SIZE' or
          key == 'DIM_SECONDARY_FONT_SIZE'):
        _ival = _test_int(value)
        if _ival is not None:
            if _ival < 0:
                sys.stderr.write("Invalid dimension style integer value: '" + str(value) + "'\n")
            else:
                if (key == 'DIM_PRIMARY_PRECISION' or
                    key == 'DIM_SECONDARY_PRECISION'):
                    if _ival > 15:
                        sys.stderr.write("Invalid dimension style integer value: '" + str(value) + "'\n")
                    else:
                        _val = _ival
                else:
                    _val = _ival
    elif (key == 'DIM_PRIMARY_FONT_WEIGHT' or
          key == 'DIM_SECONDARY_FONT_WEIGHT'):
        _weight = _test_font_weight(value)
        if _weight is not None:
            _val = _weight
    elif (key == 'DIM_PRIMARY_FONT_STYLE' or
          key == 'DIM_SECONDARY_FONT_STYLE'):
        _style = _test_font_style(value)
        if _style is not None:
            _val = _style
    elif (key == 'DIM_PRIMARY_UNITS' or
          key == 'DIM_SECONDARY_UNITS'):
        _unit = _test_units(value)
        if _unit is not None:
            _val = _unit
    elif key == 'DIM_POSITION':
        _pos = _test_dim_position(value)
        if _pos is not None:
            _val = _pos
    elif key == 'DIM_ENDPOINT':
        _ept = _test_dim_endpoint(value)
        if _ept is not None:
            _val = _ept
    elif (key == 'DIM_PRIMARY_LEADING_ZERO' or
          key == 'DIM_SECONDARY_LEADING_ZERO' or
          key == 'DIM_PRIMARY_TRAILING_DECIMAL' or
          key == 'DIM_SECONDARY_TRAILING_DECIMAL' or
          key == 'DIM_DUAL_MODE' or
          key == 'RADIAL_DIM_DIA_MODE'):
        _flag = _test_boolean(value)
        if _flag is not None:
            _val = _flag
    elif (key == 'DIM_PRIMARY_PREFIX' or
          key == 'DIM_PRIMARY_SUFFIX' or
          key == 'DIM_SECONDARY_PREFIX' or
          key == 'DIM_SECONDARY_SUFFIX' or
          key == 'RADIAL_DIM_PRIMARY_PREFIX' or
          key == 'RADIAL_DIM_PRIMARY_SUFFIX' or
          key == 'RADIAL_DIM_SECONDARY_PREFIX' or
          key == 'RADIAL_DIM_SECONDARY_SUFFIX' or
          key == 'ANGULAR_DIM_PRIMARY_PREFIX' or
          key == 'ANGULAR_DIM_PRIMARY_SUFFIX' or
          key == 'ANGULAR_DIM_SECONDARY_PREFIX' or
          key == 'ANGULAR_DIM_SECONDARY_SUFFIX'):
        if isinstance(value, (str, unicode)):
            _string = value
            if isinstance(_string, str):
                _string = unicode(value)
            _val = _string
        else:
            sys.stderr.write("Invalid prefix/suffix: '%s'\n" % str(value))
    else:
        sys.stderr.write("Unhandled dimension style key: '%s'" % key)
    return _val

def _set_dimstyles(prefmod):
    _dslist = prefmod.dimstyles
    _dimstyles = globals.prefs['DIMSTYLES']
    _dsdefs = dimension.dimstyle_defaults
    if isinstance(_dslist, list):
        for _obj in _dslist:
            if not isinstance(_obj, tuple):
                sys.stderr.write("Invalid dimension style entry: '" + str(_obj) + "'\n")
                continue
            if len(_obj) != 2:
                sys.stderr.write("Invalid dimension style entry: '" + str(_obj) + "'\n")
                continue
            _name, _dsdict = _obj
            if not isinstance(_name, (str, unicode)):
                sys.stderr.write("Invalid dimension style name: '" + str(_name) + "'\n")
                continue
            if not isinstance(_dsdict, dict):
                sys.stderr.write("Invalid dimension style dictionary: '" + str(_dsdict) + "'\n")
                continue
            _defs = {}
            for _opt in _dsdefs:
                _val = _dsdefs[_opt]
                if (_opt == 'DIM_COLOR' or
                    _opt == 'DIM_PRIMARY_FONT_COLOR' or
                    _opt == 'DIM_SECONDARY_FONT_COLOR'):
                    _val = _val.clone()
                _defs[_opt] = _val
            _valid = True
            for _opt in _dsdict:
                if not isinstance(_opt, str):
                    sys.stderr.write("Invalid dimension style entry: '" + str(_opt) + "'\n")
                    _valid = False
                    break
                _uopt = string.upper(_opt)
                if _uopt not in _dsdefs:
                    sys.stderr.write("Invalid dimension style entry: '" + _opt + "'\n")
                    _valid = False
                    break
                _optval = _dsdict[_opt]
                _val = _test_dimstyle_opt(_uopt, _optval)
                if _val is None:
                    _valid = False
                    break
                _defs[_uopt] = _val
            if _valid:
                try:
                    _dimstyle = dimension.DimStyle(_name, _defs)
                    if _dimstyle not in _dimstyles:
                        _dimstyles.append(_dimstyle)
                except:
                    sys.stderr.write("Invalid dimension style: " + str(_obj) + "'\n")
    else:
        sys.stderr.write("Invalid dimension style list: '" + str(_dslist) + "'\n")

def _set_textstyles(prefmod):
    _tslist = prefmod.dimstyles
    _textstyles = globals.prefs['TEXTSTYLES']
    if isinstance(_tslist, list):
        for _obj in _tslist:
            if not isinstance(_obj, tuple):
                sys.stderr.write("Invalid text style entry: '" + str(_obj) + "'\n")
                continue
            if len(_obj) != 6:
                sys.stderr.write("Invalid text style entry: '" + str(_obj) + "'\n")
                continue
            _name = _test_unicode(_obj[0])
            if _name is None:
                continue
            _family = _obj[1]
            if not isinstance(_family, (str, unicode)):
                sys.stderr.write("Invalid text style family: '" + str(_family) + "'\n")
                continue
            _size = _test_int(_obj[2])
            if _size is None:
                continue
            if _size < 0:
                sys.stderr.write("Invalid text style size: %d\n" % _size)
                continue
            _style = _test_font_style(_obj[3])
            if _style is None:
                continue
            _weight = _test_font_weight(_obj[4])
            if _weight is None:
                continue
            _color = _test_color(_obj[5])
            if _color is None:
                continue
            _r, _g, _b = _color.getColors()
            _color = color.get_color(_r, _g, _b)
            _textstyle = text.TextStyle(_name, _family, _size, _style, _weight, _color)
            if _textstyle not in _textstyles:
                _textstyles.append(_textstyle)
    else:
        sys.stderr.write("Invalid text style list: '" + str(_dslist) + "'\n")

def _set_default_dimstyle(prefmod):
    _dimstyle = prefmod.default_dimstyle
    if isinstance(_dimstyle, (str, unicode)):
        globals.prefs['DEFAULT_DIMSTYLE'] = _dimstyle
    elif _dimstyle is None:
        pass # accept default
    else:
        sys.stderr.write("Invalid default dimension style: '" + str(_dimstyle) + "'\n")

def _set_default_textstyle(prefmod):
    _textstyle = prefmod.default_textstyle
    if isinstance(_textstyle, (str, unicode)):
        globals.prefs['DEFAULT_TEXTSTYLE'] = _textstyle
    elif _textstyle is None:
        pass # accept default
    else:
        sys.stderr.write("Invalid default text style: '" + str(_textstyle) + "'\n")

#
# this dict lists the attributes in the module and the function
# used to validate the value given by the user
#

_prefkeys = {
    'units' : _set_units,
    'user_prefs' : _set_user_prefs,
    'primary_font_family' : _set_primary_font_family,
    'primary_font_size' : _set_primary_font_size,
    'primary_font_weight' : _set_primary_font_weight,
    'primary_font_style' : _set_primary_font_style,
    'primary_font_color' : _set_primary_font_color,
    'primary_prefix' : _set_primary_prefix,
    'primary_suffix' : _set_primary_suffix,
    'primary_precision' : _set_primary_precision,
    'primary_units' : _set_primary_units,
    'primary_leading_zero' : _set_primary_print_zero,
    'primary_trailing_decimal': _set_primary_trail_decimal,
    'secondary_font_family' : _set_secondary_font_family,
    'secondary_font_size' : _set_secondary_font_size,
    'secondary_font_weight' : _set_secondary_font_weight,
    'secondary_font_style' : _set_secondary_font_style,
    'secondary_font_color' : _set_secondary_font_color,
    'secondary_prefix' : _set_secondary_prefix,
    'secondary_suffix' : _set_secondary_suffix,
    'secondary_precision' : _set_secondary_precision,
    'secondary_units' : _set_secondary_units,
    'secondary_leading_zero' : _set_secondary_print_zero,
    'secondary_trailing_decimal': _set_secondary_trail_decimal,
    'dim_offset' : _set_dim_offset,
    'dim_extension': _set_dim_extension,
    'dim_color' : _set_dim_color,
    'dim_position': _set_dim_position,
    'dim_endpoint': _set_dim_endpoint,
    'dim_endpoint_size' : _set_dim_endpoint_size,
    'dim_dual_mode' : _set_dim_dual_mode,
    'radial_dim_primary_prefix' : _set_radial_dim_primary_prefix,
    'radial_dim_primary_suffix' : _set_radial_dim_primary_suffix,
    'radial_dim_secondary_prefix' : _set_radial_dim_secondary_prefix,
    'radial_dim_secondary_suffix' : _set_radial_dim_secondary_suffix,
    'radial_dim_dia_mode' : _set_radial_dim_dia_mode,
    'angular_dim_primary_prefix' : _set_angular_dim_primary_prefix,
    'angular_dim_primary_suffix' : _set_angular_dim_primary_suffix,
    'angular_dim_secondary_prefix' : _set_angular_dim_secondary_prefix,
    'angular_dim_secondary_suffix' : _set_angular_dim_secondary_suffix,
    'font_family' : _set_font_family,
    'font_style' : _set_font_style,
    'font_weight' : _set_font_weight,
    'font_size' : _set_font_size,
    'font_color' : _set_font_color,
    'chamfer_length' : _set_chamfer_length,
    'fillet_radius' : _set_fillet_radius,
    # 'line_style' : _set_line_style,
    'line_color' : _set_line_color,
    'linetypes' : _set_linetypes,
    'colors' : _set_colors,
    'styles' : _set_styles,
    'default_style' : _set_default_style,
    'dimstyles' : _set_dimstyles,
    'default_dimstyle' : _set_default_dimstyle,
    'textstyles' : _set_textstyles,
    'default_texstyle' : _set_default_textstyle,
    'line_thickness': _set_line_thickness,
    'highlight_points' : _set_highlight_points,
    'inactive_layer_color' : _set_inactive_layer_color,
    'background_color' : _set_background_color,
    'single_point_color' : _set_single_point_color,
    'multi_point_color' : _set_multi_point_color,
    'autosplit' : _set_autosplit,
    'leader_arrow_size' : _set_leader_arrow_size,
}

def load_global_prefs():
    """Try and load the preferences stored in the global preferences file

load_global_prefs()

If the preferences file '/etc/pythoncad/prefs.py' exists and can
be read without errors, the global preferences will be set to
the values read from the file.
    """
    if os.path.isfile(pref_file):
        _f, _p, _d = imp.find_module('prefs', ['/etc/pythoncad'])
        if _f is not None:
            try:
                try:
                    _mod = imp.load_module('prefs', _f, _p, _d)
                finally:
                    _f.close()
                for _key in _prefkeys:
                    if hasattr(_mod, _key):
                        _prefkeys[_key](_mod)
            except StandardError, e: # should print the error out
                sys.stderr.write("Syntax error in %s: %s\n" % (pref_file, e))

def load_user_prefs():
    """Try and load the preferences stored in the user's preference file

load_global_prefs()

If the file '$HOME/.pythoncad/prefs.py' exists and can be read without
errors, the preferences given in that file will be used to set the
global preferences. Reading this file is conditioned upon the 'USER_PREFS'
variable being set to True.
    """
    _flag = True
    if globals.prefs.has_key('USER_PREFS'):
        _flag = globals.prefs['USER_PREFS']
    _home = None
    if os.environ.has_key('HOME'):
        _home = os.environ['HOME']
    if _flag and _home is not None:
        _pdir = os.path.join(_home, '.pythoncad')
        _user_prefs = os.path.join(_pdir, 'prefs.py')
        if os.path.exists(_user_prefs):
            _f, _p, _d = imp.find_module('prefs', [_pdir])
            if _f is not None:
                try:
                    try:
                        _mod = imp.load_module('prefs', _f, _p, _d)
                    finally:
                        _f.close()
                    for _key in _prefkeys:
                        if hasattr(_mod, _key):
                            _prefkeys[_key](_mod)
                except: # should print the error out
                    sys.stderr.write("Syntax error in %s\n" % _user_prefs)
