#!/usr/bin/env python

from string import *
from gtk import *
import _gtk
import xmlrpclib
import pysga
import sgagtk
import sys
import socket
import math
import Numeric
from Scientific.Statistics.Histogram import *

debug=FALSE

try:
  import sg
except:
  sg=0

colors=["blue","red","gray","green","black","purple"]

class dobject:
    """This is an object description of an object to be downloaded.
    """
    bins=0
    type=""
    download=FALSE
    name=""
    layer=None
    col=0
    dataset=FALSE
    def __init__(self,name,type):
        self.name=name
        self.type=type

def remove_timer(widget,params):
    if params and params['timeout']:
      timeout_remove(params['timeout'])
      if debug:
        print "Timer removed"
      cursor = cursor_new(68 & 0xfe)
      try:
        params['page_box'].get_window().set_cursor(cursor)
      except:
        pass
      while events_pending():
        mainiteration(block=FALSE)

      return TRUE
    if debug:
        print "Timer NOT removed"
    return FALSE

def finish_func(params):
    timeout_remove(params['timeout'])
    pass


def download_func(params,page_box,vbox,dobject_names,progress,label,next=None,prev=None,cancel=None):
  if not page_box.get_window():
    return FALSE
  remove_timer(0,params)
  max_objects=len(dobject_names)

  histo1D=[]
  obj_dict={}
  sheet=pysga.SGworksheet(params['sheet_name'])
  vbox.show_all()
  
  max_objects=0
  dobject_names=[]
  for i in params['dobjects']:
    if i.download==TRUE:
      max_objects=max_objects+1
      dobject_names.append(i.name)
  progress.configure(0,0,max_objects)
  progress.set_value(0)
  if debug:
        print max_objects
  while events_pending():
    mainiteration(block=FALSE)

  if params['col_choice']==0:
    cur_col=params['col_num']
  else:
    cur_col=len(sg.column_names(sheet.name))

  if not params['cont_select'] and not len(params['tags'][params['db_select']]):
    if params['obj_select'] and len(params['obj_select'])>0:
      obj_dict={params['obj_select']:params['obj_select_type']}
    else:
      obj_dict=params['histos'][params['db_select']]
    vbox.show_all()
    while events_pending():
      mainiteration(block=FALSE)

    keys=obj_dict.keys()
  
    real_cnt=0
    for cnt in range(len(keys)):
      if not keys[cnt] in dobject_names:
        continue
      progress.set_value(real_cnt)
      real_cnt=real_cnt+1
      my_dobject=params["dobjects"][cnt]
      label.set_text("Downloading "+obj_dict[keys[cnt]]+" '"+keys[cnt]+"'")
      cursor = cursor_new(150 & 0xfe)
      try:
        page_box.get_window().set_cursor(cursor)
      except:
        pass
      while events_pending():
        mainiteration(block=FALSE)
      
      if debug:
        print "obj_dict=",obj_dict
      
      try:
        if obj_dict[keys[cnt]]=='histogram':
          rpc_params={"bootfile":params["fdname"],
                      "db":params['db_select'],
                      "histname":keys[cnt]}  
          histo=params['dbsvr'].DBServer.getHisto1Dcol(rpc_params)
          histo1D.append(histo)
          min=histo["min"]
          delta=(histo["max"]-histo["min"])/histo["bins"]
          bins=Numeric.arrayrange(histo["min"]+delta/2,histo["max"],delta)
          cols=sg.column_names(params['sheet_name'])
          col_num=len(cols)
          if cur_col+3>col_num:
           sheet.add_columns(cur_col+3-col_num)
          my_dobject.col=cur_col
          sheet.clearcol(cur_col)
          sheet.setcol(cur_col,bins)
          sheet.clearcol(cur_col+1)
          sheet.setcol(cur_col+1,histo["values"])
          sheet.clearcol(cur_col+2)
          sheet.setcol(cur_col+2,histo["errors"])
