#!/usr/bin/python
# -*-python-*-
#
# tritium.py -- a keyboard driven window manager
#
# Copyright 2007,2008 Mike O'Connor <stew@vireo.org>
#
# Portions of code plagarized from plwm's panes.py which is
#    Copyright (C) 2001  Mike Meyer <mwm@mired.org>
#
# This program 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.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import sys

from plwm import wmanager, keys, inspect, \
     border, color, font, menu, cfilter,outline, focus
     
import logging
import tritium
import sys,os
from tritium import workspace,dock
from tritium.query import *
from tritium.submap import SubMap
import tritium.frame
from tritium.frame import title,frame,tab
from Xlib import XK 

log = logging.getLogger()

class TritiumMenuHandler(menu.MenuCharHandler):
    Any_Escape = C_g = menu.MenuKeyHandler._abort
    Any_Return = menu.MenuKeyHandler._do
    Any_space = Any_Down = C_n = menu.MenuKeyHandler._down
    Any_BackSpace = Any_Up = C_p = menu.MenuKeyHandler._up

class TritiumClient( wmanager.Client,
                     tritium.frame.FrameClient,
                     tritium.frame.tab.TabClient,
		     workspace.WorkspaceClient,
		     border.BorderClient,
		     tritium.frame.title.TitleClient,
                     tritium.dock.DockClient,
                     ):
    "Put the clients in a frame, with a border."
    border_default_width = 1
    border_color_name = 'White'
    border_focuscolor_name = 'White'

    def __init__(self, screen, window, maprequest):
        self.transient=False
        self.dockapp=False

        tritium.frame.FrameClient.__init__( self, screen, window, maprequest )
        wmanager.Client.__init__( self, screen, window, maprequest )

class LayoutScreen(object):
    def __screen_client_init__( self ):
        import layout
        self.layout = layout.TritiumLayout()

        method = "screen_%d" % self.number

        if layout.TritiumLayout.__dict__.has_key( method ):
            layout.TritiumLayout.__dict__[method]( self.layout, self )

class TritiumScreen( tritium.dock.DockScreen,
                     wmanager.Screen,
		     color.Color,
		     tritium.frame.title.TitleScreen,
                     LayoutScreen,
		     message.screenMessage,
		     tritium.tritiumScreen,
		     menu.screenMenu,
                     ):
    "And panes on the screen, and I'm going to want some menus."

    menu_handler = TritiumMenuHandler
    menu_bordercolor = "Red"
    message_bordercolor = "Blue"


class TritiumConfig(object):
    def __wm_screen_init__( self ):
        log.debug( "TritiumConfig.__wm_screen_init__" )
        # the directories we searce for keys.py and layout.py in reverse order:
        sys.path.insert( 0, "/etc/X11/tritium" )
        sys.path.insert( 0, "/etc/tritium/config" )
        sys.path.insert( 0, "/usr/local/etc/X11/tritium/config" )
        sys.path.insert( 0, "/usr/local/etc/tritium/config" )
        sys.path.insert( 0, os.path.join( os.getenv('HOME'), ".tritium" ), )
        sys.path.insert( 0, os.path.join( os.getenv('HOME'), ".config/tritium/config" ) )

    def __wm_init__( self ):
        "install the tritium key map"

        import keys
        keys.TritiumKeys(self)


        # TODO: this should be moved into a patch in debian/patches
        menufile='/var/lib/tritium/debian-menu.py'
        if os.path.isfile( menufile ):
            try:
                log.info( "loading menus from %s" % menufile )
                menus = open( menufile )
                exec menus in {'wm': self}
            except:
                log.error( "error loading menu file: %s: %s, %s" % (menufile, sys.exc_info()[0],sys.exc_info()[1] ))



class Tritium( wmanager.WindowManager,
               focus.SloppyFocus,
               font.Font,
               workspace.WorkspaceWindowManager,
               tritium.frame.FrameWindowManager,
               TritiumConfig,
               tritium.tritiumWindowManager,
               inspect.InspectServer,
               ):
    client_class = TritiumClient
    screen_class = TritiumScreen

    def restart( self ):
        """
        replace the current tritium process with a new one, this will
        allow us to reread the config files without having to restart
        X, but will have the annoying side-effect of repositioning
        winodws.  so there is obviosly room for improvement
        """
        executable = sys.argv[0]
        if sys.argv[0].find( '/' ):
            # it is a relative path, so run it from pwd
            executable = os.path.join( os.getcwd(), executable )

        log.info( "going to try to restart tritium by running execvp( %s )" % executable )
        os.execvp( executable, sys.argv[1:] )

if __name__ == '__main__':
    os.environ[ "DISPLAY" ] = ":0"

    level=logging.INFO
    # right now all we understand is -d for debug
    if len( sys.argv ) > 1:
        if( len( sys.argv ) == 2 ):
            o = sys.argv.pop() 
            if o == '-d':
                import contract
                contract.checkmod(tab)
                level=logging.DEBUG

            elif o == '-dd':
                import contract
                contract.checkmod(tab)
                level=logging.DEBUG
                wmanager.debug = wmanager.do_debug
            else:
                usage()
        else:
            usage()

    logging.basicConfig( level=level,
                         format='%(asctime)s %(levelname)s %(message)s',
                         stream = sys.stderr )

    wmanager.main(Tritium)
