#
#  $Id: Todo.py,v 1.2 1999/12/11 12:35:11 rob Exp $
#
#  Copyright 1998-1999 Rob Tillotson <robt@debian.org>
#  All Rights Reserved
#
#  Permission to use, copy, modify, and distribute this software and
#  its documentation for any purpose and without fee or royalty is
#  hereby granted, provided that the above copyright notice appear in
#  all copies and that both the copyright notice and this permission
#  notice appear in supporting documentation or portions thereof,
#  including modifications, that you you make.
#
#  THE AUTHOR ROB TILLOTSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
#  THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
#  AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
#  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
#  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
#  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
#  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE!
#
"""To Do List.
"""

__version__ = '$Id: Todo.py,v 1.2 1999/12/11 12:35:11 rob Exp $'

__copyright__ = 'Copyright 1998-1999 Rob Tillotson <robt@debian.org>'

import Pyrite
import Pyrite.Connector
from Pyrite import FLD_UNKNOWN, FLD_INT, FLD_BOOLEAN, FLD_STRING
from Pyrite import Blocks, _

import string, struct, time

class Connector(Pyrite.Connector.Connector):
    name = 'Todo'
    version = Pyrite.version
    author = Pyrite.author
    url = ''
    description = _("The built in todo list.")

    def __init__(self, *a, **kw):
	apply(Pyrite.Connector.Connector.__init__, (self,)+a, kw)
	self.default_name = 'ToDoDB'
	self.default_class = Database
	self.default_creator = 'todo'
	self.default_type = 'DATA'
	
    def classify(self, info={}):
	if info.get('type') == 'DATA' and info.get('creator') == 'todo':
	    return Database
	

_fields = {'due': (FLD_UNKNOWN, ''),
	   'priority': (FLD_INT, 0),
	   'complete': (FLD_BOOLEAN, 0),
	   'description': (FLD_STRING, ''),
	   'note': (FLD_STRING, '')
	   }

class Record(Blocks.Record):
    def __init__(self, *a, **kw):
	self.fields = _fields
	apply(Blocks.Record.__init__, (self,)+a, kw)

    def unpack(self, raw):
	self.raw = raw
	# Note: as with all date related stuff, potential timezone problems
	# lurk since the device doesn't keep track of one.
	due, pri = struct.unpack('>HB', raw[:3])
	raw = raw[3:]
	if due == 0xffff: self.data['due'] = None
	else:
	    d = ((due >> 9) + 4, # year
		 ((due >> 5) & 15), # month
		 due & 31, # mday
		 0, 0, 0, 0, 0, -1)
	    # normalize the time tuple, assuming it is already in local time;
	    # this basically just fills in the julian day, weekday, and dst
	    # flag.
	    self.data['due'] = time.localtime(time.mktime(d))

	if pri & 0x80:
	    self.data['complete'] = 1
	    self.data['priority'] = int(pri) & 0x7f
	else:
	    self.data['complete'] = 0
	    self.data['priority'] = int(pri)

	self.data['description'], raw = string.split(raw, '\0', 1)
	self.data['note'] = string.split(raw, '\0')[0]
	
    def pack(self):
	if not self.data['due']:
	    d = 0xffff
	else:
	    if self.data['due'][0] > 1900:
		d = (self.data['due'][0] - 1904) << 9
	    else:
		d = (self.data['due'][0] - 4) << 9
		
	    d = d | \
		(self.data['due'][1] << 5) | \
		self.data['due'][2]
	p = self.data['priority']
	if self.data['complete']: p = p | 0x80

	raw = struct.pack('>HB', d, p)
	raw = raw + self.data['description'] + '\0'
	raw = raw + self.data['note'] + '\0'
		
	self.raw = raw
	return self.raw

class AppBlock(Blocks.CategoryAppBlock):
    def __init__(self, *a, **kw):
	self.fields = { 'dirty': (FLD_BOOLEAN, 0),
			'sortByPriority': (FLD_BOOLEAN, 0)
			}
	apply(Blocks.CategoryAppBlock.__init__, (self,)+a, kw)

    def unpack(self, raw):
	self.raw = raw
	raw = Blocks.CategoryAppBlock.unpack(self, raw)
	self.data['dirty'] = int(struct.unpack('>H', raw[:2])[0])
	self.data['sortByPriority'] = int(struct.unpack('>B', raw[2:3])[0])

    def pack(self):
	raw = Blocks.CategoryAppBlock.pack(self)
	raw = raw + struct.pack('>HBb', self.data['dirty'],
				self.data['sortByPriority'],
				0)
	self.raw = raw
	return self.raw

class Database(Pyrite.Database):
    def __init__(self, *a, **kw):
	apply(Pyrite.Database.__init__, (self,)+a, kw)
	self.record_class = Record
	self.appblock_class = AppBlock


