#! /usr/bin/env python
###############################################################################
#                                                                             #
#   Copyright 2005 University of Cambridge Computer Laboratory.               #
#                                                                             #
#   This file is part of Nprobe.                                              #
#                                                                             #
#   Nprobe 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.                                       #
#                                                                             #
#   Nprobe 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 Nprobe; if not, write to the Free Software                     #
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA #
#                                                                             #
###############################################################################


##############################################################################
## 
## 
## Data plotting tool - callable from other tools, or as free-standing plotter
## 
##
##
############################################################################ 
############################################################################ 

import string
import os
from sys import argv
import getopt
from math import modf

from sys import exit
from math import *
from math import hypot
from Tkinter import *
from tkSimpleDialog import askstring
from np_widgets import BarButton, TwoEntryDialogue, PCan, YSCROLL
from minmax import *
from np_drawutil import *
#import np_tcp 
import np_printplot
import copy
import tkColorChooser

from np_bitmaps import ccross

from np_data import DataSet, EmptyDataSetError, WrongDataTypeError, DataError, Plot_Decoration, DATA_TS, DATA_PDF, DATA_CDF, DATA_HIST, DATA_SM, DATA_RANGES, DataReader, AddFun, Dedit, EDIT, DELETE

		
############################################################################## 
#############################################################################

#
# Dimensions etc.
#

B_WI = 750
B_HT = 500

## B_WI = 1500
## B_HT = 1000


B_TB_HT = 25

#RootGeom = '%dx%d+%d+%d' % (B_WI, B_HT, B_XPOS, B_YPOS)
#RootGeom = '%dx%d' % (B_WI, B_HT)

C_LHMARGIN = 80
C_RHMARGIN = 35
C_TOPMARGIN = 50
C_BOTMARGIN = 75
C_TITLEMARGIN = 25

MIN_XTIC_WI = 100
MIN_YTIC_HI = 50

TITLEFONT = ("helvetica", 10)
LABELFONT = ("helvetica", 8)

	    
############################################################################## 
#############################################################################

#
# Data types and plotting modes
#

STYLE_POINTS = 0x1
STYLE_LINES = 0x2
STYLE_BARS = 0x4
STYLE_EBARS = 0x8
STYLE_EBARS_SD = 0x10 | STYLE_EBARS
STYLE_EBARS_SE = 0x20 | STYLE_EBARS

MODE_TS = DATA_TS
MODE_TS_SMOOTH = DATA_TS | DATA_SM
MODE_PDF = DATA_PDF
MODE_PDF_SMOOTH = DATA_PDF | DATA_SM
MODE_CDF = DATA_CDF
MODE_CDF_SMOOTH = DATA_CDF | DATA_SM
MODE_HIST = DATA_HIST
MODE_HIST_SMOOTH = DATA_HIST | DATA_SM

MODE_RANGES = DATA_RANGES

XLINE = 1
YLINE = 2

	    
############################################################################## 
#############################################################################

class Plot_canv:

    def __init__(self, plot, sets, mode=MODE_TS, 
		 style=STYLE_POINTS, fgcol='white', bgcol='black', 
		 scaledata=None, plotlinewidth=1, axislinewidth=1,
                 zero_origin=1):

	self.plot = plot
	self.scaledata = scaledata
	self.sets = sets
        if sets:
            self.dtype = sets[0].type

	self.fgcol = fgcol
	self.bgcol = bgcol

        self.zero_origin = zero_origin

	c = self.canv = Canvas(plot.frame)
	c.config(bg='black', cursor=(ccross, 'orange'))
	#c.config(bg='black', cursor=('@/usr/groups/nprobe/python/Python-2.2/Install/Misc/ccross.bmp', 'orange'))
	#c.config(bg='black', cursor=('@/home/jch1003/work/python/ccross.bmp', 'orange'))
	#c.config(bg='black', cursor=('@./ccross.bmp', 'orange'))

	self.xorg = C_LHMARGIN
	self.xwi = self.plot.wi - C_LHMARGIN - C_RHMARGIN

	self.yorg = self.plot.ht - B_TB_HT - C_BOTMARGIN
	self.yht = self.plot.ht - B_TB_HT -C_BOTMARGIN - C_TOPMARGIN

	self.bounds = (self.xorg, self.xorg+self.xwi, self.yorg-self.yht, 
		       self.yorg)

	self.xlab = plot.xlab
	self.ylab = plot.ylab

	self.min_xtic_wi = MIN_XTIC_WI
	self.min_ytic_ht = MIN_YTIC_HI

	self.xfloats = self.yfloats = 0

	self.style = style
	self.mode = mode

	self.rboxing = 0
	self.rbox = None

        c.sbox = None
        c.sboxing = 0

        c.slides = []

        self.plotlinewidth = plotlinewidth
        self.axislinewidth = axislinewidth


	Widget.bind(c, "<1>", self.mouse_1_down)
	Widget.bind(c, "<B1-Motion>", self.mouse_1_drag)
	Widget.bind(c, "<ButtonRelease-1>", self.mouse_1_up)
	Widget.bind(c, "<Double-Button-1>", self.plot.mouse_3_down)

	Widget.bind(c, "<2>", self.mouse_2_down)
	Widget.bind(c, "<B2-Motion>", self.mouse_2_drag)
	Widget.bind(c, "<ButtonRelease-2>", self.mouse_2_up)

	Widget.bind(c, "<Shift-Button-2>", self.mouse_2_shift_down)
	Widget.bind(c, "<Shift-B2-Motion>", self.mouse_2_shift_drag)
	Widget.bind(c, "<Shift-ButtonRelease-2>", self.mouse_2_up)

	Widget.bind(c, "<3>", self.mouse_3_down)
	Widget.bind(c, "<B3-Motion>", self.mouse_3_drag)
	Widget.bind(c, "<ButtonRelease-3>", self.mouse_3_up)
              
	Widget.bind(c, "<Shift-Button-3>", self.mouse_3_shift_down)
	Widget.bind(c, "<Shift-B3-Motion>", self.mouse_3_shift_drag)
	Widget.bind(c, "<Shift-ButtonRelease-3>", self.mouse_3_up)

	Widget.bind(c, "<Control-Button-3>", self.mouse_3_control_down)
	Widget.bind(c, "<Control-B3-Motion>", self.mouse_3_control_drag)
	Widget.bind(c, "<Control-ButtonRelease-3>", self.mouse_3_control_up)

	self.setup()

##############################################################################


    def mouse_1_down(self, event):
	# set origin of selection box
	canv = event.widget
	x = canv.canvasx(event.x)
	y = canv.canvasy(event.y)

	x = MAX(x, self.bounds[0])
	x = MIN(x, self.bounds[1])
	y = MIN(y, self.bounds[3])
	y = MAX(y, self.bounds[2])

	#print 'B1 %d, %d' % (x, y)
	#self.rboxing = 1
	canv.startx=x
	canv.starty=y
	canv.rbox = None

##############################################################################

    def mouse_1_drag(self, event):
	# draw selection box
	canv = event.widget
	x = canv.canvasx(event.x)
	y = canv.canvasy(event.y)

	x = MAX(x, self.bounds[0])
	x = MIN(x, self.bounds[1])
	y = MIN(y, self.bounds[3])
	y = MAX(y, self.bounds[2])
    
	#if self.rboxing and canv.startx != x  and canv.starty != y :
	if canv.startx != x  and canv.starty != y :
	    self.rboxing = 1 
	    canv.delete(canv.rbox)
	    canv.rbox = canv.create_rectangle(
		canv.startx, canv.starty, x, y, outline='red', stipple='gray75')
	    canv.lastx = x
	    canv.lasty = y
		
	    

##############################################################################
		
    def mouse_1_up(self, event):

	canv = event.widget
	if canv.rbox != None:
	    canv.delete(canv.rbox)
	    canv.rbox = None
	if self.rboxing:
	    self.rboxing = 0
	else:
	    return
	x = canv.canvasx(event.x)
	y = canv.canvasy(event.y)

	x = MAX(x, self.bounds[0])
	x = MIN(x, self.bounds[1])
	y = MIN(y, self.bounds[3])
	y = MAX(y, self.bounds[2])
    

	# don't zoom for small movement on dbl click
	if abs(x-canv.startx) < 5 or abs(y-canv.starty) < 5:
	    return
	scaledata = self.find_indices(event, canv.startx, canv.starty, 1)
	plot = self.plot

	#scaledata = (xmaxval, xminval, ymaxval, yminval, xscalef, yscalef, xrangeval, yrangeval, self.xfloats, self.yfloats)
        #print 'last top %d' % (plot.is_top[-1])
	plot.is_top.append(self.plot.is_top[-1])
	c = Plot_canv(plot, self.sets, style=self.style, mode=self.mode,
                      scaledata=scaledata)
	plot.canvasses[plot.canv_curr].canv.pack_forget()
	plot.canvasses.append(c)
	plot.canv_curr = plot.canv_curr + 1
	c.canv.pack(side=LEFT, fill=BOTH, expand = 1)
	#self.plot.is_top.append(self.plot.is_top[-1])

##############################################################################


    def mouse_2_down(self, event):
	# set origin of selection box
	canv = event.widget
	x = canv.canvasx(event.x)
	y = canv.canvasy(event.y)

	#print 'B1 %d, %d' % (x, y)
	#self.rboxing = 1
	canv.start1x=x
	canv.start1y=y
	canv.sbox = None

##############################################################################


    def mouse_2_shift_down(self, event):

	canv = event.widget
	xpos = canv.canvasx(event.x)
	ypos = canv.canvasy(event.y)

	xpos = MAX(xpos, self.bounds[0])
	xpos = MIN(xpos, self.bounds[1])
	ypos = MIN(ypos, self.bounds[3])
	ypos = MAX(ypos, self.bounds[2])

        gt = canv.gettags
        co = canv.coords
        nr = canv.find_enclosed(xpos-10, ypos-10, xpos+10, ypos+10)
        nrc = [n for n in nr if 'ctr' in gt(n)]
        if nrc:
            x = xpos
            y = ypos
            clo = nrc[0]
            coords = co(clo)
            dst = hypot(coords[0]-xpos, coords[1]-ypos)
            for n in nrc[1:]:
                coords = co(n)
                ndst = hypot(coords[0]-xpos, coords[1]-ypos)
                if ndst < dst:
                    dst = ndst
                    clo = n
            coords = canv.coords(clo)
            xpos, ypos = coords[0], coords[1]
            canv.slidecol = canv.itemcget(clo, 'fill')
            t = gt(clo)
            canv.slides = canv.find_withtag(t[0])
            canv.start1x = canv.lastx = x
            canv.start1y = canv.lasty = y

            self.postxt = canv.create_text(x, y, text='')

##############################################################################

    def mouse_2_shift_drag(self, event):

        
	canv = event.widget
        if not canv.slides:
            return
        co = canv.coords
        mv = canv.move
	x = canv.canvasx(event.x)
	y = canv.canvasy(event.y)

        bb = canv.bbox(self.postxt)
        xwi = bb[2] - bb[0]
        canv.delete(self.postxt)

        TEXT = canv.create_text

        dx = x - canv.lastx
        dy = y - canv.lasty

        for i in canv.slides:
            mv(i, dx, dy)

        xv = ((x-canv.start1x)/self.xscalef)
        yv = ((canv.start1y - y)/self.yscalef)

        off = 10
        if x + xwi - off < self.bounds[1]:
            anch = W
        else:
            off = -off
            anch = E

        self.postxt = TEXT(x+off, y, text='%+f %+f' % (xv, yv),
                           anchor=anch, fill=canv.slidecol,
                           font=("helvetica", 10, "bold") )
            
        canv.lastx=x
        canv.lasty=y

##############################################################################

    def mouse_2_drag(self, event):
	# draw selection box
	canv = event.widget
	x = canv.canvasx(event.x)
	y = canv.canvasy(event.y)
    
	#if self.rboxing and canv.startx != x  and canv.starty != y :
	if canv.start1x != x  and canv.start1y != y :
	    canv.sboxing = 1 
	    canv.delete(canv.sbox)
	    canv.sbox = canv.create_rectangle(
		canv.start1x, canv.start1y, x, y, outline='blue', stipple='gray75')
	    canv.lastx = x
	    canv.lasty = y
		
	    