#          if params['rename_choice']:
#            sg.set_column_name(sheet.name,cur_col,keys[cnt]+"_bins")
#            sg.set_column_name(sheet.name,cur_col+1,keys[cnt]+"_values")
#            sg.set_column_name(sheet.name,cur_col+2,keys[cnt]+"_errors")
          if my_dobject.dataset==FALSE:
              exp1="col(%d,sheet='%s')"%(cur_col,sheet.name)
              exp2="col(%d,sheet='%s')"%(cur_col+1,sheet.name)
              width =abs(bins[1]-bins[0])/2
              my_dobject.layer.plot_expression_xy_bars(exp1,exp2,width)
              my_dobject.dataset=TRUE
          else:
            my_dobject.layer.refresh()
          my_dobject.layer.autoscale()
          cur_col=cur_col+3
      except socket.error, my_except:
        try: 
         errstring=my_except[1]
        except:
         errstring=my_except[0]
        vbox.pack_start(GtkLabel("Unable to connect:\n"+errstring),
        expand=FALSE,fill=FALSE,padding=5)
        return
      except xmlrpclib.ProtocolError, my_except:
        vbox.pack_start(GtkLabel("XML-RPC error connecting to\n"+
         my_except.url+":\n"+my_except.errmsg),
        expand=FALSE,fill=FALSE,padding=5)
        return
  #    except:
  #      vbox.pack_start(GtkLabel("Unknown error\n"),
  #      expand=FALSE,fill=FALSE,padding=5)
  #      return
      label.set_text("Download complete")
      progress.set_value(max_objects)
      cursor = cursor_new(68 & 0xfe)
      page_box.get_window().set_cursor(cursor)
      while events_pending():
        mainiteration(block=FALSE)
  
  else: #We're dealing with tags
    containers=params['tags'][params['db_select']].keys()
    if debug:
        print "containers=",containers
    for cont in containers:
      if params['tag_select']:
        if debug:
          print "params['tag_select']=",params['tag_select']
        tags=[params['tag_select']]
      else:
        tags=[]
        if debug:
          print "params['tags'][params['db_select']][cont].keys()=",params['tags'][params['db_select']][cont].keys()
        for tname in params['tags'][params['db_select']][cont].keys():
          tags.append(tname)
      if debug:
        print "tags=",tags
      for tname in tags:
        if params['obj_select_type']=='Column':
          colnames=[params['obj_select']]
        else:
          colnames=params['tags'][params['db_select']][cont][tname]['cols']
        if debug:
          print "colnames=",colnames
        col_num=len(colnames)
        cols=sg.column_names(params['sheet_name'])
        sheet_col_num=len(cols)
        if cur_col+3>sheet_col_num:
           sheet.add_columns(cur_col+3-sheet_col_num)

        real_cnt=0
        for i in range(col_num):
          cname=colnames[i]
          if not cname in dobject_names:
            continue
          my_dobject=params["dobjects"][i]
          progress.set_value(real_cnt)
          real_cnt=real_cnt+1

          label.set_text("Downloading "+cont+" : "+tname+" : "+cname)
          cursor = cursor_new(150 & 0xfe)
          page_box.get_window().set_cursor(cursor)
          while events_pending():
            mainiteration(block=FALSE)

          try:
            rpc_params={"bootfile":params["fdname"],
                        "db":params['db_select'],
                        "contname":cont,
                        "tagname":tname,  
                        "colname":cname}
            print "Reading tag column",cname
            tag=params['dbsvr'].DBServer.getTagColumn(rpc_params)
            print "Finished"
            if tag['count']==0:
#              raise ValueError
              if debug:
                 print "Error retrieving Column "+cname+" from\nBootfile: "+\
                 params['fdname']+"\nDatabase: "+params['db_select']+"\nContainer: "+cont+"\nTag: "+tname
                 print "tag=",tag
                 print "cur_col=",cur_col," col_num=",col_num
            cols=sg.column_names(params['sheet_name'])
            sheet_col_num=len(cols)
            if cur_col+3>sheet_col_num:
               sheet.add_columns(cur_col+3-sheet_col_num)
            if debug:
               print "Binning ",my_dobject.name," into ",my_dobject.bins," bins"
            my_dobject.col=cur_col
            H=Histogram(tag["values"],my_dobject.bins)
            try:
              H=Histogram(tag["values"],my_dobject.bins)
              print "H1"
              sheet.clearcol(cur_col)
              print "H2"
              sheet.setcol(cur_col,H.array[:,0])
              print "H3"
              sheet.clearcol(cur_col+1)
              print "H4"
              sheet.setcol(cur_col+1,H.array[:,1])
              print "H5"
              sheet.clearcol(cur_col+2)
              print "H6"
              sheet.setcol(cur_col+2,tag["values"])
              print "H7"
              width=abs(H.array[1,0]-H.array[0,0])/2
              print "H8"
            except:
              if debug:
                print "Histogram exception! Continuing"
                print "tag['values']=",tag["values"]
#              sheet.clearcol(cur_col)
#              sheet.clearcol(cur_col+1)
#              sheet.clearcol(cur_col+2)
              width=0.
              print "After exception 0"
              pass
#            if params['rename_choice']:
#              sg.set_column_name(sheet.name,cur_col,cname+"_bins")
#              sg.set_column_name(sheet.name,cur_col+1,cname+"_values")
#              sg.set_column_name(sheet.name,cur_col+2,cname+"_data")
            print "After exception"
            if my_dobject.dataset==FALSE:
              exp1="col(%d,sheet='%s')"%(cur_col,sheet.name)
              exp2="col(%d,sheet='%s')"%(cur_col+1,sheet.name)
              if debug:
                print "bin width=",width
              my_dobject.layer.plot_expression_xy_bars(exp1,exp2,width)
              my_dobject.dataset=TRUE
            else:
              my_dobject.layer.refresh()
            my_dobject.layer.autoscale()
            cur_col=cur_col+3

          except socket.error, my_except:
            try: 
              errstring=my_except[1]
            except:
              errstring=my_except[0]
            vbox.pack_start(GtkLabel("Unable to connect:\n"+errstring),
            expand=FALSE,fill=FALSE,padding=5)
            return
          except xmlrpclib.ProtocolError, my_except:
            vbox.pack_start(GtkLabel("XML-RPC error connecting to\n"+
              my_except.url+":\n"+my_except.errmsg),
            expand=FALSE,fill=FALSE,padding=5)
            return
          except ValueError:
            vbox.pack_start(GtkLabel("Error retrieving Column '"+cname+"' from\nBootfile: "+\
              params['fdname']+"\nDatabase: "+params['db_select']+"\nContainer: "+cont+"\nTag: "+tname),
            expand=FALSE,fill=FALSE,padding=5)
            return
          except:
            pass

        label.set_text("Download complete")
        progress.set_value(max_objects)
        cursor = cursor_new(68 & 0xfe)
        try:
          page_box.get_window().set_cursor(cursor)
        except:
          pass
        while events_pending():
          mainiteration(block=FALSE)
  params['plot'].refresh_canvas()
  params['timeout']=timeout_add(5000, download_func, params,page_box,vbox,dobject_names,progress,label,next,prev,cancel)
  return TRUE

