#!/usr/bin/python

import dbGtk
import sys
import os

if not sys.modules.has_key('gtk'):
    import pygtk
    pygtk.require('1.2')

import gtk
import GtkExtra

if hasattr(gtk,'require'):
    gtk.require('1.2')

import string


default_join_rules=\
r"""%/%_%_id \3s/\3_id
tbl%/id% tbl\2s/id
%/%_%_id \3/id
%/%_%_id \2/\3_id
%/%_id \2/id
%_%/%_id \2/id
tbl%/id% tbl\2/\2id"""


class login_widget:
    #connection to the database
    db=None

    #strings
    thedbapi=None
    thehost="localhost"
    theuser=os.getenv('USER') or os.getenv('USERNAME') or \
             os.getenv('LOGIN') or ''
    thepasswd=""
    thedb=""

    try:
        f=open( (os.getenv('HOME') or '') + '/.my.cnf' )
        a=1
        while a:
            a=f.readline()
            if a[:12] == '[sql-editor]' or a[:7] == '[mysql]':
                while a:
                    a=f.readline()
                    if a and a[-1] == '\n' :
                        a=a[:-1]
                    b=a.split('=')[-1]
                    while b and b[0] == ' ':
                        b=b[1:]
                    while b and b[-1] == ' ':
                        b=b[:-1]
                    if a[:4] == 'user':
                        theuser=b
                    if a[:4] == 'pass':
                        thepasswd=b
                    if a and a[0] == '[':
                        break
    except IOError:
        pass

    field_entrywidget={}
    
    def __init__(self):
        #while db ==None:
        window=gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
        window.set_title("sql editor")
        v=gtk.GtkVBox()
        v.show()
        window.add(v)

        self.b1=gtk.GtkRadioButton(None,"MySQL")
        self.b1.show()
        v.pack_start(self.b1)
        self.b2=gtk.GtkRadioButton(self.b1,"PostgreSQL")
        self.b2.show()
        v.pack_start(self.b2)
        
        
        for i in [ 'host','user','passwd','db']:
            h=gtk.GtkHBox()
            v.pack_start(h)
            h.show()
            l=gtk.GtkLabel(i)
            l.show()
            h.pack_start(l)
            e=gtk.GtkEntry()
            e.show()
            if i == 'passwd':
                e.set_visibility(gtk.FALSE)
            h.pack_start(e)
            var=getattr(self, "the" + i)
            e.set_text(var)
            self.field_entrywidget[i]=e

        b=gtk.GtkButton("CONNECT")
        b.show()
        b.connect("clicked", self.dbconnect)
        v.pack_start(b)

        self.statusbar=s=gtk.GtkStatusbar()
        s.show()        
        v.pack_start(s)

        s.push(1,"""warning: this programs is very young\n\
do not edit valuable data with it""")

        window.connect("delete_event", gtk.mainquit)
        window.show()
        self.window=window
    def dbconnect(self,button):

        for i in [ 'host','user','passwd','db']:
            e=self.field_entrywidget[i]
            setattr(self, "the" + i, e.get_text())

        if self.b1.get_active():
            self.thedbapi="MySQLdb"
        else:
            self.thedbapi="PgSQL"
            
        try:
            (dbapi,dbapi_exceptions)=dbGtk.load_dbapi(self.thedbapi)
            if self.b1.get_active():
                #connect
                self.db = dbapi.connect(host=self.thehost, user=self.theuser,
                                        #THIS IS A MISTAKE in MySQLdb
                                        passwd=self.thepasswd)
            else:
                self.db = dbapi.connect(host=self.thehost, user=self.theuser,
                                        password=self.thepasswd)
            self.db.select_db(self.thedb)
        except ImportError, msg:
            self.statusbar.push(1,str(msg)+
                                '\n(you should install the Debian package python-'+
                                self.thedbapi.lower()+' )')
        except Exception, msg:
            self.statusbar.push(1,str(msg))
        else:
            gtk.mainquit()


login=login_widget()

gtk.mainloop()



login.window.destroy()


if login.db :
    (dbapi,dbapi_exceptions)=dbGtk.load_dbapi(login.thedbapi)