##############################################################################
		
    def mouse_2_up(self, event):

	canv = event.widget
	if canv.sbox != None:
	    canv.delete(canv.sbox)
	    canv.sbox = None
	x = canv.canvasx(event.x)
	y = canv.canvasy(event.y)

        if canv.slides:
            mv = canv.move
            dx = canv.start1x -  canv.lastx
            dy = canv.start1y - canv.lasty 
            for i in canv.slides:
                mv(i, dx, dy)
            canv.slides = []
	    canv.delete(self.postxt)
            
	if canv.sboxing:
	    canv.sboxing = 0
	else:
	    return

	if abs(x-canv.start1x) < 5 or abs(y-canv.start1y) < 5:
	    return
        
	tdict = {}
	scaledata = self.find_indices(event, canv.start1x, canv.start1y, 0)
        xmin = scaledata[1]
        xmax = scaledata[0]
	ymin = scaledata[3]
	ymax = scaledata[2]
	for s in self.sets:
	    if s.callback == None or s.hidden[-1]:
		continue
	    i1, i2 = s.curr_indices[-1]
	    for d in s.data[i1:i2+1]:
		if ymin <= d[1] <= ymax and xmin <= d[0] <= xmax:
		    try:
			for p in d[3]:
			    if not tdict.has_key(p):
				tdict[p] = None
		    except IndexError:
			# this data doesn't have a tags list
			pass

	tlist = tdict.keys()
        if len(tlist):
            s.callback(tlist)
		
##############################################################################
		
    def mouse_3_down(self, event):

         self.mouse_3_down_all(event, 0)
		
		
##############################################################################
		
    def mouse_3_shift_down(self, event):

         self.mouse_3_down_all(event, 1)
		
##############################################################################
		
    def mouse_3_down_all(self, event, shift):

	canv = event.widget
	xpos = canv.canvasx(event.x)
	ypos = canv.canvasy(event.y)

	xpos = MAX(xpos, self.bounds[0])
	xpos = MIN(xpos, self.bounds[1])
	ypos = MIN(ypos, self.bounds[3])
	ypos = MAX(ypos, self.bounds[2])

        TEXT = canv.create_text

        #print 'xy', xpos, ypos
        col = 'white'

        if shift:
            gt = canv.gettags
            co = canv.coords
            nr = canv.find_enclosed(xpos-10, ypos-10, xpos+10, ypos+10)
            nrc = [n for n in nr if 'ctr' in gt(n)]
            if nrc:
                clo = nrc[0]
                coords = co(clo)
                dst = hypot(coords[0]-xpos, coords[1]-ypos)
                for n in nrc[1:]:
                    coords = co(n)
                    ndst = hypot(coords[0]-xpos, coords[1]-ypos)
                    if ndst < dst:
                        dst = ndst
                        clo = n
                coords = canv.coords(clo)
                xpos, ypos = coords[0], coords[1]
                #print 'nr xy', clo, xpos, ypos
                col = canv.itemcget(clo, 'fill')

##             else:
##                 xpos = None
##                 self.postxt = TEXT(0, 0, text='')

        if xpos:
            x = ((xpos-self.xorg)/self.xscalef) + self.xmin
            y = ((self.yorg-ypos)/self.yscalef) + self.ymin
            
            self.postxt = TEXT(xpos+10, ypos, text='%f %f' % (x, y), anchor=W,
                               fill=col,
                               font=("helvetica", 10, "bold") )
		
##############################################################################
		
    def mouse_3_drag(self, event):

        self.mouse_3_drag_all(event, 0)
		
##############################################################################
		
    def mouse_3_shift_drag(self, event):

        self.mouse_3_drag_all(event, 1)
		
##############################################################################
		
    def mouse_3_drag_all(self, event, shift):

	canv = event.widget
	xpos = canv.canvasx(event.x)
	ypos = canv.canvasy(event.y)

	xpos = MAX(xpos, self.bounds[0])
	xpos = MIN(xpos, self.bounds[1])
	ypos = MIN(ypos, self.bounds[3])
	ypos = MAX(ypos, self.bounds[2])

        bb = canv.bbox(self.postxt) 
        xwi = bb[2] - bb[0]
        canv.delete(self.postxt)

        TEXT = canv.create_text
        col = 'white'

        if shift:
            gt = canv.gettags
            co = canv.coords
            nr = canv.find_enclosed(xpos-10, ypos-10, xpos+10, ypos+10)
            nrc = [n for n in nr if 'ctr' in gt(n)]
            if nrc:
                clo = nrc[0]
                coords = co(clo)
                dst = hypot(coords[0]-xpos, coords[1]-ypos)
                for n in nrc[1:]:
                    coords = co(n)
                    ndst = hypot(coords[0]-xpos, coords[1]-ypos)
                    if ndst < dst:
                        dst = ndst
                        clo = n
                coords = canv.coords(clo)
                xpos, ypos = coords[0], coords[1]
                #print 'nr xy', clo, xpos, ypos
                col = canv.itemcget(clo, 'fill')
        ##     else:
##                 xpos = None
##                 self.postxt = TEXT(0, 0, text='')

        if xpos:

            x = ((xpos-self.xorg)/self.xscalef) + self.xmin
            y = ((self.yorg-ypos)/self.yscalef) + self.ymin

            off = 10
            if xpos + xwi - off < self.bounds[1]:
                anch = W
            else:
                off = -off
                anch = E

            self.postxt = TEXT(xpos+off, ypos, text='%f %f' % (x, y),
                               anchor=anch, fill=col,
                               font=("helvetica", 10, "bold") )
		
##############################################################################
		
    def mouse_3_up(self, event):

	canv = event.widget

        canv.delete(self.postxt)
		
##############################################################################
		
    def mouse_3_control_down(self, event):

	canv = event.widget
	xpos = canv.canvasx(event.x)
	ypos = canv.canvasy(event.y)

	xpos = MAX(xpos, self.bounds[0])
	xpos = MIN(xpos, self.bounds[1])
	ypos = MIN(ypos, self.bounds[3])
	ypos = MAX(ypos, self.bounds[2])
        
	self.startx=xpos
	self.starty=ypos
	self.scaleline = None
	self.scaletxt = None
        self.rscaling = 1
		
##############################################################################
		
    def mouse_3_control_drag(self, event):

	canv = event.widget
	xpos = canv.canvasx(event.x)
	ypos = canv.canvasy(event.y)

	xpos = MAX(xpos, self.bounds[0])
	xpos = MIN(xpos, self.bounds[1])
	ypos = MIN(ypos, self.bounds[3])
	ypos = MAX(ypos, self.bounds[2])
        
	if self.startx != xpos or self.starty != ypos:

            if self.scaletxt:
                bb = canv.bbox(self.scaletxt) 
                xwi = bb[2] - bb[0]
            else:
                xwi = 120
	    canv.delete(self.scaleline) 
	    canv.delete(self.scaletxt)

            xdelta = (xpos-self.startx)/self.xscalef
            ydelta = (self.starty-ypos)/self.yscalef

            TEXT = canv.create_text
            LINE = canv.create_line

            off = 10
            if xpos + xwi - off < self.bounds[1]:
                anch = W
            else:
                off = -off
                anch = E

            self.scaletxt = TEXT(xpos+off, ypos, text='%+f %+f' % (xdelta, ydelta), anchor=anch, fill='white',
             font=("helvetica", 10, "bold"))
            self.scaleline = LINE(self.startx, self.starty, xpos, ypos,
                                  width=1, fill='white')
            
		
##############################################################################
		
    def mouse_3_control_up(self, event):

	canv = event.widget

        if self.rscaling:
            canv.delete(self.scaletxt)
            canv.delete(self.scaleline)
            self.rscaling = 0
	    

##############################################################################

    def find_indices(self, event, sx, sy, append_indices):

	canv = event.widget
	x = canv.canvasx(event.x)
	y = canv.canvasy(event.y)

	x = MAX(x, self.bounds[0])
	x = MIN(x, self.bounds[1])
	y = MIN(y, self.bounds[3])
	y = MAX(y, self.bounds[2])
    

	xmin = MIN(x, sx)-self.xorg
	xmax = MAX(x, sx)-self.xorg
	xminval = xmin/self.xscalef + self.xmin
	xmaxval = xmax/self.xscalef + self.xmin
	xrange = xmax - xmin
	if xrange == 0:
	    return (newi1, newi2)
	xrangeval = xmaxval - xminval
	xscalef = float(self.xwi/xrangeval)

	ymin = self.yorg - MAX(y, sy)
	ymax = self.yorg - MIN(y, sy)
	yminval = ymin/self.yscalef + self.ymin
	ymaxval = ymax/self.yscalef + self.ymin
	yrange = ymax - ymin
	if yrange == 0:
	    return (newi1, newi2)
	yrangeval = ymaxval - yminval
	yscalef = float(self.yht/yrangeval)
	#print xminval
	#i = 0

	for s in self.sets:
	    i1, i2 = s.curr_indices[-1]
	    if i1 == None:
		# this set is zoomed out of range
		if append_indices:
		    s.curr_indices.append((i1, i2))
		    s.hidden.append(s.hidden[-1])
		continue
	    try:
		newi1 = find_point(xminval, s.data, i1, i2, P_BEFORE)
	    except NotInRange:
		#print 'for newi1 value %.3f not in range %.3f-%.3f' % (xminval, s.data[i1][0], s.data[i2][0])
		if xminval < s.data[0][0] < xmaxval:
		    #print '%.3f < %.3f < %.3f' % (xminval, s.data[0][0], xmaxval)
		    newi1 = 0
		else:
		    #print 'not %.3f < %.3f < %.3f' % (xminval, s.data[0][0], xmaxval)
		    newi1 = None

	    try:
		newi2 = find_point(xmaxval, s.data, i1, i2, P_AFTER)
	    except NotInRange:
		#print 'for newi2 value %.3f not in range %.3f-%.3f' % (xmaxval, s.data[i1][0], s.data[i2][0])
		if xminval < s.data[-1][0] < xmaxval:
		    #print '%.3f < %.3f < %.3f' % (xminval, s.data[-1][0], xmaxval)
		    newi2 = s.len - 1
		else:
		    #print 'not %.3f < %.3f < %.3f' % (xminval, s.data[-1][0], xmaxval)
		    newi2 = None

	    #print 'newi1=%s newi2=%s' % (repr(newi1), repr(newi2))

	    if newi1 == None:
		newi2 = None
	    if newi2 == None:
		newi1 = None

	    if append_indices:
		s.hidden.append(s.hidden[-1])
		s.curr_indices.append((newi1, newi2))
		if newi1 == None:
		    try:
			#s.ops.configure(fg='red')
			s.ops.top.configure(state=DISABLED)
			s.ops.hide.configure(state=DISABLED)
			s.ops.col.configure(state=DISABLED, background='grey')
		    except AttributeError:
			# only one set
			pass

	    

	scaledata = (xmaxval, xminval, ymaxval, yminval, xscalef, yscalef, xrangeval, yrangeval, self.xfloats, self.yfloats)

## 	print 'i1=%d->%d i2=%d->%d' % (self.i1, newi1, self.i2, newi2)

## 	print 'xminval=%.3f xmaxval=%.3f' % (self.data[newi1][0], 
## 					     self.data[newi2][0])
## 	print 'xmin=%.3f xmax=%.3f xrange=%.3f' % (xminval, xmaxval, xrangeval)

	return scaledata
	

##############################################################################

    def setup(self):

        self.order = [] # record of drawing order
        if not self.sets:
            return
        for s in self.sets:
            s.newcol = s.col
	#print self.data, self.i1, self.i2
	if self.scaledata == None:
	    # first canvas - scale
	    self.scale()
	else:
	    self.use_scaledata()
	self.draw_axes()
	self.draw()
	self.draw_labels()

##############################################################################

    def draw_title(self, t):

	TEXT = self.canv.create_text
	x = self.xorg + self.xwi/2
	y = self.yorg + C_BOTMARGIN/2 + 5
        
        # replace DIV
        t = t.replace('DIV', '/')

        if self.plot.sspec:
            t += '-sm.%s' % (self.plot.sspec)

	TEXT(x, y, text=t, fill=self.fgcol, font=TITLEFONT, anchor=CENTER, 
	     tags='la')

##############################################################################

    def basename(self, path):

        # allow escape for '/' in plot label (eg. interrupts //sec.)
        i = string.find(path, '//')

        if i == -1:
            return os.path.basename(path)
        else:
            return os.path.basename(path[:i]) + path[i+1:]