def download_page2(params,page_box,next=None,prev=None,cancel=None):
  vbox=GtkVBox()  
  page_box.pack_start(vbox)
  params['page_box']=page_box

  plot=pysga.SGplot(0)
  params['plot']=plot
  max_objects=0
  dobject_names=[]
  plot.freeze()
  for i in range(len(params['dobjects'])):
    dob=params['dobjects'][i]

    if dob.download==TRUE:
      max_objects=max_objects+1
      dobject_names.append(dob.name)
      if debug:
        print "comparison:",plot.layers(),i+1
      if plot.layers()<max_objects:
        plot.new_layer(0)
  if max_objects>1:
    ncols=2.
  else:
    ncols=1.
  nrows=math.ceil(max_objects/ncols)
  hgap=0.175
  vgap=0.10
  left=0.09
  right=0.025
  top=0.03
  bottom=0.03
  width = 1./ncols - left - right
  height = 1./nrows - top - bottom
  if debug:
    print "width=",width," height=",height
    print "max_objects=",max_objects
  l=0
  for i in range(len(params['dobjects'])):
    dob=params['dobjects'][i]
    if dob.download==TRUE:
      dob.layer=plot.layer(l+1)
      dob.layer.hide_legend()
      dob.layer.set_line_style(0)
      dob.layer.set_symbol_style(1)
      dob.layer.set_symbol_color(colors[l%len(colors)])

      j=l%ncols
      k=math.floor(l/ncols)
      if debug:
        print "j=",j," k=",k
      x=j/ncols+left
      y=k/nrows+top
      if debug:
        print "x=",x," y=",y
      l=l+1
      dob.layer.resize(width,height)
      dob.layer.move(x,y)
      dob.layer.xaxis().show_titles(FALSE,TRUE);
      dob.layer.yaxis().show_titles(FALSE,FALSE);

      dob.layer.xaxis().show_labels(TRUE,FALSE);
      dob.layer.yaxis().show_labels(TRUE,FALSE);

      dob.layer.xaxis().label_style(0,0);
      dob.layer.yaxis().label_style(1,1);
      dob.layer.xaxis().label_pos(0.01,0.5);
      dob.layer.yaxis().label_pos(-0.05,0.5);


      dob.layer.xaxis().set_title(dob.name)
  plot.thaw()
    

  vbox.set_homogeneous(FALSE) 
#  print "params['tags'][params['db_select']]=",params['tags'][params['db_select']]
#  if not len(params['db_select']) or (not len(params['histos'][params['db_select']]) \
#    and not len(params['tags'][params['db_select']])):  
  if max_objects==0:
    vbox.pack_start(GtkLabel("No objects selected!\n"+
     "Press 'Back' to make a selection."),expand=TRUE,fill=TRUE,padding=5)
    vbox.show_all()
    return

  label=GtkLabel("")
  vbox.pack_start(label,expand=FALSE,fill=FALSE,padding=5)
  progress=GtkProgressBar()
  progress.set_bar_style(PROGRESS_CONTINUOUS)
  progress.set_show_text(TRUE)
    
  
  hbox=GtkHBox()
  hbox.pack_start(progress,padding=5,expand=TRUE,fill=TRUE)
  vbox.pack_start(hbox,expand=FALSE,fill=FALSE,padding=5)
  
  params['timeout']=timeout_add(0, download_func, params,page_box,vbox,dobject_names,progress,label,next,prev,cancel)
  prev.connect("pressed",remove_timer,params)

def dobject_toggle(checkbutton,my_dobject):
  my_dobject.download=checkbutton.get_active()

def bins_changed(adj,my_dobject):
  my_dobject.bins=adj.value
  if debug:
    print "Changed bins to ",adj.value


