#!/usr/bin/env python
import findrox; findrox.version(1, 9, 8)
import rox
from rox import g#, AppInfo
from rox.saving import *
from rox.loading import *
import os, os.path, re, math
from xml.dom.minidom import getDOMImplementation

_ = rox.i18n.translation(os.path.join(rox.app_dir, 'Messages'))

import AppInfo
FALSE = g.FALSE
TRUE = g.TRUE

ColorsDict = {'active_text_color'    : _('Text:'),  
              'active_border_color'  :  _('Border:'),
              'active_color_1'       :  _('Color 1:'),
              'active_shadow_1'      :  _('Shadow 1:'),
              'active_hilight_1'     :  _('Hilight 1:'),
              'active_color_2'       :  _('Color 2:'),
              'active_shadow_2'      :  _('Shadow 2:'),
              'active_hilight_2'     :  _('Hilight 2:'),
              'inactive_text_color'  :  _('Text:'),
              'inactive_border_color':  _('Border:'),
              'inactive_color_1'     :  _('Color 1:'), 
              'inactive_shadow_1'    :  _('Shadow 1:'),
              'inactive_hilight_1'   :  _('Hilight 1:'),
              'inactive_color_2'     :  _('Color 2:'), 
              'inactive_shadow_2'    :  _('Shadow 2:'),
              'inactive_hilight_2'   :  _('Hilight 2:')}

activeColors = ['active_text_color',  
                'active_border_color',
                'active_color_1',     
                'active_shadow_1',    
                'active_hilight_1',   
                'active_color_2',     
                'active_shadow_2',    
                'active_hilight_2']

inactiveColors = ['inactive_text_color',
                  'inactive_border_color',
                  'inactive_color_1',   
                  'inactive_shadow_1',  
                  'inactive_hilight_1', 
                  'inactive_color_2',   
                  'inactive_shadow_2',  
                  'inactive_hilight_2']
colors = []
colors.extend(activeColors)
colors.extend(inactiveColors)

        