##############################################################################

    def draw_labels(self):

	c = self.canv
	TEXT = c.create_text
	LINE = c.create_line
        width = self.plotlinewidth
	x = self.xorg+self.xwi
	y = C_TITLEMARGIN

	t = self.plot.title
	tl = len(t)
	if tl:
	    self.draw_title(t)

	ts = self.sets[self.plot.is_top[-1]]
	p = os.path.split(ts.path)[1]
	if tl == 0:
	    self.draw_title(p)

	i = 0
	for s in self.sets:
	    if not s.hidden[-1]:
                #print s.path
		p = self.basename(s.path)
                #p = s.path
		if not len(p):
		    p = '%d' % (i)
                if len(self.sets) > 1 and self.plot.is_top[-1] == s.indx:
                    p = '> ' + p
                # add any smoothing suffix
                p += s.opath
                # replace DIV
                p = p.replace('DIV', '/')
		col = s.col
		if col == None:
		    col = self.fgcol
		tt = TEXT(x-10, y, text=p, fill=col,  font=TITLEFONT, anchor=NE, tags='la')
		bb = c.bbox(tt)
		y = (bb[1]+bb[3])/2
		LINE(x-1,y,x+1,y,fill=col, tags='la', width=width)
		LINE(x,y-1,x,y+1,fill=col, tags='la', width=width)
		y =  bb[3]
                if self.mode & (MODE_PDF| MODE_HIST):
                    try:
                        inf = '\n%d Samples Min = %.3f Max = %.3f Range = %.3f\nMean = %.3f sd = %.3f, V = %.3f' % (s.tslen, s.min, s.max, s.range, s.mean, 					       s.sd, s.variance)
                        tt = TEXT(x-10, y, text=inf, fill=col,  font=LABELFONT, 
                                  anchor=NE, tags='la')
                        bb = c.bbox(tt)
                        y =  bb[3]
                    except AttributeError:
                        # may be no statsdata
                        pass

		
	    i += 1

	return y
	

##############################################################################

    def scale(self):

	mmbase = self.sets[0]
	ibase = self.sets[0].curr_indices[-1][0]
	self.xmax = self.xmin = mmbase.data[ibase][0]
        #print ibase, mmbase.data[ibase]
	self.ymax = self.ymin = mmbase.data[ibase][1]
        style = self.plot.stylev_curr.get()
	for s in self.sets:
	    #print data
	    i1, i2 = s.curr_indices[-1]
	    if i1 == None:
		continue
	    data = s.data
	    #s.printself()
	    xmax = xmin = data[i1][0]
	    ymax = ymin = data[i1][1]

            # allow for error bars?
            eb = 0
            if (style & STYLE_EBARS) and ('SD' in s.fields or 'SD' in s.fields):
                if style == STYLE_EBARS_SD:
                    ebdi = s.fields.index('SD')
                elif style == STYLE_EBARS_SE:
                    ebdi = s.fields.index('SE')
                #print 'ebdi', ebdi
                if len(data[i1]) > ebdi:
                    eb = 1
                    ymin = data[i1][1]-data[i1][ebdi]
                    ymax = data[i1][1]+data[i1][ebdi]

	    llen = 0

	    for p in data[i1:i2+1]:
		llen = llen + 1
		x = p[0]
		y = p[1]
		if not int(x) == x:
		    self.xfloats = 1
		else:
		    p[0] = float(x)
		if not int(y) == y:
		    self.yfloats = 1
		else:
		    p[1] = float(y)
		xmax = MAX(xmax, x)
		xmin = MIN(xmin, x)
                if eb:
                    ymax = max(ymax, y+p[ebdi])
                    ymin = min(ymin, y-p[ebdi])
                else:
                    ymax = MAX(ymax, y)
                    ymin = MIN(ymin, y)


	    self.xmax = MAX(self.xmax, xmax)
	    self.xmin = MIN(self.xmin, xmin)
	    self.ymax = MAX(self.ymax, ymax)
	    self.ymin = MIN(self.ymin, ymin)


	if self.mode == MODE_PDF:
	    ymin = 0.0
        if self.zero_origin:
            self.ymin = min(0.0, self.ymin)
        if self.mode & MODE_HIST and self.mode & MODE_RANGES:
            self.xmin = self.xmin - self.get_bktsz(s)

	xrange = float(self.xmax - self.xmin)
	if xrange == 0.0:
	    xrange = float(self.xmax/10)
	try:
	    self.xscalef = float(self.xwi/xrange)
	except ZeroDivisionError:
	    xrange = 10.0
	    self.xscalef = float(self.xwi/xrange)

	yrange = float(self.ymax - self.ymin)
	if yrange == 0:
	    yrange = float(self.ymax/10)
	try:
	    self.yscalef = float(self.yht/yrange)
	except ZeroDivisionError:
	    yrange = 10.0
	    self.yscalef = float(self.yht/yrange)
	self.xrange = xrange
	self.yrange = yrange

	# print 'scale x: max=%.3f min=%.3f scalef=%f y: max=%.3f min=%.3f scalef=%f' % (self.xmax, self.xmin, self.xscalef, self.ymax, self.ymin, self.yscalef)

##############################################################################

    def use_scaledata(self):

	s = self.scaledata

	self.xmax = s[0]
	self.xmin = s[1]
	self.ymax = s[2]
	self.ymin = s[3]
	self.xscalef = s[4]
	self.yscalef = s[5]
	self.xrange = s[6]
	self.yrange = s[7]
	self.xfloats = s[8]
	self.yfloats = s[9]

##############################################################################

    def draw_axes(self):

	LINE = self.canv.create_line
        width = self.axislinewidth
        TEXT = self.canv.create_text

	if self.mode == MODE_PDF:
	    xlab = self.ylab
	    ylab = 'Probability\nof occurence'

	elif self.mode == MODE_CDF:
	    xlab = self.ylab
	    ylab = 'Cumulative\nProbability\nof occurence'
	else:
	    xlab = self.xlab
	    ylab = self.ylab

	xlab = self.draw_xtics(xlab)
	ylab = self.draw_ytics(ylab)

	# y axis
	LINE(self.xorg, self.yorg, self.xorg, self.yorg-self.yht, 
	     fill=self.fgcol, width=width)
	TEXT(self.xorg, self.yorg-self.yht-15, text=ylab, 
	     fill=self.fgcol, anchor = SE, font=LABELFONT)
	# x axis
	LINE(self.xorg, self.yorg, self.xorg+self.xwi, self.yorg, 
	     fill=self.fgcol, width=width)
	TEXT(self.xorg+self.xwi, self.yorg+20, text=xlab, fill=self.fgcol, 
	     anchor = NE, font=LABELFONT)
	
##############################################################################
	    

    def calc_ticfacts(self, ticsep, scalef, range, floats):

        try:
            t = ticsep/scalef
        except OverflowError:
            print 'ticfacts except: range=%s scalef=%s' % (repr(range),
                                                           repr(scalef))
            inc = range
            axinc = inc*scalef
            return (axinc, inc)

        #print 'ticfacts: range%s scalef%s' % (repr(range), repr(scalef))
        #print 't=%.3f' % (t)

        #inc = 1.0000000000000
        inc = 0.000001

        while inc < t:
            inc = inc*10

        lastdelta = abs(inc - t)
        lastinc = inc
        biginc = inc
        for scale in [2,4,10]:
            thisinc = inc/scale
            delta = abs(thisinc - t)
            if delta > lastdelta:
                break
            lastdelta = delta
            lastinc = thisinc

        smallinc = lastinc
        if smallinc == biginc/4 or smallinc == biginc/10:
            medinc = biginc/2
        else:
            medinc = biginc

        if smallinc == 0:
            smallinc = medinc = biginc = 1 #?

        axinc = smallinc*scalef

        return (axinc, smallinc, medinc, biginc) 
	
##############################################################################
	    

    def calc_ticfacts_time(self, ticsep, scalef, range, floats, unit):

        #print 'calc_ticfacts_time: unit \'%s\' range=%s' % (unit, repr(range))
        scales1 = [2, 4, 10]
        scales2 = [2, 4, 12]
        scales3 = [2, 4, 24]
        inc1 = 0.000000001
        tunits = [('', 1, None),
                  ('ns', 1000, scales1),
                  ('us', 1000, scales1, inc1),
                  ('ms', 1000, scales1, inc1),
                  ('s', 60, scales1),
                  ('m', 60, scales2),
                  ('h', 24, scales2),
                  ('days', 1, scales3)]
        start = [units[0] for units in tunits].index(unit)

        unit = tunits[start][0]
        scales = tunits[start][2]
        fact = 1.0
        
        while tunits[start][1] > 1:
            newfact = tunits[start][1]
            if range < fact*newfact:
                break
            start += 1
            unit = tunits[start][0]
            scales = tunits[start][2]
            fact = fact*newfact


        #print 'calc_ticfacts_time: unit %s, fact=%s, scales ' % (unit, repr(fact)),
        #print scales
            
	try:
	    t = ticsep/scalef
	except OverflowError:
            print 'ticfacts_time except: range=%s scalef=%s' % (repr(range),
                                                           repr(scalef))
	    inc = range
	    xinc = inc*scalef
	    return (xinc, inc)

        #print 'ticfacts_time: range=%s scalef=%s' % (repr(range), repr(scalef))
        #print 't=%.3f' % (t)
        
        inc = 0.000000001*fact


	while inc < t:
            #print 'inc %s' % (repr(inc)) 
	    inc = inc*10

        #print 'inc %s' % (repr(inc))

	lastdelta = abs(inc - t)
	lastinc = inc
        biginc = inc
	for scale in scales:
	    thisinc = inc/scale
	    delta = abs(thisinc - t)
	    if delta > lastdelta:
		break
	    lastdelta = delta
	    lastinc = thisinc
            #print 'lastinc %s' % (repr(lastinc))

	smallinc = lastinc
        if smallinc == biginc/scales[1] or smallinc == biginc/scales[-1]:
            medinc = biginc/2
        else:
            medinc = smallinc

        if smallinc == 0:
            smallinc = medinc = biginc = 1 #?

        axinc = smallinc*scalef

        #print 'axinc=%s, incs=%s/%s/%s , unit=\'%s\'' % (repr(axinc), repr(smallinc), repr(medinc), repr(biginc), unit)

	return (axinc, smallinc, medinc, biginc, fact, unit)
	
###############################################################################

    def parse_lab(self, lab):
        
        if lab.count('%'):
            i = lab.index('%')
            if  lab[i+1] != '%':
                return (lab[:i], lab[i+1:])
            #else:
                #return (lab[:i] + lab[i+1:], 'dec')

        return (lab, 'dec')
	
###############################################################################

    def draw_ytics(self, lab):

        return self.draw_tics(-1, self.ymin, self.yrange, self.yscalef,
                              self.yorg, self.min_ytic_ht, self.yfloats,
                              self.yht, lab)
	
###############################################################################

    def draw_xtics(self, lab):
        
        return self.draw_tics(1, self.xmin, self.xrange, self.xscalef,
                              self.xorg, self.min_xtic_wi, self.xfloats,
                              self.xwi, lab, trace=0)
	
###############################################################################

    def draw_tics(self, dir, minval, range, scalef, org, ticsep,
                  floats, dim, lab, trace=0):

        def keepgoing(dir, pos, org, dim):

            if dir == 1 and pos <= org+dim:
                return 1
            elif dir == -1 and pos >= org-dim:
                return 1
            else:
                return 0

        def near_nuff(val, inc):

            if fabs(fmod(val, inc)) < inc/100:
                return 1
            else:
                return 0

        def pretty(v, min_places):

            def ppr(v, val, places):
                fmt = '%%.%df' % (places)
               # print 'printing', fmt % (val), '%d places v=%.10f' % (places, v)

            # pretty print tic values

            #print min_places
            