def download_selection_page(params,page_box,next=None,prev=None,cancel=None):
  vbox=GtkVBox()  
  page_box.pack_start(vbox)

  vbox.set_homogeneous(FALSE) 
  if debug:
    print "params['tags'][params['db_select']]=",params['tags'][params['db_select']]
  if not len(params['db_select']) or (not len(params['histos'][params['db_select']]) \
    and not len(params['tags'][params['db_select']])):  
    vbox.pack_start(GtkLabel("No objects selected!\n"+
     "Press 'Back' to make a selection."),expand=TRUE,fill=TRUE,padding=5)
    vbox.show_all()
    return

  label=GtkLabel("")
  vbox.pack_start(label,expand=FALSE,fill=FALSE,padding=5)

  table=GtkTable(2,1,FALSE)
  table.set_col_spacings(10)
  table.set_row_spacings(5) 
  swin=GtkScrolledWindow()
  swin.set_policy(POLICY_NEVER,POLICY_AUTOMATIC)
  swin.show() 
  vbox.pack_start(swin,expand=TRUE,fill=TRUE,padding=5)
  swin.add_with_viewport(table)
  
  histo1D=[]
  obj_dict={}
  sheet=pysga.SGworksheet(params['sheet_name'])
  vbox.show_all() 
  if params['col_choice']==0:
    cur_col=params['col_num']
  else:
    cur_col=len(sg.column_names(sheet.name))

  params['dobjects']=[]
  if not params['cont_select'] and not len(params['tags'][params['db_select']]):
    label.set_text("Please select histograms to download:")
    if params['obj_select'] and len(params['obj_select'])>0:
      obj_dict={params['obj_select']:params['obj_select_type']}
    else:
      obj_dict=params['histos'][params['db_select']]
    vbox.show_all()
    keys=obj_dict.keys()
    if debug:
      print "obj_dict=",obj_dict
    
    for cnt in range(len(keys)):
      my_dobject=dobject(keys[cnt],"histogram")
      params['dobjects'].append(my_dobject)
      hbox=GtkHBox()
      button3 = GtkCheckButton(label=keys[cnt]) 
      table.attach(button3, 0, 2, cnt, cnt+1,yoptions=0,xpadding=5)  
      button3.set_active(my_dobject.download)
      button3.connect("toggled",dobject_toggle,my_dobject)

  else: #We're dealing with tags
    containers=params['tags'][params['db_select']].keys()
    label.set_text("Please select columns to download:")
    if debug:
      print "containers=",containers
    for cont in containers:
      if params['tag_select']:
        tags=[params['tag_select']]
      else:
        tags=[]
        for tname in params['tags'][params['db_select']][cont].keys():
          tags.append(tname)
      if debug:
        print "tags=",tags
      for tname in tags:
        if params['obj_select_type']=='Column':
          colnames=[params['obj_select']]
        else:
          colnames=params['tags'][params['db_select']][cont][tname]['cols']
        if debug:
          print "colnames=",colnames
        col_num=len(colnames)

        for i in range(col_num):
          cname=colnames[i]
          my_dobject=dobject(cname,"column")
          params['dobjects'].append(my_dobject)
          hbox=GtkHBox()
          button3 = GtkCheckButton(label=cname) 
          table.attach(button3, 0, 1, i, i+1,yoptions=0,xpadding=5)  
          button3.set_active(my_dobject.download)
          button3.connect("toggled",dobject_toggle,my_dobject)
          Adj=GtkAdjustment(10,1,50,1,5)
          rangew=GtkSpinButton(adj=Adj,digits=0)
          my_dobject.bins=Adj.value
          Adj.connect("value_changed",bins_changed,my_dobject)
          table.attach(rangew, 1, 2, i, i+1,yoptions=0,xpadding=5)  
  vbox.show_all()


def plot_col_page(params,page_box,next=None,prev=None,cancel=None):
# First create new sheet object, which may create a new physical sheet:
  mysheet=pysga.SGworksheet(params['sheet_name'])
  vbox=GtkVBox()  
  page_box.pack_start(vbox)

  vbox.set_homogeneous(FALSE)  
  if not len(params['db_select']):  
    vbox.pack_start(GtkLabel("No objects selected!\n"+
     "Press 'Back' to make a selection."),expand=TRUE,fill=TRUE,padding=5)
    vbox.show_all()
    return
  
  table = GtkTable(3, 2, FALSE)
  table.set_col_spacings(10)
  table.set_row_spacings(5) 
  vbox.pack_start(table,expand=TRUE,fill=TRUE,padding=5)
  
  dblabel=GtkLabel("Database: "+params['db_select'])
  dblabel.set_justify(JUSTIFY_LEFT)
  table.attach(dblabel, 0, 2, 0, 1,yoptions=0,xpadding=5)  
  if params['obj_select'] and len(params['obj_select']):
    table.attach(GtkLabel(params['obj_select_type']+": "+params['obj_select']),0,1,
    1, 2, yoptions=0, xpadding=5, xoptions=0)
  table.attach(GtkLabel("Sheet selected: "+params['sheet_name']), 0, 2, 2, 3,yoptions=0,xpadding=5,xoptions=0)  
  table.attach(GtkHSeparator(),0,2, 3,4)    
  table.attach(GtkLabel("Start inserting in:"),0,1,
   4, 5, yoptions=0, xpadding=5, xoptions=0)      


  params['col_choice']=0
  button1 = GtkRadioButton(None, "Existing column:") 
  button1.connect("toggled",col_toggle,params,0)

  menu=GtkCombo()
  cols=sg.column_names(params['sheet_name'])
  menu.set_popdown_strings(cols)
  menu.set_value_in_list(TRUE,FALSE)
  active=mysheet.col0()
  params['col_num']=active
  menu.entry.set_text(cols[active])

  menu.entry.set_editable(FALSE)
  menu.entry.connect("changed",col_combo_changed,params)


  hbox=GtkHBox()
  hbox.pack_start(button1,expand=FALSE,fill=FALSE,padding=0)
  hbox.pack_start(menu,expand=FALSE,fill=FALSE,padding=5)
  vbox.pack_start(hbox,expand=TRUE,fill=TRUE,padding=5)

  button2 = GtkRadioButton(button1, "New column after column '"+cols[-1]+"'")
  button2.connect("toggled",col_toggle,params,1)  
  hbox=GtkHBox()  
  hbox.pack_start(button2,expand=FALSE,fill=FALSE,padding=0)
  vbox.pack_start(hbox,expand=TRUE,fill=TRUE,padding=5)
  
  vbox.pack_start(GtkHSeparator(),expand=TRUE,fill=TRUE,padding=5) 

  hbox=GtkHBox()
  button3 = GtkCheckButton(label="Rename columns using object name") 
  hbox.pack_start(button3,expand=FALSE,fill=FALSE,padding=0)
  vbox.pack_start(hbox,expand=TRUE,fill=TRUE,padding=5)
  button3.set_active(TRUE)
  params['rename_choice']=TRUE
  button3.connect("toggled",rename_toggle,params)

  vbox.show_all()

