import wx
from ObjectAttrValidator import *
from SurgicalLogClasses import *

###############################################################################
# Validators for data flow through dialogs
###############################################################################
        
class intValidator(wx.PyValidator):
    def __init__(self):
        wx.PyValidator.__init__(self)
        self.Bind(wx.EVT_CHAR, self.OnChar)

    def Clone(self):
        return intValidator()

    def Validate(self, win):
        tc = self.GetWindow()
        val = tc.GetValue()
        
        for x in val:
            if x not in string.digits:
                return False

        return True

    def OnChar(self, event):
        key = event.GetKeyCode()

        if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
            event.Skip()
            return

        if chr(key) in string.digits:
            event.Skip()
            return

        if not wx.Validator_IsSilent():
            wx.Bell()

        # Returning without calling even.Skip eats the event before it
        # gets to the text control
        return
    
    def TransferToWindow(self):
        """
        Transfer data from validator to window.
        The default implementation returns False, indicating that an error
        occurred.  We simply return True, as we don't do any data transfer.
        """
        return True # Prevent wxDialog from complaining.
    
    def TransferFromWindow(self):
        """
        Transfer data from validator to window.
        The default implementation returns False, indicating that an error
        occurred.  We simply return True, as we don't do any data transfer.
        """
        return True # Prevent wxDialog from complaining.

class ObjectAttrDateValidator(ObjectAttrValidator):
    def __init__( self, *args, **kwargs ):
        """ Standard constructor. """
        super(ObjectAttrDateValidator,self).__init__( *args, **kwargs )
    
    def Validate( self, win ):
        """
        Validate the contents of the given control.
        
        Default behavior: Anything goes.
        """
        wgt = self.GetWindow()
        flValid = True
        val = self._getControlValue()
        if self.flRequired and not val.IsOk():
            flValid = False
        if flValid and self.formatter:
            flValid = self.formatter.validate( val )
        if self.validationCB:
            self.validationCB( self.obj, self.attrName, val, self.flRequired, flValid )
        
        if not flValid:
            if not self.IsSilent():
                wx.Bell()
            wgt.SetFocus()
            wgt.SetBackgroundColour(wx.Colour(200,50,50))
        else:
            wgt.SetBackgroundColour(wx.NullColour)
            
        return flValid
    
    def TransferToWindow( self ):
        """
        Transfer data from validator to window.
        
        Delegates actual writing to destination widget to subclass
        via _setControlValue method.
        """
        if self.obj == None:
            # Clear the widget
            wgt = self.GetWindow()
            wgt.Clear()
            return True
        
        # Default behavior otherwise
        return super(ObjectAttrDateValidator,self).TransferToWindow()
    
    
    def _setControlValue( self, value ):
        """
        Set the value of the TextCtrl.
        """
        wgt = self.GetWindow()
        wgt.SetValue( value )
    
    
    def _getControlValue( self ):
        """
        Return the value from the TextCtrl.
        """
        wgt = self.GetWindow()
        return wgt.GetValue()

class ObjectAttrBellTextValidator(ObjectAttrTextValidator):
    def __init__( self, *args, **kwargs ):
        """ Standard constructor. """
        super(ObjectAttrBellTextValidator,self).__init__( *args, **kwargs )
    
    def Validate( self, win ):
        #call the parent function
        flValid = super(ObjectAttrBellTextValidator,self).Validate(win)
        
        wgt = self.GetWindow()
        if not flValid:
            if not self.IsSilent():
                wx.Bell()
            wgt.SetFocus()
            wgt.SetBackgroundColour(wx.Colour(200,50,50))
        else:
            wgt.SetBackgroundColour(wx.NullColour)
            
        return flValid

class ObjectAttrSpinValidator( ObjectAttrTextValidator ):
    """
    Validator for TextCtrl widgets.
    """
    def __init__( self, *args, **kwargs ):
        """ Standard constructor. """
        super(ObjectAttrTextValidator,self).__init__( *args, **kwargs )
    
    def Validate( self, win ):
        return True

class mouseSexFormater():
    def __init__(self):
        return None
    
    def format(self, stored_value):
        """ Format a value for presentation. """
        if stored_value == 0:
            return "male"
        else:
            return "female"
        
    def coerce(self, presentation_value):
        """ Convert a presentation-formatted value
            to a storage-formatted value (may include
            type conversion such as string->integer).
        """
        if presentation_value == "male":
            return 0
        else:
            return 1
        
    def validate(self, presentation_value):
        """ Validate a presentation-formatted value.
            Return True if valid or False if invalid.
        """
        return True
    
class drugListValidator(wx.PyValidator):
    def __init__(self, obj, attr, flRequired=True):
        wx.PyValidator.__init__(self)
        self.obj = obj
        self.attr = attr
        self.required = flRequired
    
    def Clone(self):
        return drugListValidator(self.obj,self.attr,self.required)
    
    def Validate(self, parent):
        wgt = self.GetWindow()
        flValue = True
        if self.required and wgt.GetCount()==0:
            flValue = False
            wx.MessageBox("You must provide at least one drug!","Error",style=wx.ICON_ERROR)
        return flValue
    
    def TransferToWindow(self):
        wgt = self.GetWindow()
        wgt.Clear()
        drugList = getattr(self.obj, self.attr)
        for drug in drugList:
            wgt.Append(drug.printForList())
        return True
    
    def TransferFromWindow(self):
        wgt = self.GetWindow()
        drugList = []
        for item in wgt.GetItems():
            drugName = ""
            drugDose = 0
            drugTuple = item.partition("|")
            if drugTuple[1]=="":
                #the string did not contain |
                return False
            else:
                drugName = drugTuple[0].strip()
                drugDose = int(drugTuple[2].replace(" uL","").strip(),10)
                drugList.append(drugClass(name=drugName,dose=drugDose))
        setattr(self.obj, self.attr, drugList)