##             if int(v) == v:
##                 #print 'int', v
##                 #print 'printing %d' % (int(v))
##                 return ('%d' % (int(v)), 0)

            SF = 3
            savev = v
            places = 0
            blanks = 0
            sf = 0
            reps = 0
            last_trailer = None
            #print 'start printing %.10f'% (v)
            while modf(v)[0]:
                #print 'upping',
                #ppr(v, savev, places)
                places += 1
                v *= 10
                ip = modf(v)[1]
                if ip != 0:
                    sf += 1 # got a s.f.
                if not ip%10:
                    blanks += 1 # this place doesn't add to precision
                    if (blanks == SF and sf >= SF) or blanks >= 10: # enough s.f. and precision
                        #print 'blanks break'
                        break
                if last_trailer != None and ip%10 == last_trailer:
                    reps += 1
                    if reps >= SF and sf >= SF:
                        #print 'reps break'
                        break
                last_trailer = ip%10

            places = max([min_places, places])
            
            #print 'endup',
            #ppr(v, savev, places)
            fmt = '%%.%df' % (places)
            str = fmt % (savev)

            # consume any trailing zeros
            while str[-1] == '0' and places > min_places:
                places -=1
                fmt = '%%.%df' % (places)
                str = fmt % (savev)

            #print 'final',
            #ppr(v, savev, places)
            #print 'xxxxxx'

            return (str, places)

        def time_pretty(v, unit):
            
           # print 'time', v, unit

            if unit == 'h' or unit == 'm':
                minor = (v*60)%60
            elif unit == 'days':
                minor = (v*24)%24

            v = floor(v)

            if minor:
                return '%d' % (minor)
            else:
                return '%.0f' % (v)

    #
    # Start main function
    #

        if dir == 1:
            ds = 'X'
        else:
            ds = 'Y'

        #print ds

        if trace:
            print '%stics: minval=%s maxval=%s range=%s\nfloats %d org %d' \
              % (ds, repr(minval), repr(minval+range), repr(range), floats,
                 org)
	LINE = self.canv.create_line
        width = self.axislinewidth
	TEXT = self.canv.create_text

        lab, unit = self.parse_lab(lab)
        if unit == 'dec':
            fact = 1
            axinc, smallinc, medinc, biginc  = self.calc_ticfacts(ticsep,
                                           scalef, range, floats)
        else:
            axinc, smallinc, medinc, biginc, fact, unit \
                   = self.calc_ticfacts_time(ticsep, scalef, range, floats,
                                             unit)
            lab += unit
        
        if trace:
            print '%stics: axinc=%s incs=%s/%s/%s' % (ds, axinc,
                        repr(smallinc), repr(medinc), repr(biginc))
	val = minval
	adj = 0
        pos = org
	# get the first tic to a sensible value
	baseadj = minval%smallinc
	if baseadj:
	    val = minval + smallinc - baseadj
	    # offset the tics
	    adj = dir*int(baseadj*scalef)
            pos = org - adj + dir*axinc    

        if trace:
            print '%stics baseadj=%s val=%s adj=%s pos=%s' % (ds,
                        repr(baseadj), repr(val), repr(adj), repr(pos)) 

        if dir == -1:
            ticstart = self.xorg
        else:
            ticstart = self.yorg
            
        smalltic = 4
        medtic = 7
        bigtic = 10

        bigfont = ("helvetica", 8)
        medfont = ("helvetica", 6)

        savepos = pos
        saveval = val
        printsmalls = 0
        printed = 0

        # establish min places
        min_places = 0
        while keepgoing(dir, pos, org, dim):
            min_places = max([pretty(val, 0)[1], min_places])
            pos = pos+(dir*axinc)
            val = val+smallinc

        passes = 0
        while printed < 2 and passes < 3:
            pos = savepos
            val = saveval
            while keepgoing(dir, pos, org, dim):
                if trace:
                    print '%stics val=%s pos=%s label=%s val%%biginc=%s' % (ds,
                          repr(val), repr(pos), repr(val/fact), repr(val%biginc))
                if near_nuff(val, biginc) or val == 0.0:
                    ticend = ticstart + (dir*bigtic)
                    font=bigfont
                    printed += 1
                elif near_nuff(val, medinc) or medinc == biginc:
                    ticend = ticstart + (dir*medtic)
                    font = medfont
                    printed += 1
                else:
                    ticend = ticstart + (dir*smalltic)
                    font = medfont
                    if printsmalls:
                        printed += 1
                if unit in ['dec', 's', 'us', 'ns']:
                    ticstr = pretty(float(val)/fact, min_places)[0]
                else:
                    ticstr = time_pretty(float(val)/fact, unit)
                if dir == 1:
                    # x-axis
                    LINE(pos, ticstart, pos, ticend, fill=self.fgcol,
                         width=width)
                    TEXT(pos, ticend+2, text=ticstr,
                         fill=self.fgcol, anchor = N, font=font)
                else:
                    LINE(ticstart, pos, ticend, pos, fill=self.fgcol,
                         width=width, tag='yt')
                    TEXT(ticend-2, pos, text=ticstr,
                         fill=self.fgcol, anchor = E, font=font, tag='yt')

                pos = pos+(dir*axinc)
                val = val+smallinc
            printsmalls += 1
            passes += 1

        return lab
	
###############################################################################

    def draw(self):

       # print 'top is %d' % (self.plot.is_top[-1])
	topset = None
	for s in self.sets:
            #print '#%d %d %d' % (s.indx, s.curr_indices[-1][0], s.curr_indices[-1][1])
            #print 'Set', s
	    if s.indx == self.plot.is_top[-1] \
                   and s.curr_indices[-1][1] >= s.curr_indices[-1][0]:
		topset = s
		#print 'topset=%d' % (s.indx)
		continue
            if s.curr_indices[-1][1] >= s.curr_indices[-1][0] and not s.hidden[-1]:
                self.draw_set(s)
	        #print 'drawing set %d' % (s.indx)
                self.order.append(s.indx)
                #print 'append %d' % (s.indx)

        if topset:
            indx = topset.indx
            self.draw_set(topset)
            self.order.append(indx)
	   # print 'drawing topset %d' % (indx)
        else:
            if self.order:
                indx =  self.order[-1]
            else:
                indx = 0

        self.plot.topset.set(indx)
        self.plot.is_top[-1] = indx

        self.draw_decs()
	
###############################################################################

    def draw_decs(self):
        
        for d in self.plot.decs:

            type = d.type

            if type == XLINE:
                for x in d.coords:
                    if self.xmin < x < self.xmax:
                        x -= self.xmin
                        xc = x*self.xscalef + self.xorg
                        self.canv.create_line(xc, self.yorg, xc,
                               self.yorg-self.yht, fill=d.col, width=1,
                               tags=('decs'))

            elif type == YLINE:
                for y in d.coords:
                    if self.ymin < y < self.ymax:
                        y -= self.ymin
                        yc = self.yorg - y*self.yscalef
                        self.canv.create_line(self.xorg, yc,
                               self.xorg+self.xwi, yc, fill=d.col, width=1,
                                              tags=('decs'))
	
###############################################################################

    def undraw_decs(self):

        dels = self.canv.find_withtag('decs')
        for d in list(dels):
            self.canv.delete(d)
	
###############################################################################

    def redraw_decs(self):

        self.undraw_decs()
        self.draw_decs()

##############################################################################

    def get_bktsz(self, set):

        if set.bktsz:
            return set.bktsz
        else:
            start = (set.data[-1][0] - set.data[0][0])/len(set.data)
            last = set.data[0][0]
            for p in set.data[1:]:
                start = min(start, p[0]-last)
                last = p[0]
            set.bktsz = start
            return start
	
###############################################################################

    def draw_set(self, set):

       # print 'draw-set', set.indx, set.hidden
	if set.hidden[-1]:
	    return

       # print 'in draw set'

	i1, i2 = set.curr_indices[-1]
	#print 'i1=' + repr(i1) + ' i2=' + repr(i2)
	if i1 == None:
	    return
	#col = 'blue'
	style = self.style
	bounds = self.bounds

	xmin = self.xmin
	ymin = self.ymin

	xscalef = self.xscalef
	yscalef = self.yscalef

	xorg = self.xorg
	yorg = self.yorg
	ytop = self.bounds[2]
        xtop = self.bounds[1]

	collist = self.plot.collist
	clen = len(collist)
        
	LINE = self.canv.create_line
        #if self.mode & (MODE_HIST | MODE_PDF):
        if self.mode & MODE_HIST:
            width = max(1, abs(int((self.get_bktsz(set)*xscalef) - 2)))
            if self.mode & MODE_RANGES:
                lshift = width/2 + 4
            else:
                lshift = 0
        else:
            width = self.plotlinewidth
            lshift = 0

	s = set
	col = s.col
	try:
	    tag = s.tg
	except AttributeError:
	    # only one set
	    tag = ''
	data = s.data
	i1, i2 = s.curr_indices[-1]
	#print 'i1=' + repr(i1) + ' i2=' + repr(i2)
	if i1 == None:
	    return
	lastx = None

	#print 'xorg=%d yorg=%d' % (self.xorg, self.yorg)

	# connect to previous point
	if (style & STYLE_LINES and i1 != 0):
	    xv = data[i1-1][0] - xmin
	    yv = data[i1-1][1] - ymin
	    lastx = int(xv*xscalef)+xorg
	    lasty = yorg - int(yv*yscalef)

        # drawing error bars?
        eb = 0
        if (style & STYLE_EBARS):
            if 'SD' in s.fields or 'SE' in s.fields:
                if style == STYLE_EBARS_SD:
                    ebdi = s.fields.index('SD')
                elif style == STYLE_EBARS_SE:
                    ebdi = s.fields.index('SE')
                if len(data[0]) > ebdi:
                    eb = 1
            else:
                style = STYLE_POINTS

	for p in data[i1:i2+1]:
	    xv = p[0] - xmin
	    yv = p[1] - ymin
	    x = int(xv*xscalef)+xorg
	    y = yorg - int(yv*yscalef)
	    if col == None:
		contag = p[2]
		thiscol = collist[int(contag%clen)]
	    else:
		thiscol = col

	    if (style & STYLE_LINES):
		if lastx != None:
		    try:
			x0, y0, x1, y1 = endpoints(lastx, lasty, x, y, bounds)
			LINE(x0, y0, x1, y1, fill=thiscol, width=width, 
			 tags=(tag, 'li'))
                        LINE(x,y,x,y, fill=thiscol, tags=(tag, 'li', 'ctr'))
		    except Nodraw:
			pass
		lastx = x
		lasty = y

	    if (style & STYLE_POINTS) and inside(x, y, bounds):
		LINE(x-2,y,x+2,y,fill=thiscol, width=width, tags=(tag, 'pnt'))
		pp = LINE(x,y-2,x,y+2,fill=thiscol, width=width, tags=(tag, 'pnt'))
 		LINE(x,y,x,y, fill=thiscol, tags=(tag, 'pnt', 'ctr'))

	    if style == STYLE_BARS:
                x -= lshift
                if x - (width/2) > xtop:
                    break
		y = MIN(MAX(y, ytop), yorg)
                thiswidth = width
                while x-(thiswidth/2) < xorg:
                    x += 1
                    thiswidth -= 2
                while x+(thiswidth/2) > xtop:
                    x -= 1
                    thiswidth -= 2  
		pp = LINE(x, yorg, x, y, fill=thiscol, width=thiswidth,
			 tags=('bar', tag))
 		LINE(x,y,x,y, fill=thiscol, tags=(tag, 'bar', 'ctr'))

            if (style & STYLE_EBARS) and eb:
                ebl = int(p[ebdi]*yscalef)
                ytop = y+ebl
                ybott = y-ebl
                LINE(x,ytop,x,ybott,fill=thiscol, width=width, tags=(tag, 'eb'))
                LINE(x-2,ytop,x+2,ytop,fill=thiscol, width=width, tags=(tag, 'eb'))
                LINE(x-2,y,x+2,y,fill=thiscol, width=width, tags=(tag, 'eb'))
                LINE(x-2,ybott,x+2,ybott,fill=thiscol, width=width, tags=(tag, 'eb'))
 		LINE(x,y,x,y, fill=thiscol, tags=(tag, 'eb', 'ctr'))
                


	# connect to following point
	if (style & STYLE_LINES and i2 != s.len-1):
	    xv = data[i2+1][0] - xmin
	    yv = data[i2+1][1] - ymin
	    x = int(xv*xscalef)+xorg
	    y = yorg - int(yv*yscalef)
	    contag = data[i2+1][2]
	    thiscol = collist[int(contag%clen)]
	    try:
		x0, y0, x1, y1 = endpoints(lastx, lasty, x, y, bounds)
		LINE(x0, y0, x1, y1, fill=thiscol, width=width, 
		 tags=(tag, 'li'))
	    except Nodraw:
		pass

##############################################################################

    def undraw_set(self, set):

       # print 'undraw_set', set.indx, set.tg

        t = set.tg
        c = self.canv

	dels = c.find_withtag(t)
	for d in list(dels):
	    c.delete(d)
        
        

############################################################################## 
#############################################################################