def new_sheet_name_changed(entry,params):
    params['sheet_name']=entry.get_text()    
    
def sheet_toggle(button,params,widget,value):
  params['sheet_choice']=value
  if value==0:
    params['sheet_name']=widget.entry.get_text()    
  elif value==1:
    params['sheet_name']=params['db_select']
  elif value==2:
    params['sheet_name']=widget.get_text()    

  if widget:
    if button.get_active():
      widget.set_sensitive(TRUE)
    else:
      widget.set_sensitive(FALSE)

def rename_toggle(button,params):
  params['rename_choice']=(params['rename_choice']+1)%2
  
def col_toggle(button,params,value):
  params['col_choice']=value

def sheet_combo_changed(entry,params):
  params['sheet_name']=entry.get_text()

def col_combo_changed(entry,params,cols):
  text=entry.get_text()
  cnt=0
  for col in cols:
    if col==text:
      params['col_num']=cnt
      break
    cnt=cnt+1

def create_menu(names):
  if not len(names): return None
  menu = GtkMenu()
  group = None
  for name in names:
    menuitem = GtkRadioMenuItem(group,name)
    group = menuitem
    menu.append(menuitem)
    menuitem.show()
  return menu


def plot_sheet_page(params,page_box,next=None,prev=None,cancel=None):
  vbox=GtkVBox()
  page_box.pack_start(vbox)

  vbox.set_homogeneous(FALSE)  
  if not len(params['db_select']):  
    vbox.pack_start(GtkLabel("No objects selected!\n"+
     "Press 'Back' to make a selection."),expand=TRUE,fill=TRUE,padding=5)
    vbox.show_all()
    next.set_sensitive(FALSE)
    return
  
  table = GtkTable(3, 2, FALSE)
  table.set_col_spacings(10)
  table.set_row_spacings(5) 
  vbox.pack_start(table,expand=TRUE,fill=TRUE,padding=5)
  table.attach(GtkLabel("Database: "+params['db_select']), 0, 1, 0, 1,yoptions=0,xpadding=5,xoptions=EXPAND|FILL)  


  if params['obj_select'] and len(params['obj_select'])>0:
    table.attach(GtkLabel(params['obj_select_type']+": "+params['obj_select']),0,1,
    1, 2, yoptions=0, xpadding=5, xoptions=0)    

  else:
    page_box.show_all()
    cursor = cursor_new(150 & 0xfe)
    page_box.get_window().set_cursor(cursor)
    while events_pending():
      mainiteration(block=FALSE)
    histos=fetch_histonames(params,params['db_select'])
#    tags=fetch_tagnames(params,params['db_select'])
    tags=params['tags'][params['db_select']]

    cursor = cursor_new(68 & 0xfe)
    page_box.get_window().set_cursor(cursor)
    histonames=histos.keys()
    tagnames=tags.keys()

    if len(histonames)>0:
      table.attach(GtkLabel("%d histogram(s) found in this database"%(len(histonames))),0,1,
      1, 2, yoptions=0, xpadding=5, xoptions=0)    
    elif len(tagnames)>0:
      table.attach(GtkLabel("%d container(s) found in this database"%(len(tagnames))),0,1,
      1, 2, yoptions=0, xpadding=5, xoptions=0)    
    else:
      table.attach(GtkLabel("No usable objects found in this database"),0,1,
      1, 2, yoptions=0, xpadding=5, xoptions=0)    
      vbox.show_all()
      next.set_sensitive(FALSE)
      return 
    

  table.attach(GtkHSeparator(),0,2,2,3)    
  table.attach(GtkLabel("Put values in:"),0,2,
   3, 4, yoptions=0, xpadding=5, xoptions=0)      

  params['sheet_choice']=0
  button1 = GtkRadioButton(None, "Existing sheet:") 