class Window(rox.Window, Saveable, XDSLoader):
    def __init__(self, schemePath = None):
        rox.Window.__init__(self)
        XDSLoader.__init__(self, ['text/uri-list'])
        self.uri = schemePath
        
        self.modified = 0
        self.vbox = g.VBox()
        self.hbox = g.HBox()
        self.hbox.set_border_width(6)
        if schemePath != None and os.path.getsize(schemePath+'/schemerc') > 0:
            self.loadSchemeDir(schemePath)            
        else:
            self.scheme = self.loadScheme(rox.app_dir+'/schemerc')
            self.schemeName = 'NewScheme'
            self.appInfo = AppInfo.AppInfo()

        self.set_title(self.schemeName)

        self.colorFrames = self.frames()
        self.hbox.pack_start(self.colorFrames)

        bbox=g.Toolbar()
        bbox.set_style(g.TOOLBAR_ICONS)
        bbox.insert_stock(g.STOCK_CLOSE,_('Quit '),None,self.quit,'quit',-1)
        bbox.insert_stock(g.STOCK_SAVE,_('Save this scheme'),None,self.save,'save',-1)
        
        self.vbox.pack_start(bbox)
        self.vbox.pack_start(self.infos())
        self.vbox.pack_start(self.hbox)
        self.add(self.vbox)
        self.show_all()
    def loadSchemeDir(self, path):
        try:
            self.scheme = self.loadScheme(path+'/schemerc')
            self.schemeName = os.path.basename(path)
        except:
            rox.report_exception()
        #try:
        self.appInfo = AppInfo.AppInfo(path+'/AppInfo.xml')
        #except:
        #    self.appInfo = None

    def xds_load_from_file(self, path):
        self.loadSchemeDir(path)
        self.uri = path
        for cn, button in self.colorButtons.iteritems():
            button.set_str(self.scheme[cn])
            button.tooltip.set_tip(button, self.scheme[cn])

        box = self.aVbox
        pb = self.preview('a')
        for child in box.get_children():
            if str(type(child)).find("gtk.Image"):
                child.set_from_pixbuf(pb)
                break
        box = self.inaVbox
        pb = self.preview('ina')
        for child in box.get_children():
            if str(type(child)).find("gtk.Image"):
                child.set_from_pixbuf(pb)
                break
        name = self.appInfo.getSummary()
        author = self.appInfo.getAuthor()
        comments = self.appInfo.getComments()
        if name == "":
            name = self.schemeName
        self.infosList[0]['value'] = name
        self.infosList[1]['value'] = author
        self.infosList[2]['value'] = comments
        for info in self.infosList:
            info['entry'].set_text(info['value'])

    def infos(self):
        vbox = g.VBox()
        vbox.set_spacing(4)
        vbox.set_border_width(6)
        name = self.appInfo.getSummary()
        author = self.appInfo.getAuthor()
        comments = self.appInfo.getComments()
        if name == "": name = self.schemeName
        self.infosList = [{'name': _('Name:'),     'entry': g.Entry(), 'value': name},
                          {'name': _('Author:'),   'entry': g.Entry(), 'value': author},
                          {'name': _('Comments:'), 'entry': g.Entry(), 'value': comments}]
        for info in self.infosList:
            label = g.Label(info['name'])
            label.set_alignment(1.0,0.5)
            hbox = g.HBox(False,4)
            hbox.pack_start(label)
            info['entry'].set_text(info['value'])
            info['entry'].set_width_chars(30)
            info['entry'].connect('changed', self.entryChanged) 
            hbox.pack_start(info['entry'])
            vbox.pack_start(hbox)
        return vbox
    def entryChanged(self,widget):
        self.modified = 1
        self.set_title(self.schemeName+"*")
    def frames(self):
        aFrame   = g.Frame(_('Active window'))
        inaFrame = g.Frame(_('Inactive window'))
        self.aVbox    = g.VBox()
        self.inaVbox  = g.VBox()
        aFrame.add(self.aVbox)
        inaFrame.add(self.inaVbox)
        self.aVbox.set_spacing(4)
        self.inaVbox.set_spacing(4)
        self.aPreviewXpm = g.Image()
        self.aPreviewXpm.set_from_pixbuf(self.preview('a'))
        self.aVbox.pack_start(self.aPreviewXpm)
        self.inaPreviewXpm = g.Image()
        self.inaPreviewXpm.set_from_pixbuf(self.preview('ina'))
        self.inaVbox.pack_start(self.inaPreviewXpm)
        self.colorButtons = {}
        for cn in colors:
            label = g.Label(ColorsDict[cn])
            label.set_alignment(1.0,0.5)
            hbox = g.HBox(False,4)
            hbox.pack_start(label)

            button = ColorButt(cn,ColorsDict[cn])
            button.set_str(self.scheme[cn])
            button.connect('clicked', self.button_clicked)
            button.tooltip = g.Tooltips()
            button.tooltip.set_tip(button, self.scheme[cn])
            
            self.colorButtons[cn] = button
            hbox.pack_end(button, False, False, 4)
            if cn[0] == 'a':
                self.aVbox.pack_start(hbox)
            else:
                self.inaVbox.pack_start(hbox)
        box = g.HBox()
        box.set_spacing(6)
        box.pack_start(aFrame)
        box.pack_start(inaFrame)
        return box
    def expose(self, button, event):
        self.set_title(self.schemeName+"*")
        exColor = self.scheme[button.key]
        self.scheme[button.key]=button.get()
        button.tooltip.set_tip(button, button.get())
        if self.scheme[button.key] != exColor:
            if button.key[0] == 'a':
                box = self.aVbox
                pb = self.preview('a')
            else:
                box = self.inaVbox
                pb = self.preview('ina')
            for child in box.get_children():
                if str(type(child)).find("gtk.Image"):
                    child.set_from_pixbuf(pb)
                    break
    def save(self, widget, event):
        if not self.modified: return
        if self.uri == None:
            self.uri = self.schemeName
        self.savebox = SaveBox(self, self.uri, 'inode/directory')
        schemeIcon =  self.schemeIcon(self.scheme)
        self.savebox.set_type('inode/directory', schemeIcon)
        self.savebox.show()
        
    def quit(self, widget, event):
        import sys
        sys.exit(0)

    def button_clicked(self, widget):
        if str(type(widget)).find("Schemer.ColorButt"):
            widget.connect('expose-event', self.expose)
            self.modified = 1
    def svgSchemeIcon(self, scheme):
        try:
            f = open(rox.app_dir+'/icon-template.svg','r')
            svgTemplate = f.read()
            f.close
        except:
            rox.report_exception()
        for key, value in scheme.iteritems():
            svgTemplate = svgTemplate.replace('"'+key+'"','"'+value+'"')
            svgTemplate = svgTemplate.replace('fill:'+key+';','file:'+value+';')
        return svgTemplate
    def schemeIcon(self, scheme):
        svg = self.svgSchemeIcon(scheme)
        pbl = g.gdk.PixbufLoader('svg')
        pbl.write(svg, len(svg))
        pbl.close()
        return pbl
        
    def preview(self, state):
        xpmFile = open(rox.app_dir+'/preview.xpm')
        xpm = xpmFile.read()
        xpmFile.close()
        
        prefix = ''
        colorList = []
        if state == 'a':
            prefix = 'active_'
            colorList = activeColors
        else:
            prefix = 'inactive_'
            colorList = inactiveColors
        try:
            for cn in colorList:
                colorName = cn.replace(prefix,'')
                xpm = re.sub(r'"(.)\s+c (#\w{6}) s '+colorName+r'",',r'"\1\tc '+self.scheme[cn]+r'",',xpm)
        except:
            rox.report_exception()
        pbl = g.gdk.PixbufLoader('xpm')
        pbl.write(xpm, len(xpm))
        pbl.close()
        pb = pbl.get_pixbuf()
        return pb
        #preview = g.Image()
        #preview.set_from_pixbuf(pb)

        #pbl.close()
        #return preview
    def loadScheme(self, path):
        scheme = {}
        try:
            f = open(path,'r')
            key = ''
            for l in f.readlines():
                if l.strip():
                    try:
                        key, value = l.split('=')
                        for color in colors:
                            if color == key:
                                scheme[key]=value.strip()
                    except:
                        pass
            f.close()
        except:
            rox.croak(_('Could not open ')+path)
        return scheme
    def set_uri(self, uri):
        self.uri = uri
        self.modified = 0
        self.set_title(self.schemeName)
    def save_to_file(self, path):
        import shutil
        if not os.path.exists(path):
            os.mkdir(path)
        dirIcon = open(path+'/.DirIcon', 'w')
        dirIcon.write(self.svgSchemeIcon(self.scheme))
        dirIcon.close()
        if self.appInfo == None:
            appInfoFile = open(path+'/AppInfo.xml','w')
            appInfoFile.write("<AppInfo>\n</AppInfo>")
            appInfoFile.close()
            self.appInfo = rox.AppInfo.AppInfo(path+'/AppInfo.xml')
        self.appInfo.setSummary(self.infosList[0]['entry'].get_text())
        self.appInfo.setAuthor(self.infosList[1]['entry'].get_text())
        self.appInfo.setComments(self.infosList[2]['entry'].get_text())

        self.appInfo.write(path+'/AppInfo.xml')

        shutil.copy(rox.app_dir+'/LoadScheme',path+'/AppRun')
        schemerc = open(path+'/schemerc','w')
        #for key, value in self.scheme.iteritems():
        #    schemerc.write(key+'='+value+"\n")
        schemerc.write("# Colors for active state\n\n")
        for key in activeColors:
            schemerc.write(key+'='+self.scheme[key]+"\n")
        schemerc.write("\n# Colors for inactive state\n\n")
        for key in inactiveColors:
            schemerc.write(key+'='+self.scheme[key]+"\n")
            
        schemerc.close()
    def can_save_to_file(self):
        return Saveable.can_save_to_file(self)