class np_Plot:

    def __init__(self, sets, path, standalone='yes', title = '',
		 xlab='', ylab='', raw_data=0, showlist=None, top=None,
                 style=STYLE_POINTS, mode=MODE_TS, width=B_WI, height=B_HT,
                 delay_activation='no', decorations=[], zero_origin=1):

       # print 'plot'
	self.path = path

        self.standalone = standalone

        self.wi = width
        self.ht = height

        if standalone == 'yes':
            self.root = Tk()
        else:
            self.root = Toplevel()
            
        self.root.geometry('%dx%d' % (width, height))
        self.root.minsize(width, height)
        self.root.maxsize(width, height)
        
        #self.root.grab_set()
        
	tstr = 'np_plot ' + path + ' - ' + title
	self.root.winfo_toplevel().title(tstr) 

        # remember stuff between loading functions
        self.fnspec = None

	self.raw_data = raw_data
	self.sets = sets
        self.dtype = sets[0].type
        self.showlist = showlist

	self.make_collist()

        posstop = 0
        # activation flags for style errorbars
        self.ebse = DISABLED
        self.ebsd = DISABLED
        
	for s in sets:
	    s.initialise()
            s.indx = sets.index(s)
	    if s.tag != None:
		s.col = self.collist[s.tag%len(self.collist)]
	    else:
		s.col = None
            if showlist and not showlist.count(s.indx):
                s.hidden = [1]
            else:
                s.hidden = [0]
                posstop = s.indx
            if 'SE' in s.fields:
                self.ebse = NORMAL
            if 'SD' in s.fields:
                self.ebsd = NORMAL

        if top == None:
            top = posstop

        # remember stuff between loading sets
        self.add_set_def_fields = self.sets[0].fields
        self.add_set_fields = []
        self.add_set_dir = os.path.dirname(path)
        if not self.add_set_dir:
            self.add_set_dir = os.getcwd()

	self.topset = IntVar()
	self.topset.set(top)
	self.is_top = [top]
        self.newtop = top
        self.delset = IntVar()
        self.delset.set(-1)

	self.title = title
        self.sspec = ''
	self.xlab = xlab
	self.ylab = ylab

	self.style = style
	self.mode = mode

        self.raisefn = self.raiseit
        self.hidefn = self.hideit
        self.scolfn = self.scol

        #
        # Force zero y origin
        #
        self.zero_origin = zero_origin 

        #
        # Any decorations
        #
        self.decs = decorations


	#
	# Set up toolbar
	#
	if standalone == 'yes':
	    self.quitfun = self.finish
	else:
	    self.quitfun = self._destroy
	#
	self.toolbar()

        if mode == MODE_HIST:
            self.toolbar.entryconfig('TS', state=DISABLED)
            self.style = STYLE_BARS

        if mode == MODE_PDF:
            self.toolbar.entryconfig('TS', state=DISABLED)
            self.toolbar.entryconfig('HIST', state=DISABLED)
            self.style = STYLE_BARS

        if mode == MODE_CDF:
            self.toolbar.entryconfig('TS', state=DISABLED)
            self.toolbar.entryconfig('HIST', state=DISABLED)
            self.toolbar.entryconfig('PDF', state=DISABLED)

	#
	# Set up set manipulation window
	#
        self.sw_show = 0
        self.swindow()
        # but don't show if only 1
        if len(sets) == 1:
            #self.toolbar.show_swb.configure(state=DISABLED)
            self.toolbar.entryconfig('sets', state=DISABLED)
	
	# Set up drawing area
	self.canvasses = []

        
        if delay_activation != 'yes':
            # draw
            self.activate()

##############################################################################

    def activate(self):
        
	#
	# Draw top level data and activate event loop
	#
	c = Plot_canv(self, self.sets, style=self.style, mode=self.mode, zero_origin=self.zero_origin)
	self.canvasses.append(c)
	self.canv_curr = 0
	c.canv.pack(side=LEFT, fill=BOTH, expand = 1)
        

        if self.standalone == 'yes':
            self.root.mainloop()
        else:
            self.root.wait_window(self.root)

##############################################################################

    def toolbar(self):


	self.frame = Frame(self.root)
	self.frame.config(bg='black')
	self.frame.pack(side=LEFT, fill=BOTH, expand=1)

	# create a toolbar


	toolbar = self.toolbar = Menu(self.root)
	toolbar.config(background='grey')

	toolbar.add_command(label="Quit", command=self.quitfun,
                            background='grey', foreground='red')
        toolbar.add_separator()

 	self.stylev_curr = IntVar()
 	self.stylev_curr.set(self.style)
	stym = self.stylemenu = Menu(self.toolbar)
        stym.config(background='grey')
	stym.add_radiobutton(label='Points', 
				  command=self.set_style_POINTS, 
				  variable=self.stylev_curr,
				  value=STYLE_POINTS, indicatoron=1, 
				  selectcolor='blue')
	stym.add_radiobutton(label='Lines', 
				  command=self.set_style_LINES, 
				  variable=self.stylev_curr,
				  value=STYLE_LINES, indicatoron=1, 
				  selectcolor='blue')
	stym.add_radiobutton(label='LinesPoints', 
				  command=self.set_style_LINESPOINTS, 
				  variable=self.stylev_curr,
				  value=STYLE_POINTS | STYLE_LINES, indicatoron=1, 
				  selectcolor='blue')
	stym.add_radiobutton(label='Bars', 
				  command=self.set_style_BARS, 
				  variable=self.stylev_curr,
				  value=STYLE_BARS, indicatoron=1, 
				     selectcolor='blue')
        
	stym.add_radiobutton(label='Errorbars-s.d.', 
				  command=self.set_style_EBARS, 
				  variable=self.stylev_curr,
				  value=STYLE_EBARS_SD, indicatoron=1, 
				     selectcolor='blue', state=self.ebsd)
	stym.add_radiobutton(label='Errorbars-s.e.', 
				  command=self.set_style_EBARS, 
				  variable=self.stylev_curr,
				  value=STYLE_EBARS_SE, indicatoron=1, 
				     selectcolor='blue', state=self.ebse)
        toolbar.add_cascade(label='Style', menu=stym)

	toolbar.add_command(label="sets", command=self.show_sw,
                            background='grey')


	self.v = IntVar()
	self.v.set(self.mode)
	toolbar.add_radiobutton(label="TS", background='grey',
                                variable=self.v, value=MODE_TS, 
                                indicatoron=0, 
                                command=self.set_mode_TS)
	toolbar.add_radiobutton(label="HIST", background='grey',
                                variable=self.v, value=MODE_HIST, 
                                indicatoron=0, 
                                command=self.set_mode_HIST)
	toolbar.add_radiobutton(label="PDF", background='grey',
                                variable=self.v, value=MODE_PDF,
                                indicatoron=0, 
                                command=self.set_mode_PDF)
	toolbar.add_radiobutton(label="CDF", background='grey',
                                variable=self.v, value=MODE_CDF,
                                indicatoron=0, 
                                command=self.set_mode_CDF)
		

        self.smoothtype = StringVar()
	smoom = self.smoothmenu = Menu(self.toolbar, background='grey')
        
	meansmoom = Menu(smoom, background='grey')
	meansmoom.add_radiobutton(label='5s', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='mean:5', indicatoron=0,
                                  background='grey')
	meansmoom.add_radiobutton(label='10s', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='mean:10', indicatoron=0,
                                  background='grey')
	meansmoom.add_radiobutton(label='60s', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='mean:60', indicatoron=0,
                                  background='grey')
        smoom.add_cascade(label='Mean over...', menu=meansmoom)
        
	smasmoom = Menu(smoom, background='grey')
	smasmoom.add_radiobutton(label='5s', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='sma:5', indicatoron=0,
                                  background='grey')
	smasmoom.add_radiobutton(label='10s', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='sma:10', indicatoron=0,
                                  background='grey')
	smasmoom.add_radiobutton(label='60s', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='sma:60', indicatoron=0,
                                  background='grey')
        smoom.add_cascade(label='Sma over...', menu=smasmoom)
        
	emasmoom = Menu(smoom, background='grey')
	emasmoom.add_radiobutton(label='0.1', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='ema:0.1', indicatoron=0,
                                  background='grey')
	emasmoom.add_radiobutton(label='0.2', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='ema:0.2', indicatoron=0,
                                  background='grey')
	emasmoom.add_radiobutton(label='0.5', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='ema:0.5', indicatoron=0,
                                  background='grey')
        smoom.add_cascade(label='Ema alpha...', menu=emasmoom)

        smoom.add_radiobutton(label='Han', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='han', indicatoron=0,
                                  background='grey')

    ##     smoom.add_radiobutton(label='Other', 
## 				  command=self.mode_smooth, 
## 				  variable=self.smoothtype,
## 				  value='', indicatoron=0,
##                                   background='grey')

        self.osmoom = osmoom =  Menu(smoom, background='grey')
        osmoom.add_radiobutton(label='Other', 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value='', indicatoron=0,
                                  background='grey')
        smoom.add_cascade(label='Other', menu=osmoom)
        
        toolbar.add_cascade(label='Smooth', menu=smoom)


	toolbar.add_command(label="Print", command=self.hardcopy,
                            background='grey')

        if len(self.sets) == 1:
            toolbar.add_command(label="Data", command=self.showsetdata,
                            background='grey')

        addm = self.addm = Menu(self.toolbar, background='grey')
        addm.add_command(label="Add data set", command=self.addset,
                            background='grey')
        addm.add_command(label="Add function", command=self.addfn,
                            background='grey')
        addm.add_command(label="Set fields", command=self.add_setfields,
                            background='grey')
        toolbar.add_cascade(label='Add', menu=addm)
        

        self.root.config(menu=toolbar)

##############################################################################

    def swindow(self):

        sw = self.sw = Toplevel()
        sw.transient(self.root)
        sw.winfo_toplevel().title('np_plot Sets')

        maxlen = 0
        nlines = len(self.sets)
        for s in self.sets:
            maxlen = max([maxlen, len(s.path)])

        ht = nlines*20 +40
        wi = maxlen*60

        sw.config(height=ht, width=wi)

        toolbar = sw.toolbar = Menu(sw)
	toolbar.config(background='grey')

	toolbar.add_command(label="Hide", command=self.hide_sw,
                            background='grey', foreground='black')  
	
	# just a separator
        toolbar.add_separator(background='black')

        sw.defer_redraw=IntVar()
        sw.defer_redraw.set(0)

	toolbar.add_checkbutton(label="Defer Draw", command=self.defer,
                            background='grey', foreground='black',
                                variable=sw.defer_redraw, indicatoron=0, 
                               selectcolor='blue', hidemargin=0)

	toolbar.add_command(label="ReDraw", command=self.redraw,
                            background='grey', foreground='black', state=DISABLED)
        sw.config(menu=toolbar)

        # just to make a vertical gap
	sep = Frame(sw)
	sep.configure(bg='grey60', height=10, relief=RAISED)
	sep.pack(side=TOP, fill=X)
        
	sw.allframe = Frame(sw)
	sw.allframe.configure(bg='black', height=50, relief=RAISED)
	sw.allframe.pack(side=TOP, fill=X)

        self.hideall = IntVar()
        self.hideall.set(0)
        sw.allframe.allb = Checkbutton(sw.allframe, text=' Hide ', command=self.all_hide,fg='black', bg='grey', indicatoron=0, variable=self.hideall)
        sw.allframe.allb.pack(side=LEFT)

        self.hidenone = IntVar()
        self.hidenone.set(0)
        sw.allframe.noneb = Checkbutton(sw.allframe, text='Show',
                                 command=self.all_show,fg='black', bg='grey',
                                 indicatoron=0, variable=self.hidenone)
        sw.allframe.noneb.pack(side=LEFT)

        sw.allframe.lab =  Checkbutton(sw.allframe, text='All Sets',
                                 command=self.all_show,
                                 disabledforeground='red', bg='black',
                                 indicatoron=0, state=DISABLED)
        sw.allframe.lab.pack(side=LEFT, fill=X, expand=1)

        # just to make a vertical gap
	sep = Frame(sw)
	sep.configure(bg='grey60', height=10, relief=RAISED)
	sep.pack(side=TOP, fill=X)

        maxchar = 0
        for s in self.sets:
            maxchar = max([maxchar, len(s.path)])
        #print maxchar

        sw.setframe = Frame(sw)
        sw.setframe.configure(bg='black', relief=RAISED)
        sw.setframe.pack(side=TOP, fill=X)

        self.showset = IntVar()
        self.showset.set(0)
        
        i = 0
        tag0 = 'a'
        tag = 'a'
        for s in self.sets:
            #print tag
            s.tg = tag0 + tag
            hide = s.hidden[-1]
            if hide:
                bstate = DISABLED
                fg = 'grey80'
                bg = 'grey'
                txt = 'Show'
            else:
                bstate = NORMAL
                fg = s.col
                bg = 'black'
                txt = 'Hide'
            s.ops = Frame(sw.setframe)
            s.ops.configure(bg='black', width=wi, height=25)
            s.ops.pack(side=TOP, fill=X)
            
            s.ops.top = Radiobutton(s.ops, text=' Top ', 
                               command=self.raisefn, 
                               variable=self.topset,
                               value=i, indicatoron=0, selectcolor='blue')
            s.ops.top.configure(bg='grey', fg='black', state=bstate)
            s.ops.top.pack(side=LEFT)
            
            s.ops.hide = Checkbutton(s.ops, text=txt, variable=s.hide, 
                               command=self.hidefn, indicatoron=0, 
                               onvalue=1, offvalue=0, selectcolor='grey')
            s.ops.hide.configure(bg='grey', fg='black')
            s.hide.set(hide)
            s.ops.hide.pack(side=LEFT)
            ####
            s.ops.data = Radiobutton(s.ops, text='data', variable=self.showset,
                               value=i, command=self.showsetdata,
                                     indicatoron=0)
            s.ops.data.configure(bg='grey', fg='black')
            s.ops.data.pack(side=LEFT)
            ####
            s.ops.delete = Radiobutton(s.ops, text='Delete',
                                       variable=self.delset, value=i,
                                       command=self.deleteset,
                                       indicatoron=0)
            s.ops.delete.configure(bg='grey', fg='black')
            s.ops.delete.pack(side=LEFT)
            ####
            s.ops.col = Checkbutton(s.ops, text='%s (%d)' % (s.path, s.len),
                                    background=bg,
                                    foreground=fg, variable=s.docol,
                                    command=self.scolfn, indicatoron=0,
                                    onvalue=1, offvalue=0, selectcolor='blue',
                                    disabledforeground='grey40',
                                    width=maxchar+10, state=bstate)
            s.ops.col.pack(side=LEFT)


            i += 1
            #tag += 'a'
            nt = ord(tag)+1
            if nt > ord('z'):
                nt = ord('a')
                tag0 = chr(ord(tag0)+1)
            tag = chr(nt)

        # just to make a vertical gap
	sw.sep = Frame(sw)
	sw.sep.configure(bg='grey60', height=10, relief=RAISED)
	sw.sep.pack(side=TOP, fill=X)

        if not self.sw_show:
            sw.withdraw() #start hidden