#  menu=GtkOptionMenu()
  menu=GtkCombo()
  button1.connect("toggled",sheet_toggle,params,menu,0)
  sheets=sg.worksheet_names()
  menu.set_popdown_strings(sheets)
  menu.set_value_in_list(TRUE,FALSE)
  #menu.set_menu(create_menu(sheets))
  active=sg.active_worksheet_name()
  params['sheet_name']=active

  for i in range(len(sheets)):
    if active==sheets[i]:
      menu.entry.set_text(active)
      break
  menu.entry.set_editable(FALSE)
  menu.entry.connect("changed",sheet_combo_changed,params)

  hbox=GtkHBox()
  hbox.pack_start(button1,expand=FALSE,fill=FALSE,padding=0)
  hbox.pack_start(menu,expand=FALSE,fill=FALSE,padding=5)
  vbox.pack_start(hbox,expand=TRUE,fill=TRUE,padding=5)

  button2 = GtkRadioButton(button1, "New sheet named '"+params['db_select']+"'") 
  button2.connect("toggled",sheet_toggle,params,None,1)  
  hbox=GtkHBox()  
  hbox.pack_start(button2,expand=FALSE,fill=FALSE,padding=0)
  vbox.pack_start(hbox,expand=TRUE,fill=TRUE,padding=5)
 
  hbox=GtkHBox()
  button3 = GtkRadioButton(button1, "New sheet named: ") 

  sheet_entry=GtkEntry()
  sheet_entry.connect("changed",new_sheet_name_changed,params)
  hbox.pack_start(button3,expand=FALSE,fill=FALSE,padding=0)
  hbox.pack_start(sheet_entry,expand=TRUE,fill=TRUE,padding=5)

  vbox.pack_start(hbox,expand=TRUE,fill=TRUE,padding=5)
  sheet_entry.set_sensitive(FALSE)
  button3.set_active(FALSE)
  button3.connect("toggled",sheet_toggle,params,sheet_entry,2)

  vbox.show_all()
    


def unselect_hist(tree,item,item2,(params,dbname,histname)):
  params['obj_select_type']=''
  params['obj_select']=''
  params['db_select']=''
  params['hselect'][dbname][histname]=FALSE

def fetch_histonames(params,dbname):
    rpc_params={"bootfile":params["fdname"],
                "dbs":[dbname]}  
    histos=params['dbsvr'].DBServer.getHistos(rpc_params)

    types={}
    params['histos'][dbname]=types
    histos['names']={}
    names=histos['histonames']
    htypes=histos['histotypes']
    for i in range(len(names)):
      types[names[i]]=htypes[i]
    return types

def fetch_tagnames(params,dbname):
    rpc_params={"bootfile":params["fdname"],
                "dbs":[dbname]}  
    tags=params['dbsvr'].DBServer.getTags(rpc_params)
    tagnames=tags['tags']
    continfo={}
    for i in range(len(tags['tags'])):
        try:
            temp=continfo[tags['containertag'][i]]
        except:
          continfo[tags['containertag'][i]]={}
        rpc_params={"bootfile":params["fdname"],
                "db":dbname,
                "container":tags['containertag'][i],
                "tagname":tags['tags'][i]}
        if debug:
          print "fetching %s:%s"%(tags['containertag'][i],tags['tags'][i])          
        while events_pending():
          mainiteration(block=FALSE)        
        columns=params['dbsvr'].DBServer.getColumns(rpc_params)
        if columns:
          continfo[tags['containertag'][i]][tags['tags'][i]]=columns
      
    params['tags'][dbname]=continfo
    if debug:
      print continfo
    return continfo


def io_thread(params):
  params['histos']={}
  dbitems=params['dbitems'].keys()
  for i in range(len(dbitems)):
    dbname=dbitems[i]
    labelstring="http://"+params["host"]+":"+params["port"]+params["path"]+\
    "\n Scanning for histograms:\n"+dbname
    params['dblabel'].set_text(labelstring)
    rpc_params={"bootfile":params["fdname"],
                "dbs":[dbname]}
    
    while events_pending():
      mainiteration(block=FALSE)
    histos=params['dbsvr'].DBServer.getHistos(rpc_params)
    histonames=histos['histonames']
    histotypes=histos['histotypes']
    if len(histonames)>0:
       for j in range(len(histonames)):
         item=params["ctree"].insert_node(params['dbitems'][dbname],None,
                [histonames[j],histotypes[j]],expanded=TRUE,is_leaf=TRUE)

  labelstring="http://"+params["host"]+":"+params["port"]+params["path"]
  params['dblabel'].set_text(labelstring)



def connect(params):
  params["dbsvr"] = xmlrpclib.Server("http://"+params["host"]+":"+params["port"]+params["path"])
  dbs=params["dbsvr"].DBServer.getDBs(params["fdname"])
  params['dbs']=dbs

  params['dbitems']={}
  dbitems=params['dbitems']
  for i in range(len(dbs)):
    item=params["ctree"].insert_node(None,None,[dbs[i]],expanded=TRUE,is_leaf=FALSE)
    dbitems[dbs[i]]=item


def select_row_db(ctree,node,column,params):
  node_info=ctree.get_node_info(node)
  nodename=node_info[0]
  if debug:
    print node_info
  params['obj_select']=None
  params['obj_select_type']=None
  params['db_select']=None
  params['cont_select']=None
  params['tag_select']=None