class ColorButt(g.Button):
	def __init__(self, key, title):
		g.Button.__init__(self)
		self.c_box = g.EventBox()
		self.add(self.c_box)
		self.key = key
		self.title = title
		self.set_size_request(40, 20)
		self.dialog = None
		self.connect('clicked', self.clicked)
		self.connect('expose-event', self.expose)

	def expose(self, widget, event):
		self.c_box.window.draw_rectangle(
			self.c_box.style.bg_gc[g.STATE_NORMAL], True,
			0, 0, self.c_box.allocation.width, self.c_box.allocation.height)

	def set(self, c):
		self.c_box.modify_bg(g.STATE_NORMAL, c)

	def set_str(self, s):
		self.set(g.gdk.color_parse(s))
	def gColor_to_hex(self, c):		
		temp_hex = hex(int((float(c)/65535) * 255));
		if len(temp_hex) > 3:
			return temp_hex[-2:]
		else:
			return "0" + temp_hex[-1:]

	def get(self):
		c = self.c_box.get_style().bg[g.STATE_NORMAL]
                #print "red : " + str(c.red)
		return '#%s%s%s' % (self.gColor_to_hex(c.red), self.gColor_to_hex(c.green), self.gColor_to_hex(c.blue))

	def clicked(self, button):
		if self.dialog:
			self.dialog.destroy()

		def closed(dialog):
			self.dialog = None

		def response(dialog, resp):
			if resp != g.RESPONSE_OK:
				dialog.destroy()
				return
			self.set(dialog.colorsel.get_current_color())
			dialog.destroy()

		self.dialog = g.ColorSelectionDialog(self.title)
		self.dialog.set_position(g.WIN_POS_MOUSE)
		self.dialog.connect('destroy', closed)
		self.dialog.connect('response', response)

		c = self.c_box.get_style().bg[g.STATE_NORMAL]
		self.dialog.colorsel.set_current_color(c)
		self.dialog.show()