##############################################################################

    def hide_sw(self):

        self.sw.withdraw()
        self.sw_show = 0

##############################################################################

    def show_sw(self):

        self.sw.deiconify()
        self.sw_show = 1

##############################################################################

    def all_hide(self):

        self.hideall.set(0)
        
        for s in self.sets:
            s.hide.set(1)

        if self.sw.defer_redraw.get():
            self.hide_deferred()
        else:
            self.hideit()

##############################################################################

    def all_show(self):

        self.hidenone.set(0)
        
        for s in self.sets:
            s.hide.set(0)

        if self.sw.defer_redraw.get():
            self.hide_deferred()
        else:
            self.hideit()

##############################################################################

    def defer(self):

        val = self.sw.defer_redraw.get()
        #print val
        
        if val == 1:
            self.sw.toolbar.entryconfig('Defer Draw', foreground='red', background='grey65')
            for s in self.sets:
                s.ops.top.configure(command=self.raise_deferred)
                s.ops.hide.configure(command=self.hide_deferred)
                s.ops.col.configure(command=self.scol_deferred)
        else:
            self.sw.toolbar.entryconfig('Defer Draw', foreground='black', background='grey')
            self.sw.toolbar.entryconfig('ReDraw', state=DISABLED)
            for s in self.sets:
                s.ops.top.configure(command=self.raiseit)
                s.ops.hide.configure(command=self.hideit)
                s.ops.col.configure(command=self.scol)
            self.redraw()
            
##############################################################################

    def redraw(self):

	c = self.canvasses[self.canv_curr]
        topset = None

        for s in self.sets:
            hide = s.hide.get()
            #print hide
            if s.indx == self.newtop:
                topset = s
                #print 'redraw %d is topset' % (s.indx)
                continue
            if hide and not s.hidden[-1]:
                #print 'redraw hiding %d' % (s.indx)
                c.undraw_set(s)
                s.hidden[-1] = 1
                c.order.remove(s.indx)
            elif not hide and s.hidden[-1]:
                #print 'redraw showing %d' % (s.indx)
                s.hidden[-1] = 0
                s.col = s.newcol
                c.draw_set(s)
                c.order.append(s.indx)
            elif s.col != s.newcol:
                #print 'redraw colouring %d' % (s.indx)
                s.col = s.newcol
                c.undraw_set(s)
                c.draw_set(s)
                c.order.remove(s.indx)
                c.order.append(s.indx)
                
        topset.col = topset.newcol
        self.topset.set(self.newtop)

        hide = topset.hide.get()
        if hide and not topset.hidden[-1]:
            c.undraw_set(topset)
            topset.hidden[-1] = 1
            c.order.remove(topset.indx)
        elif not hide and topset.hidden[-1]:
            topset.hidden[-1] = 0
            c.draw_set(topset)
            c.order.append(topset.indx)

	self.redraw_labels()
        c.redraw_decs()

        self.sw.toolbar.entryconfig('ReDraw', state=DISABLED)

##############################################################################

    def addset(self):

        dr = DataReader([self.add_set_dir], fields=self.add_set_fields)
        try:
            sets, path, title, xlab, ylab, decs, mode, decs = dr.get_data()
        except DataError, s:
            print 'Data Error %s' % (s)
            return

        self.add_set_dir = os.path.dirname(path)

        s = sets[0]
       # print 'addset', s.fields
        s.initialise()
        if s.tag != None:
            if self.sets:
                s.tag = self.sets[-1].tag + 1
            else:
                s.tag = 1
            s.col = self.collist[s.tag%len(self.collist)]
        else:
            s.col = None
        self.sets.append(s)
       # print 'sets', self.sets
        s.indx = self.sets.index(s)
        s.hidden = [0]
        # data for errorbars in new set?
        if 'SE' in s.fields:
            self.stylemenu.entryconfig('Errorbars-s.e.', state=NORMAL)
        if 'SD' in s.fields:
            self.stylemenu.entryconfig('Errorbars-s.d.', state=NORMAL)

        self.clear_canvasses()
        self.topset.set(s.indx)
        self.is_top = [s.indx]
        for s in self.sets:
            s.reset()

        self.sw.withdraw()
        del self.sw
        self.swindow()
        if len(self.sets) > 1:
            self.toolbar.entryconfig('sets', state=NORMAL)
        else:
            self.toolbar.entryconfig('sets', state=DISABLED)

	c = Plot_canv(self, self.sets, mode=MODE_TS, style=STYLE_POINTS)
	c.canv.pack(side=LEFT, fill=BOTH, expand = 1)
	self.canvasses.append(c)
	self.canv_curr = 0
        

##############################################################################

    def addfn(self):

        newdata = []

        # call up an AddFun instance - will exit with new data populated
        af = AddFun(self, newdata)

        if newdata:
            stuff = newdata[0]
            if 1:
                sets = stuff[0]
                for s in sets:
                    s.initialise()
                    if self.sets:
                        s.tag = self.sets[-1].tag + 1
                    else:
                        s.tag = 1
                    s.col = self.collist[s.tag%len(self.collist)]
                    self.sets.append(s)
                    s.indx = self.sets.index(s)
                    s.hidden = [0]

                self.clear_canvasses()
                self.topset.set(s.indx)
                self.is_top = [s.indx]
                for s in self.sets:
                    s.reset()

                self.sw.withdraw()
                del self.sw
                self.swindow()
                if len(self.sets) > 1:
                    self.toolbar.entryconfig('sets', state=NORMAL)
                else:
                    self.toolbar.entryconfig('sets', state=DISABLED)

                c = Plot_canv(self, self.sets, mode=MODE_TS, style=STYLE_POINTS)
                c.canv.pack(side=LEFT, fill=BOTH, expand = 1)
                self.canvasses.append(c)
                self.canv_curr = 0

                self.fnspec = stuff[1]

##############################################################################

    def add_setfields(self):

        def_entry = field_l2str(self.add_set_def_fields)

        fieldstr = askstring('Set fields?', 'Enter field spec for new data sets\n- format \'f1:f2: ...\'\n - poss values \'X\', \'Y\', \'T\', \'SD\', \'SE\' ', parent=self.root, initialvalue=def_entry)

        if fieldstr != None:
            fields = field_str2l(fieldstr)
        else:
            fields = []

        if fields:
            self.add_set_def_fields = fields
            self.add_set_fields = fields
        else:
            self.add_set_fields = []

##############################################################################

    def showsetdata(self):
        
        from np_widgets import PListB, XYSCROLL
        
        self.droot = root = Toplevel()
        root.geometry('500x500')
        root.minsize(200, 200)
        
        tb = Menu(root)
	tb.configure(bg='grey')
        tb.add_command(label='Quit', command=self.dquit, background='grey',
                       foreground='red')
        self.data_how = IntVar()
        self.data_how.set(0)
        tb.add_radiobutton(label='Coords', background='grey',
                           command=self.setdata, variable=self.data_how,
                           value=0, indicatoron=0)
        tb.add_radiobutton(label='Full', background='grey',
                           command=self.setdata, variable=self.data_how,
                           value=1, indicatoron=0)

        eb = Menu(tb)
	eb.configure(bg='grey')
        eb.add_command(label='Edit point', command=self.pedit,
                       background='grey', foreground='black')
        eb.add_command(label='Delete point', command=self.pdelete,
                       background='grey', foreground='black')
        eb.add_command(label='Restore all', command=self.prestore,
                       background='grey', foreground='black')
        tb.add_cascade(menu=eb, label='Edit')
        
        root.config(menu=tb)
        
        self.databox = lb = PListB(root, XYSCROLL) 
 	lb.config(bg='white',  fg='black', selectborderwidth=0, 
 			       selectbackground='grey', 
 			       selectforeground='black', 
 			       font = ('helvetica', 10), selectmode=EXTENDED)
 	lb.pack(side=LEFT, fill=BOTH, expand=1)

        self.setdata()

        
##############################################################################

    def pedit(self):

        pts = self.databox.curselection()
        try:
            pts = map(int, pts)
        except ValueError:
            pass
        if not pts:
            return

        pts.sort()
        set = self.sets[self.showset.get()]
        data = set.data
        canv = self.canvasses[self.canv_curr]
        stuff = []
        for p in pts:
            stuff.append((p, self.databox.get(p)))

        newvals = []
        Dedit(self.droot, stuff, newvals)

        #for i, e in newvals:
        for indx in range(len(newvals)):
            i, e = newvals[indx]
            ent = stuff[indx][1]
            self.databox.delete(i)
            self.databox.insert(i, e)
            cds = e.split()
            newd = []
            for v in cds:
                newd.append(float(v))
            d = data[i]
            if len(d) != len(newd):
                print 'data length confusion'
            set.edits.append((EDIT, i, d, ent))
            del data[i:i+1]
            data.insert(i, newd)
            
        canv.undraw_set(set)
        canv.draw_set(set)
            

        
##############################################################################

    def prestore(self):
        
        set = self.sets[self.showset.get()]
        data = set.data
        canv = self.canvasses[self.canv_curr]
        rests = set.edits
        rests.reverse()
        for op, i, d, ent in rests:
            if op == DELETE:
                data.insert(i, d)
                #print ' inserting', ent
                self.databox.insert(i, ent)
            elif op == EDIT:
                data[i] = d
                self.databox.delete(i)
                self.databox.insert(i, ent)
            
        canv.undraw_set(set)
        canv.draw_set(set)

        
##############################################################################

    def pdelete(self):

        pts = self.databox.curselection()
        try:
            pts = map(int, pts)
        except ValueError:
            pass
        if not pts:
            return

        pts.sort()
        
        dd = 0
        set = self.sets[self.showset.get()]
        data = set.data
        canv = self.canvasses[self.canv_curr]
        for p in pts:
            i = p - dd
            ent = self.databox.get(i)
            #print 'deleting', data[i][0], data[i][1]
            set.edits.append((DELETE, i, data[i], ent))
            del data[i:i+1]
            self.databox.delete(i)
            dd += 1
            
        canv.undraw_set(set)
        canv.draw_set(set)
        
##############################################################################

    def setdata(self):

        

        set = self.sets[self.showset.get()]
        data = set.data
        lb = self.databox
        lb.delete(0, END)
        full = self.data_how.get()
        
        for p in data:
            e = []
            s = ''
            ind = 0
            if full:
                for f in p:
                    s += repr(f)
                    s += ' '

                i = 0
                while len(s):
                    if i == 0:
                        ss = s[:100]
                    else:
                        ss = '  ' + s[:100]
                    s = s[100:]
                    e.append(ss)
                    i += 1
                for ee in e:
                    lb.insert(END, ee)
            else:
                s = repr(p[0]) + ' ' + repr(p[1])
                lb.insert(END, s)