# First check whether a histogram or tag was selected
  for db in params['dbitems'].keys():
      parent=params['dbitems'][db]
      params['db_select']=db
      params['obj_select']=''
      if debug:
        print "params['tags'].keys()=",params['tags'].keys()
        if parent==node:
          print "parent=",parent," node=",node
      if parent==node: # A database was selected
        if debug:
            print "Database selected!"
        params['db_select']=db
        params['obj_select']=None
        if params['histos'].has_key(db) or params['tags'].has_key(db):
          break
        cursor = cursor_new(150 & 0xfe)
        ctree.get_window().set_cursor(cursor)
        while events_pending():
          mainiteration(block=FALSE)
        histos=fetch_histonames(params,node_info[0])
        histonames=histos.keys()
        params['histonodes'][db]=[]
        for i in range(len(histonames)):
          leaf=params["ctree"].insert_node(node,None,[histonames[i]],expanded=TRUE,is_leaf=TRUE)        
          params['histonodes'][db].append(leaf)

        #Fetch tags
        while events_pending():
          mainiteration(block=FALSE)
        containers=fetch_tagnames(params,node_info[0])
        contnames=containers.keys()
        params['tagnodes'][db]={}
        for i in range(len(contnames)):
          leaf=params["ctree"].insert_node(node,None,[contnames[i]],expanded=TRUE,is_leaf=FALSE)
          params['tagnodes'][db][contnames[i]]={}
          tags=containers[contnames[i]]
          if debug:
            print tags
          tagnames=tags.keys()
          for j in range(len(tagnames)):
            tleaf=params["ctree"].insert_node(leaf,None,[tagnames[j]],expanded=TRUE,is_leaf=FALSE)
            params['tagnodes'][db][contnames[i]][tagnames[j]]=tleaf
            colnames=tags[tagnames[j]]['cols']

            for k in range(len(colnames)):
                cleaf=params["ctree"].insert_node(tleaf,None,[colnames[k]],expanded=TRUE,is_leaf=TRUE)
        while events_pending():
          mainiteration(block=FALSE)
        if debug:
          print "Setting cursor"
        cursor = cursor_new(68 & 0xfe)
        ctree.get_window().set_cursor(cursor)

        break
      elif ctree.is_ancestor(parent,node):
        if params['histos'][db].has_key(nodename):
            if debug:
              print "Histogram selected! ",nodename
            params['db_select']=db
            params['cont_select']=None
            params['tag_select']=None
            params['obj_select']=ctree.get_node_info(node)[0]
            params['obj_select_type']=params['histonodes'][db][ctree.get_node_info(node)[0]]
            break
        if params['tags'][db].has_key(nodename):
            if debug:
              print "Container selected! ",nodename
            params['db_select']=db
            params['cont_select']=nodename
            params['tag_select']=None
            params['obj_select']=ctree.get_node_info(node)[0]
            params['obj_select_type']="Container"
            break
        containers=params['tags'][db]
        contnames=containers.keys()
        tag_found=0
        col_found=0
        for name in contnames:
            if col_found:
                break
            if containers[name].has_key(nodename):
                if debug:
                  print "Tag selected! ",nodename
                params['db_select']=db
                params['cont_select']=name
                params['tag_select']=nodename
                params['obj_select']=ctree.get_node_info(node)[0]
                params['obj_select_type']="Tag"
                tag_found=1
                break
            tags=containers[name]
            tag_names=tags.keys()
            for tname in tag_names:
                tparent=params['tagnodes'][db][name][tname]
                if nodename in tags[tname]['cols']:
                    if debug:
                      print "Column selected! ",nodename
                    params['db_select']=db
                    params['cont_select']=name
                    params['tag_select']=ctree.get_node_info(tparent)[0]
                    params['obj_select']=ctree.get_node_info(node)[0]
                    params['obj_select_type']="Column"
                    col_found=1
                    break

        if tag_found or col_found:
            break

# This should never happen!
        if debug:
          print "Unknown object selected!"
        params['db_select']=''


def build_object_page(params,page_box,next=None,prev=None,cancel=None):
  vbox=GtkVBox()
  page_box.pack_start(vbox)
  vbox.set_homogeneous(FALSE)
  input=params['input']

  for name in ['host','path','port','fdname']:
     params[name]=input[name].entry.get_text()
     values=sg.config_get_value(name,"clarens")
     sg.config_set_value(name,"clarens",[params[name]]+
     filter(lambda x,y=params[name]: x != y,values),TRUE)
  sg.config_set_value("secure","clarens",input['secure'].get_active(),TRUE)

  params['histos']={}
  params['tags']={}
  params['histonodes']={}
  params['tagnodes']={}


  if input['secure'].get_active() and sys.version[0]>'1':
   protocol='https'
  else:
   protocol='http'
  labelstring=protocol+"://"+params["host"]+":"+params["port"]+params["path"]

  dblabel=GtkLabel(labelstring)
  params['dblabel']=dblabel
  vbox.pack_start(dblabel,expand=FALSE,fill=FALSE,padding=5)
  vbox.pack_start(GtkHSeparator(),expand=FALSE,fill=FALSE,padding=5)
  swin=GtkScrolledWindow()
  swin.set_policy(POLICY_NEVER,POLICY_NEVER)
  swin.show() 
  vbox.pack_start(swin,padding=5)


  ctree=GtkCTree(cols=1,titles=[params["fdname"]])
  ctree.set_expander_style(CTREE_EXPANDER_TRIANGLE)
  ctree.set_line_style(CTREE_LINES_DOTTED)
  ctree.connect("tree-select-row",select_row_db,params)