class table_browser:
    #tables infos
    #table_info={}
    #fields in tables
    table_fields={}
    
    def __init__(self,db,thedb):
        db.select_db(thedb)

        window=gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
        window.set_title("sql:/"+login.thedb)
        v=gtk.GtkVBox(spacing=3)
        v.show()
        window.add(v)
        
        #for joins
        self.fj=gtk.GtkFrame('config joins')
        #self.fj.show()        
        self.vj=gtk.GtkVBox()
        h=gtk.GtkHBox()
        h.show()
        l=gtk.GtkLabel("Join rules:")
        l.show()
        h.pack_start(l)
        b=gtk.GtkButton("(help)")
        b.show()
        b.connect("clicked",self.help)
        h.pack_start(b)
        self.vj.pack_start(h)
        self.entry_widget = e = gtk.GtkText()
        e.show()
        e.set_editable(gtk.TRUE)
        #self.entry_widget.delete_text(0, self.entry_widget.get_length())
        e.insert_defaults(default_join_rules)
        self.vj.pack_start(e)
        self.vj.show()
        self.fj.add(self.vj)
        
        mf = GtkExtra.MenuFactory()
        mf.add_entries([
            ('File/config joins', None, self.fj.show ),
            ('File/-', None, None),
            ('File/Quit', None, gtk.mainquit ),
            #('Form/Save template', None,  self.gtk_form_save),
            #('Form/Load form',       None,         self.gtk_form_load),
            #('Form/Paste form',       None,         self.gtk_form_paste)
            ('Help/on joins', None, self.help)
            ])
        # activate key bindings ...
        #self.add_accel_group(mf.accelerator)
        #self.mf = mf
        #returnmf
        mf.show()
        v.pack_start(mf,gtk.FALSE,gtk.FALSE,gtk.FALSE)
    
        c=db.cursor()        
        c.execute('SHOW TABLES')
        tables=[]
        t=c.fetchone()        
        while t:
            tables.append(t[0])
            t=c.fetchone()
        del c

        for t in tables:
            info=dbGtk.table_info(login.db, login.thedb, t)
            #self.table_info[t]=info
            self.table_fields[t]=info.fields
            
            h=gtk.GtkHBox()
            v.pack_start(h,gtk.FALSE,gtk.FALSE,gtk.FALSE)
            h.show()
            
            b=gtk.GtkButton("Edit")
            b.table_name=t[0]
            b.show()
            b.connect('clicked',self.edit_table,t)
            h.pack_start(b,gtk.FALSE,gtk.FALSE,gtk.FALSE)
            
            l=gtk.GtkLabel(t)
            l.show()
            h.pack_start(l)
            
            
        
        v.pack_start(self.fj)


        ## h=gtk.GtkHandleBox()
##         h.show()
##         def deta(_h,w,h=h):
##             if hasattr(h,'set_size_request'):
##                 h.set_size_request(300,600)
##             else:
##                 h.set_usize(-1,600)
##         def atta(_h,w,h=h):
##             if hasattr(h,'set_size_request'):
##                 h.set_size_request(0,0)
##             else:
##                 h.set_usize(-1,20)
##         h.connect('child-detached',deta)
##         h.connect('child-detached',atta)
        
        f=gtk.GtkFrame('logs')
        f.show()
        
        scrolled_win = gtk.GtkScrolledWindow()
        scrolled_win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrolled_win.show()
        self.list = gtk.GtkList()
        self.list.set_selection_mode(gtk.SELECTION_MULTIPLE)
        self.list.set_selection_mode(gtk.SELECTION_BROWSE)
        scrolled_win.add_with_viewport(self.list)
        self.list.show()

        f.add(scrolled_win)
        #h.add(f)
        v.pack_start(f)
        
        window.connect("delete_event", gtk.mainquit)
        window.show()
        self.window=window

    def main_log(self, level,text):
        list_item = gtk.GtkListItem(text)
        list_item.show()
        self.list.add(list_item)

    def help(self,b):
        window=gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
        window.set_policy(gtk.FALSE, gtk.TRUE, gtk.FALSE)
        window.set_title("sql-editor join help")
        #window.connect("delete_event", window.destroy)
        e=gtk.GtkText()
        e.show()
        e.set_editable(gtk.TRUE)
        e.insert_defaults(dbGtk.joins.__doc__)
        #FIXME: this is ignored...
        #e.set_usize(180,180)
        window.add(e)
        window.set_usize(580,580)
        window.show()

    def edit_table(self,b,name):
        l=self.entry_widget.get_length()
        t=self.entry_widget.get_chars(0,l)
        join_rules=string.split(t,'\n')

        (dbapi,dbapi_exceptions)=dbGtk.load_dbapi(login.thedbapi)
        dbGtk.editor(login.db, login.thedb, name,
                     #api
                     dbapi,dbapi_exceptions,
                     #this is for logging in the main window
                     self.main_log,
                     #these are used for automatic joins
                     join_rules, self.table_fields
                     )

        


if login.db :
    browser=table_browser(login.db,login.thedb)
    gtk.mainloop()