##############################################################################

    def deleteset(self):

        indx = self.delset.get()
        s = self.sets[indx]
        top = self.topset.get()
        self.sets.remove(s)

        if top == indx:
            top = 0
        self.topset.set(top)
        self.is_top = [top]

        s.ops.pack_forget()

        self.clear_canvasses()
        i = 0
        for s in self.sets:
            s.reset()
            s.indx = i
            s.ops.top.configure(value=i)
            s.ops.data.configure(value=i)
            s.ops.delete.configure(value=i)
            i += 1
        
        if len(self.sets) > 1:
            self.toolbar.entryconfig('sets', state=NORMAL)
        else:
            self.toolbar.entryconfig('sets', state=DISABLED)

        if self.sets:
            c = Plot_canv(self, self.sets, mode=MODE_TS, style=STYLE_POINTS)
            c.canv.pack(side=LEFT, fill=BOTH, expand = 1)
            self.canvasses.append(c)
            self.canv_curr = 0

        

##############################################################################

    def dquit(self):

        self.droot.withdraw()
        del self.droot
        

##############################################################################

        


    def mouse_3_down(self, event):

	if self.canv_curr == 0:
	    return

	self.canvasses[self.canv_curr].canv.pack_forget()
	del(self.canvasses[self.canv_curr])
	#print 'deleted'
	self.canv_curr = self.canv_curr - 1
	self.style = self.canvasses[self.canv_curr].style
	self.stylev_curr.set(self.style)
	self.canvasses[self.canv_curr].canv.pack(side=LEFT, fill=BOTH, expand = 1)

	for s in self.sets:
	    s.curr_indices.pop(-1)
	    s.hidden.pop(-1)
	    i1, i2 =  s.curr_indices[-1]
	    if i1 != None:
		try:
		    hide = s.hidden[-1]
		    s.hide.set(hide)
                    if not hide:
                        s.ops.top.configure(state=NORMAL)
                        s.ops.hide.configure(state=NORMAL)
                        s.ops.col.configure(state=NORMAL,
                                            fg=s.col, bg='black')
                    else:
                        s.ops.top.configure(state=DISABLED)
                        s.ops.hide.configure(state=NORMAL)
                        s.ops.col.configure(state=DISABLED,
                                            fg='grey80', bg='grey')
		except AttributeError:
		    # only one set
		    pass

	self.is_top.pop(-1)
	if len(self.sets) > 1:
            #print 'resetting topset to %d' % (self.is_top[-1])
	    self.topset.set(self.is_top[-1])

	
##############################################################################


    def clear_canvasses(self):

	for c in self.canvasses:



            Widget.unbind(c.canv, "<1>")
            Widget.unbind(c.canv, "<B1-Motion>")
            Widget.unbind_class(c.canv, Canvas, "<B1-Motion>")
            Widget.unbind_all(c.canv, "<B1-Motion>")
            Widget.unbind(c.canv, "<ButtonRelease-1>")
            Widget.unbind(c.canv, "<Double-Button-1>")

            Widget.unbind(c.canv, "<2>")
            Widget.unbind(c.canv, "<B2-Motion>")
            Widget.unbind(c.canv, "<ButtonRelease-2>")

            Widget.unbind(c.canv, "<3>")
            Widget.unbind(c.canv, "<B3-Motion>")
            Widget.unbind(c.canv, "<ButtonRelease-3>")

            Widget.unbind(c.canv, "<Control-Button-3>")
            Widget.unbind(c.canv, "<Control-B3-Motion>")
            Widget.unbind(c.canv, "<Control-ButtonRelease-3>")



            
	    c.canv.delete(ALL)
	    c.canv.pack_forget()
	    del(c)

	self.canvasses = []
	self.canv_curr = None



##############################################################################

    def set_style_POINTS(self):
	self.stylev_curr.set(STYLE_POINTS)
	self.change_style()

##############################################################################

    def set_style_LINES(self):
	self.stylev_curr.set(STYLE_LINES)
	self.change_style()

##############################################################################

    def set_style_LINESPOINTS(self):
	self.stylev_curr.set(STYLE_POINTS | STYLE_LINES)
	self.change_style()

##############################################################################

    def set_style_BARS(self):
	self.stylev_curr.set(STYLE_BARS)
	self.change_style()

##############################################################################

    def set_style_EBARS(self):
       # print self.stylev_curr.get()
	#self.stylev_curr.set(STYLE_EBARS)
        #print 'in set_style_EBARS'
	self.change_style()

##############################################################################

    def change_style(self):

	   style = self.stylev_curr.get()
	  # print 'style %d->%d' % (self.style, style)
	   if style == self.style:
	       return
           oldstyle = self.style
	   self.style = style
	   #print 'style %d' % (style)

	   c = self.canvasses[self.canv_curr]
	   c.style = style

	   if not (style & STYLE_LINES):
	       dels = c.canv.find_withtag('li')
	       for d in list(dels):
		   c.canv.delete(d)
	   if not (style & STYLE_POINTS):
	       dels = c.canv.find_withtag('pnt')
	       for d in list(dels):
		   c.canv.delete(d)
	   if not (style & STYLE_BARS):
	       dels = c.canv.find_withtag('bar')
	       for d in list(dels):
		   c.canv.delete(d)
	   if (not (style & STYLE_EBARS)) or ((style & STYLE_EBARS) and style != oldstyle):
	       dels = c.canv.find_withtag('eb')
	       for d in list(dels):
		   c.canv.delete(d)

           if (not ((oldstyle & style) & STYLE_EBARS)) or ((style & STYLE_EBARS) and style != oldstyle):
	       dels = c.canv.find_withtag('yt')
	       for d in list(dels):
		   c.canv.delete(d)
               # re-scale to allow for bars
               c.scale()
               c.draw_ytics(self.ylab)

	   c.draw()

	   

##############################################################################

    def redraw_labels(self):

	c = self.canvasses[self.canv_curr]
	dels = c.canv.find_withtag('la')
	for d in list(dels):
	    c.canv.delete(d)
	c.draw_labels()

	   

##############################################################################

    def raiseit(self, force=0):
            

	#print 'raise_to_top set %d' % (self.topset.get())

	i = self.topset.get()
	if (not force) and (i == self.is_top[-1]):
	    return

	c = self.canvasses[self.canv_curr]
	
	set = c.sets[i]
	i1, i2 = set.curr_indices[-1]
	if i1 == None or set.hidden[-1]:
	    # out of range or hidden - reset button to former value
	    self.topset.set(self.is_top[-1])
	    return
        c.sets[self.is_top[-1]].ops.top.configure(state=NORMAL)
        #print 'raising %d' % (i)
        c.order.remove(i)
        c.order.append(i)
        c.undraw_set(set)
	self.is_top[-1] = i
	self.redraw_labels()
	c.draw_set(set)
        self.topset.set(i)
        #print 'raise set top %d' % (self.is_top[-1])

        c.redraw_decs
	   

##############################################################################

    def raise_deferred(self):

        # reset button state but defer re-drawing
        # newtop is current candidate
        self.sets[self.newtop].ops.top.configure(state=NORMAL)
        # get the new one
        self.newtop = self.topset.get()
        self.sets[self.newtop].ops.top.configure(state=DISABLED)

        # enable redraw button
        #self.sw.redb.configure(state=NORMAL)
        self.sw.toolbar.entryconfig('ReDraw', state=NORMAL)
        return

##############################################################################

    def hideit(self):

	c = self.canvasses[self.canv_curr]
        redraw_decs = 0

	i = 0
	for s in self.sets:
	   # print s.indx, 'hide=%d' % (s.hide.get()), 'currently', s.hidden[-1]
	    hide = s.hide.get()
	    if hide and not s.hidden[-1]:
		s.hidden[-1] = 1
                c.order.remove(i)
                c.undraw_set(s)
		if i == self.topset.get():
		   # print 'hiding top %d' % (i)
                    try:
                        newtop = c.order[-1]
                       # print 'new top %d' % (newtop)
                        self.topset.set(newtop)
                        self.is_top[-1] = newtop
                        self.sets[newtop].ops.top.configure(state=DISABLED)
                    except IndexError:
                        # all hidden - stack empty
                        print 'hide indx error'
                        pass
		#break
                s.ops.top.configure(state=DISABLED)
                s.ops.col.configure(state=DISABLED, background='grey')
                s.ops.hide.configure(text='Show')
	    elif not hide and s.hidden[-1]:
                if len(c.order):
                    self.sets[self.topset.get()].ops.top.configure(state=NORMAL)
		s.hidden[-1] = 0
		c.draw_set(s)
                c.order.append(i)
		self.topset.set(i)
		self.is_top[-1] = i
		#break
                s.ops.top.configure(state=DISABLED)
                s.ops.col.configure(state=NORMAL, foreground=s.col,
                                    background='black')
                s.ops.hide.configure(text='Hide')
                redraw_decs = 1
	    i += 1

	self.redraw_labels()

        if redraw_decs:
            c.redraw_decs()

##############################################################################

    def hide_deferred(self):

        #print 'hide-deferred'

        # adjust buttons defer redraw
        
	c = self.canvasses[self.canv_curr]
        
        for s in self.sets:
            hide = s.hide.get()
            if hide:
                # hiding it
                s.ops.top.configure(state=DISABLED)
                s.ops.col.configure(state=DISABLED, background='grey')
                s.ops.hide.configure(text='Show')
                if s.indx == self.newtop: # hiding desired top
                    newtop = None
                    order = c.order[:]
                    order.reverse()
                    for indx in order: # get the easiest
                        if not self.sets[indx].hide.get():
                            newtop = indx
                            break
                    if newtop != None:
                        self.newtop = newtop
                        self.topset.set(newtop)

            else:
                # showing it
                s.ops.top.configure(state=NORMAL)
                s.ops.col.configure(state=NORMAL, foreground=s.col,
                                background='black')
                s.ops.hide.configure(text='Hide')

        # enable redraw
        self.sw.toolbar.entryconfig('ReDraw', state=NORMAL)
        return

	   

##############################################################################

    def scol(self):

        self.root.update_idletasks()
        
	for s in self.sets:
            #print 'docol %d' % (s.docol.get())
	    if s.docol.get():
		s.docol.set(0)
		rgb, col = tkColorChooser.askcolor(color=s.col, 
						    master=self.frame)
                if col:
                    s.col = col
                else:
                    return
                self.topset.set(s.indx)
                self.raiseit(force=1)
                s.ops.col.configure(foreground=s.col)
		#break

	   

##############################################################################

    def scol_deferred(self):

        #print 'scol_deferred'
        self.root.update_idletasks()
        
	for s in self.sets:
            #print 'docol deferred %d' % (s.docol.get())
	    if s.docol.get():
		s.docol.set(0)
		rgb, col = tkColorChooser.askcolor(color=s.col, 
						    master=self.frame)
                #print 'set %d col %s->%s' % (s.indx, repr(s.col), repr(s.newcol))
                if col:
                    s.newcol = col
                else:
                    return
		#s.docol.set(0)
                s.ops.col.configure(fg=s.newcol)

        # enable redraw
        self.sw.toolbar.entryconfig('ReDraw', state=NORMAL)

        return

##############################################################################

    def add_Decoration(self, decs):

        for dec in decs:
            self.decs.append(dec)

##############################################################################

    def finish(self):

	for c in self.canvasses:
	    c.canv.pack_forget()
	    del(c.canv)
	    del(c)
        self.sw.destroy()
 	self.root.destroy()

	    #sys.exit(0)

##############################################################################

    def _destroy(self):

	for c in self.canvasses:
	    c.canv.pack_forget()
	    del(c.canv)
	    del(c)
        self.sw.destroy()
 	self.root.destroy()

############################################################################

    def hardcopy(self):

	np_printplot.PrintControl(self.root, plot=self)

############################################################################

    #
    # Do like this as IntVar value is incorrect if not stand alone
    #

    def set_mode_TS(self):
	self.v.set(MODE_TS)
	self.change_mode()

############################################################################

    def set_mode_HIST(self):
	self.v.set(MODE_HIST)
	self.change_mode()

############################################################################

    def set_mode_PDF(self):
	self.v.set(MODE_PDF)
	self.change_mode()

############################################################################

    def set_mode_CDF(self):
	self.v.set(MODE_CDF)
	self.change_mode()

############################################################################

    def change_mode(self):

	mode = self.v.get()
	#print 'mode %d->%d' % (self.mode, mode)
	if mode == self.mode:
	    return

	self.clear_canvasses()
        self.sspec = ''

	if mode == MODE_TS:
	    c = self.mode_ts()

	if mode == MODE_HIST:
	    c = self.mode_hist()
	
	if mode == MODE_PDF:
	    c = self.mode_pdf()
	
	if mode == MODE_CDF:
	    c = self.mode_cdf()

        if (mode & (MODE_HIST | MODE_PDF | MODE_CDF)):
            self.stylemenu.entryconfig('Errorbars-s.d.', state=DISABLED)
            self.stylemenu.entryconfig('Errorbars-s.e.', state=DISABLED)
        else:
            self.stylemenu.entryconfig('Errorbars-s.d.', state=self.ebsd)
            self.stylemenu.entryconfig('Errorbars-s.e.', state=self.ebse)

	#self.clear_canvasses()
	c.canv.pack(side=LEFT, fill=BOTH, expand = 1)
	self.canvasses.append(c)
	self.canv_curr = 0
	    
	self.mode = mode

