#! /usr/bin/python
from wxPython.wx import *
import mx.DateTime as mx

class MyFrame(wxFrame):
    def __init__(self, parent, id, title):
        wxFrame.__init__(self, parent, id, title,
                         wxPoint(100, 100), wxSize(240, 120))
        self.panel = MyPanel(self)
        self.CentreOnScreen()

        EVT_CLOSE(self,self.OnCloseWindow)
        
    def OnCloseWindow(self, event):
        self.Destroy()

class MyPanel(wxPanel):
    def __init__(self,frame):
        wxPanel.__init__(self,frame,-1)

        t1 = MyDateCtrl(self,-1,"",(10,20),(80,-1))
        t2 = wxTextCtrl(self,-1,"",(10,50),(80,-1))

        t1.SetFocus()

class MyDateCtrl(wxTextCtrl):
    def __init__(self,parent,id,val,pos,size):
        wxTextCtrl.__init__(self,parent,id,val,pos,size)

        EVT_SET_FOCUS(self,self.OnGotFocus)
        EVT_KILL_FOCUS(self,self.OnLostFocus)
        EVT_CHAR(self,self.OnChar)

    def OnGotFocus(self,evt):
        if self.GetValue() == '':
            self.SetValue('  /  /    ')
        self.SetInsertionPoint(0)
        self.SetSelection(-1,-1)
        self.pos = 0
        evt.Skip()

    def OnLostFocus(self,evt):
        if self.GetValue() == '  /  /    ':  # ) remove these lines
            self.SetValue('')                # ) if you want a blank
            evt.Skip()                       # ) entry to default to
            return                           # ) today's date
        date = self.GetValue().split('/')
        day = date[0].strip()
        if day == '':
            day = mx.now().day
        else:
            day = int(day)
        month = date[1].strip()
        if month == '':
            month = mx.now().month
        else:
            month = int(month)
        year = date[2].strip()
        now_year = mx.now().year
        if year == '':
            year = now_year
        elif len(year) == 2:
            century = int(now_year/100)*100
            year = int(year)+century
            if year - now_year > 50:
                year -= 100
            elif year - now_year < -50:
                year += 100
        else:
            year = int(year)
        try:
            date = mx.DateTime(year,month,day)
            self.SetValue('%02d/%02d/%04d' % (day,month,year))
        except mx.RangeError, error:
            print error.__str__()
        evt.Skip()

    def OnChar(self,evt):
        if evt.KeyCode() in (WXK_LEFT, WXK_RIGHT, WXK_HOME, WXK_END):
            if self.GetSelection() == (0,10):
                self.SetSelection(0,0)
            if evt.KeyCode() == WXK_LEFT:
                if self.pos > 0:
                    self.pos -= 1
                    if self.pos in (2,5):
                        self.pos -= 1
            elif evt.KeyCode() == WXK_RIGHT:
                if self.pos < 10:
                    self.pos += 1
                    if self.pos in (2,5):
                        self.pos += 1
            elif evt.KeyCode() == WXK_HOME:
                self.pos = 0
            elif evt.KeyCode() == WXK_END:
                self.pos = 10
            self.SetInsertionPoint(self.pos)
            return
        if evt.KeyCode() in (WXK_BACK, WXK_DELETE):
            if self.GetSelection() == (0,10):
                self.SetSelection(0,0)
            if evt.KeyCode() == WXK_BACK:
                if self.pos == 0:
                    return
                self.pos -= 1
                if self.pos in (2,5):
                    self.pos -= 1
            elif evt.KeyCode() == WXK_DELETE:
                if self.pos == 10:
                    return
            curr_val = self.GetValue()
            self.SetValue(curr_val[:self.pos]+' '+curr_val[self.pos+1:])
            self.SetInsertionPoint(self.pos)
            return
        if evt.KeyCode() in (WXK_TAB, WXK_RETURN) or evt.KeyCode() > 255:
            evt.Skip()
            return
        if self.pos == 10:
            wxBell()
            return
        ch = chr(evt.KeyCode())
        if ch not in ('0123456789'):
            wxBell()
            return
        if self.GetSelection() == (0,10):
            curr_val = '  /  /    '
        else:
            curr_val = self.GetValue()
        self.SetValue(curr_val[:self.pos]+ch+curr_val[self.pos+1:])
        self.pos += 1
        if self.pos in (2,5):
            self.pos += 1
        self.SetInsertionPoint(self.pos)

class MyApp(wxApp):
    def OnInit(self):
        frame = MyFrame(NULL, -1, "Customised date control")
        frame.Show(true)
        self.SetTopWindow(frame)
        return true

def run():
    app = MyApp(0)     # Create an instance of the application class
    app.MainLoop()     # Tell it to start processing events

if __name__ == '__main__':
    run()