#  ctree.connect("tree-expand",expand_row_db,params)
  swin.add_with_viewport(ctree)

  params["ctree"]=ctree
  params['db_select']=''

  cursor = cursor_new(150 & 0xfe)
  page_box.get_window().set_cursor(cursor)
  while events_pending():
    mainiteration(block=FALSE)
  try:  
    connect(params)
  
  except socket.error, my_except:
    try: 
     errstring=my_except[1]
    except:
     errstring=my_except[0]
    swin.destroy()
    vbox.pack_start(GtkLabel("Unable to connect:\n"+errstring),
    expand=FALSE,fill=FALSE,padding=5)
    next.set_sensitive(FALSE)

  except xmlrpclib.ProtocolError, my_except:
    swin.destroy()
    vbox.pack_start(GtkLabel("XML-RPC error connecting to\n"+
     my_except.url+":\n"+my_except.errmsg),
    expand=FALSE,fill=FALSE,padding=5)
    next.set_sensitive(FALSE)
  except:
    swin.destroy()
    vbox.pack_start(GtkLabel("Unknown error\n"),
    expand=FALSE,fill=FALSE,padding=5)
    next.set_sensitive(FALSE)
    
  cursor = cursor_new(68 & 0xfe)
  page_box.get_window().set_cursor(cursor)

  swin.set_policy(POLICY_NEVER,POLICY_AUTOMATIC)
  vbox.show_all()


  return vbox

def set_def_host():
    sg.config_set_value("host","clarens",["localhost"],FALSE)

def set_def_path():
    sg.config_set_value("path","clarens",["/cgi-bin/DBServer"],FALSE)

def set_def_port():
    sg.config_set_value("port","clarens",["80"],FALSE)

def set_def_fdname():
    sg.config_set_value("fdname","clarens",["/home2/myoofd/ORCATEST.boot"],FALSE)

def set_def_secure():
    sg.config_set_value("secure","clarens",FALSE,FALSE)
    
def commit_value():
    pass

def init_page(params,page_box,next=None,prev=None,cancel=None):
  connect_vbox=GtkVBox()
  page_box.pack_start(connect_vbox)
  frontpage=connect_vbox
  table = GtkTable(3, 2, FALSE)
  table.set_col_spacings(10)
  table.set_row_spacings(5) 
  connect_vbox.pack_start(table,expand=TRUE,fill=TRUE,padding=5)
  input=params["input"]

  input['host']=GtkCombo()
  input['host'].set_popdown_strings(sg.config_get_value("host","clarens"))
  input['path']=GtkCombo()
  input['path'].set_popdown_strings(sg.config_get_value("path","clarens"))
  input['port']=GtkCombo()
  input['port'].set_popdown_strings(sg.config_get_value("port","clarens"))
  input['fdname']=GtkCombo()
  input['fdname'].set_popdown_strings(sg.config_get_value("fdname","clarens"))

  names=['host','port','path','fdname']
  for i in range(len(names)):
    table.attach(GtkLabel(names[i]), 0, 1, i, i+1,yoptions=0,xpadding=5,xoptions=0)
    table.attach(input[names[i]], 1, 2,i,i+1,yoptions=0,xpadding=5,xoptions=EXPAND|FILL)

  input['host'].entry.set_text(sg.config_get_value("host","clarens")[0])
  input['path'].entry.set_text(sg.config_get_value("path","clarens")[0])
  input['port'].entry.set_text(sg.config_get_value("port","clarens")[0])
  input['fdname'].entry.set_text(sg.config_get_value("fdname","clarens")[0])

  input['secure'] = GtkCheckButton(label="Use SSL encryption")

  connect_vbox.add(GtkHSeparator())
  connect_vbox.add(input['secure'])
    
  input['secure'].set_active(sg.config_get_value("secure","clarens"))

  hbox=GtkHBox()
  connect_vbox.set_spacing(0)
  connect_vbox.show_all()
  return connect_vbox


def clarens_init():
  params={
#These are compulsory
  "funcs":[init_page,build_object_page,plot_sheet_page,plot_col_page,
           download_selection_page,download_page2],
  "finish":finish_func,

#This is optional
  "labels":["Connection","Object selection","Worksheet","Column","Object selection","Download"],

#Some of the data we want to pass to out page constructor 
  "host":"localhost",
  "port":"80",
  "path":"/cgi-bin/DBServer",
  "fdname":"/home2/myoofd/ORCATEST.boot",
  "dbs":[],
  "dbsvr":0,
  "treepage":0,
  "frontpage":0,
  "tree_item":0,
  "db_label":"",
  "input": {'host': 0,
           'path': 0,
           'port': 0,
           'fdname': 0}
  }

  sg.config_register("host","clarens",set_def_host,commit_value)
  sg.config_register("path","clarens",set_def_path,commit_value)
  sg.config_register("port","clarens",set_def_port,commit_value)
  sg.config_register("fdname","clarens",set_def_fdname,commit_value)
  sg.config_register("secure","clarens",set_def_secure,commit_value)
  wizard=sgagtk.SGwizard(params)
  
  
if not sg:
  wizard=sgagtk.SGwizard(params,tabs=TRUE,modal=FALSE,title="Clarens remote analysis client")
  mainloop()
else:
 sg.register_plugin("CMS Demo","Plot:",clarens_init)