##############################################################################

    def mode_ts(self):

	#print 'mode ts'
	for set in self.sets:
	    set.data = set.tsdata
	    set.len = set.tslen
	    set.reset()
	self.style = STYLE_POINTS
	self.stylev_curr.set(STYLE_POINTS)

        self.stylemenu.entryconfig('Errorbars-s.d.', state=self.ebsd)
        self.stylemenu.entryconfig('Errorbars-s.e.', state=self.ebse)

        

	return Plot_canv(self, self.sets, mode=MODE_TS, style=STYLE_POINTS)

##############################################################################

    def mode_pdf(self):

	#print 'mode pdf'
        i = 0
	for set in self.sets:
	    if set.pdfdata == None:
                if set.tag == None:
                    tag = i
                else:
                    tag = set.tag
		self.make_pdfdata(set, tag)
	    set.data = set.pdfdata
	    set.len = set.pdflen
	    set.reset()
            i += 1
	self.style = STYLE_BARS
	self.stylev_curr.set(STYLE_BARS)

	return Plot_canv(self, self.sets, mode=MODE_PDF, style=STYLE_BARS)

##############################################################################

    def mode_cdf(self):

	#print 'mode cdf'
	i = 0
	for set in self.sets:
	    if set.cdfdata == None:
		self.make_cdfdata(set, i)
	    set.data = set.cdfdata
	    set.len = set.cdflen
	    set.reset()
	    #print 'set %d CDF generated' % (i)
	    i += 1
	style = STYLE_LINES | STYLE_POINTS
	self.style = style
	self.stylev_curr.set(style)

	return Plot_canv(self, self.sets, mode=MODE_CDF, style=style)

##############################################################################

    def mode_hist(self):

	#print 'mode cdf'
	i = 0
	for set in self.sets:
	    if set.histdata == None:
		self.make_histdata(set, i)
	    set.data = set.histdata
	    set.len = set.histlen
	    set.reset()
	    #print 'set %d CDF generated' % (i)
	    i += 1
	style = STYLE_BARS
	self.style = style
	self.stylev_curr.set(style)

	return Plot_canv(self, self.sets, mode=MODE_HIST, style=style)

##############################################################################

    def make_cdfdata(self, set, setno):

        if set.tag != None:
            tag = set.tag
        else:
            tag = setno

        if set.tsdata:
            # generate from time series data
            N = set.tslen
            data = set.tsdata

            dd = {}
            for d in data:
                v = d[1]
                if dd.has_key(v):
                    dd[v] += 1
                else:
                    dd[v] = 1

            dl = dd.items()
            dl.sort()
            acc = 0.0
            p = []
            for d in dl:
                acc += d[1]
                p.append([d[0], acc/N, tag, []])

            set.cdfdata = p
            set.cdflen = len(dl)

        elif set.pdfdata or set.histdata:
            if not set.pdfdata:
               self.make_pdfdata(set, tag) 

            p = []
            acc = 0.0
            for d in set.pdfdata:
                acc += d[1]
                p.append([d[0], acc, tag, []])

            set.cdfdata = p
            set.cdflen = len(p)

        else:

            raise WrongDataTypeError('Can\'t produce cdf from data set %d' % (setno))

	

##############################################################################

    def make_histdata(self, set, tag):

	set.histdata, set.bktsz, set.histlen = self.make_bkts(set, tag,
                                                       reduce=0)

	

##############################################################################

    def make_pdfdata(self, set, tag):

        if set.tsdata:
            set.pdfdata, set.bktsz, set.pdflen = self.make_bkts(set, tag,
                                                       reduce=1)
        elif set.histdata:
            set.histdata.sort()
            N = 0
            vtot = 0.0
            vsqtot = 0.0
            for d in set.histdata:
                val = d[0]
                freq = d[1]
                N += freq
                vtot += freq*val
                vsqtot += vtot*val
                
            M = float(vtot)/N
            set.min = float(set.histdata[0][0])
            set.max = float(set.histdata[-1][0])
            set.range = range = float(set.max - set.min)
            set.variance = V = (vsqtot- (pow(vtot, 2)/N))/(N-1)
            set.sd = sqrt(V)
            set.mean = M

            set.pdfdata = copy.deepcopy(set.histdata)
            for d in set.pdfdata:
                d[1] /= N
            set.pdflen = set.tslen = set.histlen

        else:

            raise WrongDataTypeError('Can\'t produce pdf from data set %d' % (setno))

##############################################################################

    def make_bkts(self, set, tag, reduce=0):

	N = set.tslen
	vals = []
	vtot = 0.0
	vsqtot = 0.0
	for d in set.tsdata:
	    val = d[1]
	    vtot +=  val
	    vsqtot +=  pow(val, 2)
	    vals.append(val)

	vals.sort()

	M = vtot/N
	set.min = vals[0]
	set.max = vals[-1]
	set.range = range = set.max - set.min
	set.variance = V = (vsqtot- (pow(vtot, 2)/N))/(N-1)
	set.sd = sqrt(V)
	set.mean = M

	#print'%d Samples Min = %.3f Max = %.3f Range = %.3f Mean = %.3f sd = %.3f' % (N, vals[0], vals[-1], range, M, set.sd)

	if range == 0:
	    bktdata = [(range/2, 1.0, tag, None)]

	else:
	    othresh = set.sd*2 # outlier threshold

	    # cream off the outliers
	    lows = []
	    highs = []


	    bktdata, bktsz = self.bucketise(vals, float(set.sd), N, 
						    tag, reduce)
	    if len(lows):
		lowthresh = bktdata[0][0] + bktsz
		set.low_outliers = [lowthresh, float(len(lows))/N]
	    else:
		low_outliers = None
	    if len(highs):
		highthresh = bktdata[-1][0] + bktsz
		set.high_outliers = [highthresh, float(len(highs))/N]
	    else:
		high_outliers = None
	    
	#print low_outliers
	#print high_outliers

	#set.pdflen = len(set.pdfdata)

        return (bktdata, bktsz, len(bktdata))


##############################################################################

    def bucketise(self, vals, bktsz, n, tag, reduce):

	#print ' bucketise bktsz = %f n=%d' % (bktsz, n)
	#print vals

	pdict = {}
	maxcont = 0
	maxc = n/10.0

        if reduce:
            rf = n
        else:
            rf = 1

	#bktsz = bktsz/2

	for val in vals:
	    bkt = int(val/bktsz)
	    if val < 0:
		bkt = bkt -1
	    if not pdict.has_key(bkt):
		pdict[bkt] = [0, []]
	    b = pdict[bkt]
	    b[0] = b[0] + 1
	    b[1].append(val)
	    maxcont = MAX(maxcont, b[0])
	    if b[0] == maxcont:
		maxbkt = bkt

	# reached the limit of precision?
	lim = 1
	vs = pdict[maxbkt][1]
	l = vs[0]
	for v in vs:
	   if v != l:
	       lim = 0
	       break
	   else:
	       l = v
 
	if maxcont < maxc or maxcont == 1 or lim:
	    # done
	    d = pdict.items()
	    d.sort()
	    newlist = []
	    for i in d:
		#newlist.append([i[0]*bktsz+bktsz/2, float(i[1][0])/n, tag, []])
		newlist.append([i[0]*bktsz+bktsz/2, float(i[1][0])/rf, tag, []])
	    #print newlist
	    return (newlist, bktsz)
	else:
	    return self.bucketise(vals, bktsz/2, n, tag, reduce)

##############################################################################
	    
    def mode_smooth(self):
        
        from ts_smooth import TsSmooth, NoDataError, SmoothError
        #from tkSimpleDialog import askstring

        spec = []
        sspec = self.smoothtype.get()
        if sspec == 'Other' or sspec[0] == '\'':
            sspec = askstring('Smooth spec?', 'Enter smooth:arg [,smooth:arg] ...', parent=self.root, initialvalue=sspec.replace('Other', '').replace('\'', ''))
            if sspec == None:
                return
            val = '\'' + sspec + '\''
            self.osmoom.add_radiobutton(label=val, 
				  command=self.mode_smooth, 
				  variable=self.smoothtype,
				  value=val, indicatoron=0,
                                  background='grey')
            
        for s in sspec.split(','):
                    spec.append(s.lstrip().rstrip())
            
        try:
            sm = TsSmooth(spec=spec, savesde=1)
        except SmoothError, s:
           # print s
            return

        if self.mode & MODE_TS:
            smdf = 'tsdata_sm'
        elif self.mode & MODE_PDF:
            smdf = 'pdfdata_sm'
        elif self.mode & MODE_CDF:
            smdf = 'cdfdata_sm'
        else:
            print 'mode_smooth - operating in unknown mode %x' % (self.mode)
            return

        opath = sm.opath.replace(':', '-')
        #print 'opath', opath
            
        tag = 0
        for s in self.sets:
            smd = getattr(s, smdf)
            s.odata = s.data
            try:
                s.data = smd[sspec]
            except KeyError:
                try:
                    d = sm.smooth_data(s.data)
                except SmoothError, s:
                    print 'SmoothError set %d: %s' % (tag, s)
                    return
                smd[sspec] = d
                s.data = smd[sspec]
            s.len = len(s.data)
            #print s.fields
            #print s.data
            s.fields = ['X', 'Y', 'SD', 'SE']
            if 'SE' in s.fields:
                self.stylemenu.entryconfig('Errorbars-s.e.', state=NORMAL)
            if 'SD' in s.fields:
                self.stylemenu.entryconfig('Errorbars-s.d.', state=NORMAL)
            if s.col == None:
                s.col = self.collist[tag]
                tag += 1
            s.reset()
            s.opath = opath
            #s.path = s.path + opath
        self.path = self.path + opath

	self.clear_canvasses()
        self.v.set(MODE_TS_SMOOTH)
        self.sspec = sspec
        self.style = STYLE_POINTS
	self.stylev_curr.set(STYLE_POINTS)

	c = Plot_canv(self, self.sets, mode=MODE_TS, style=STYLE_POINTS)
	c.canv.pack(side=LEFT, fill=BOTH, expand = 1)
	self.canvasses.append(c)
	self.canv_curr = 0
	    
	self.mode |= DATA_SM

        # reset otherwise any following will become cumulative
        #for s in self.sets:
            #s.data = s.odata

##############################################################################
	    
    def make_collist(self):

	global ColList, LenColList

	self.collist = ColList
	
############################################################################## 
##############################################################################

ColList = ['red',
	   'blue',
	   'yellow',
	   'green',
	   'maroon1', 
	   'SteelBlue1', 
	   'turquoise3', 
	   'dark turquoise', 
	   'cyan2', 
	   'MediumPurple3', 
	   'medium orchid', 
	   'orchid2', 
	   'salmon1', 
	   'sandy brown', 
	   'LightGoldenrod1', 
	   'DarkOliveGreen2', 
	   'SeaGreen2', 
	   'dark khaki', 
	   'DeepPink2']
LenColList = len(ColList)
	    
############################################################################## 
##############################################################################
#
# Run as free-standing plotter
#
##############################################################################

def usage(s):

    print '%s <file>' % (s)
    sys.exit(0)

############################################################################## 


def main():

    scriptname = os.path.basename(argv[0])
    wi = B_WI
    ht = B_HT
    fields = None
    exping = 0

    try:
        optlist, args = getopt.getopt(sys.argv[1:], 'hS:f:')

    except getopt.error, s:
        print 'np_plot: ' + s.val
        usage(scriptname)
        sys.exit(1)

    for opt in optlist:
        if opt[0] == '-h':
            usage(scriptname)
        if opt[0] == '-S':
            szstr = string.split(opt[1], 'x')
            try:
                wi = int(szstr[0])
                ht = int(szstr[1])
            except:
                print '%s is not a valid window size' % (opt[1])
                usage(scriptname)
        if opt[0] == '-f':
            fields = opt[1]
            

    dr = DataReader(args, fields=fields)

    try:
        sets, path, title, xlab, ylab, decs, mode, decs = dr.get_data()
    except DataError, s:
        print 'Data Error %s' % (s)
        sys.exit(1)

                

    plot=np_Plot(sets, path, standalone='yes', title=title, xlab=xlab,
        ylab=ylab, raw_data=1, delay_activation='no', mode=mode,
        decorations=decs, width=wi, height=ht)  
	     
##############################################################################


# Call main when run as script
if __name__ == '__main__':
        main()

