#!/usr/bin/python
"""
Middle-Layer between Frontend (MainView) and CoCuMa_Client.
"""
#  Copyright (C) 2004  Henning Jacobs <henning@srcco.de>
#
#  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.
#
#  $Id: MainModel.py 82 2004-07-11 13:01:44Z henning $

from __version__ import __version__
from vcard import vCard 
from vcalendar import vEvent
#from Customers import Customers
import broadcaster
import broker
import debug
import CoCuMa_Client

class MainModel:
    "This is the middle-layer link between the various Frontends and Backends"
    def __init__(self):
        # self.client is None when not connected:
        self.client = None
        self.connection_type = 'none'
        self.connection_string = ''
        broker.UnRegister('Connection Type')
        broker.UnRegister('Connection String')
        broker.Register('Connection Type', lambda self=self: self.connection_type)
        broker.Register('Connection String', lambda self=self: self.connection_string)          
    def Open(self, con_type, con_str):
        "Connect to Backend Client"
        self.client = CoCuMa_Client.Instantiate(con_type)
        if self.client and self.client.Connect(con_str):
            self.connection_type = con_type
            self.connection_string = con_str
            broadcaster.Broadcast('Contacts', 'Opened')
            broadcaster.Broadcast('Journals', 'Opened')
        else:
            self.connection_type = 'none'
            self.connection_string = ''
            if self.client:
                errorstr = self.client.getErrorString()
            else: errorstr = ""
            self.client = None
            msgstr = "Connection to %s (%s) failed.\n%s" % (con_str, con_type, errorstr)
            debug.echo("MainModel.Open(): "+msgstr)
            broadcaster.Broadcast('Notification', 'Error', {'message':msgstr})
    def Close(self, final=0):
        "Disconnect from Backend"
        self.connection_type = 'none'
        self.connection_string = ''
        if self.client:
            self.client.Disconnect()
            self.client = None
            if not final:
                # 'final' signals that the application is shutting down,
                # therefore we don't broadcast in this case
                broadcaster.Broadcast('Contacts', 'Closed')
                broadcaster.Broadcast('Journals', 'Closed')
    def isConnected(self):
        return self.client is not None

#### The following Methods just call their Backend Equivalents:
                
    def GetContact(self, handle):
        if self.client:
            card = vCard(self.client.GetContact(handle))
            card.sethandle(handle)
            return card
        else: return None
    def PutContact(self, handle, data):
        ret = None
        if self.client:
            ret = self.client.PutContact(handle, data)
            broadcaster.Broadcast('Contact', 'Saved', {'handle':handle})
        return ret
    def NewContact(self, initdict={}):
        # initdict is a dictionary with initial values for the vcard
        # e.g. initdict={'fn':'New Untitled Card'}
        ret = None
        if self.client:
            ret = self.client.NewContact(initdict)
            broadcaster.Broadcast('Contact', 'Added', {'handle':ret})
        return ret
    def DelContact(self, handle):
        ret = None
        if self.client:
            ret = self.client.DelContact(handle)
            broadcaster.Broadcast('Contact', 'Deleted', {'handle':handle})
        return ret
    def ListHandles(self, sortby=""):
        if self.client:
            return self.client.ListHandles(sortby)
        else: return []
    def QueryAttributes(self, handles, attributes):
        if self.client:
            return self.client.QueryAttributes(handles, attributes)
        else: return []
        
    # Now the same with vEvent (we call it Journal here):
        
    def GetJournal(self, handle):
        if self.client:
            jour = vEvent(self.client.GetJournal(handle))
            jour.sethandle(handle)
            return jour
        else: return None
    def PutJournal(self, handle, data):
        ret = None
        if self.client:
            ret = self.client.PutJournal(handle, data)
            broadcaster.Broadcast('Journal', 'Saved', data={'handle':handle})
        return ret
    def NewJournal(self, initdict={}):
        # initdict is a dictionary with initial values for the vEvent
        # e.g. initdict={'summary':'Important Meeting'}
        ret = None
        if self.client:
            ret = self.client.NewJournal(initdict)
            datadict = {'handle':ret}
            datadict.update(initdict)
            broadcaster.Broadcast('Journal', 'Added', data=datadict)
        return ret
    def DelJournal(self, handle):
        ret = None
        if self.client:
            ret = self.client.DelJournal(handle)
            broadcaster.Broadcast('Journal', 'Deleted', {'handle':handle})
        return ret
    def ListJournalHandles(self, sortby=""):
        if self.client:
            return self.client.ListJournalHandles(sortby)
        else: return []
    def QueryJournalAttributes(self, handles, attributes):
        if self.client:
            return self.client.QueryJournalAttributes(handles, attributes)
        else: return []
        
