def __init__(self):
     self.n = Configuration.getN()
     self.C = 0
     self.ID = Configuration.getMyID()
     self.dc = DataConn()
class WBAlgorithm:
   def __init__(self):
       self.n = Configuration.getN()
       self.C = 0
       self.ID = Configuration.getMyID()
       self.dc = DataConn()


   #def __printMatrix(self):
   #    for i in range(self.n):
   #        for j in range(self.n):
   #            logging.debug("%d %d = %d" %( i, j, self.matrix[i][j]))
   #        logging.debug("---")
  
   def addEvent(self, event):
       return
       #self.dc.updateTime(event.node, event.node,event.time)
       #self.dc.addLog(event.name,event.node,event.time,event.content)
       #@TODO put the new event into database
   
   def __hasRec(self, matrix, event, k):
       logging.debug("__hasRec: k=%d event.node=%d" %(k, event.node))
       return matrix[k][event.node] >= event.time
 
   #Prepare the message to be send to node k  
   def sendMsg2Node(self, nodek):
       #@TODO load log from database
       log = self.dc.getLogs(0,sys.maxint)
       NP = {} #partial log
       ES = {} #event lists
       matrix =  [[0 for _ in range(self.n) ] for _ in range(self.n)]
       for i in range(self.n):
           for j in range(self.n):
               matrix[i][j] = self.dc.getTime(i, j)
       for (id,name,time,content) in log:
           event = Event(id,name,time,content)
           if not self.__hasRec(matrix, event, nodek):
              ES[event.name] = (event.time, event.node, event.content)  
              logging.debug((event.time, event.node, event.content))
       NP["matrix"] = matrix
       NP["events"] = ES 
       NP["senderID"] = Configuration.getMyID() 
       NP["receiverID"] = nodek 
       logging.debug(json.dumps(NP))
       return json.dumps(NP)
 
   def receiveMsg(self, jsonMsg, node):
       logging.debug("Received Json: %s" % jsonMsg)
       #@TODO merge log in database
       data = json.loads(jsonMsg)
       m = data["matrix"]
       events = data["events"]
       recvConflictEvents= []

       #fetch from local database
       matrix =  [[0 for _ in range(self.n) ] for _ in range(self.n)]
       for i in range(self.n):
           for j in range(self.n):
               matrix[i][j] = self.dc.getTime(i, j)

       #events ranked by target node's lamport timestamp
       eventslist = [] 
       for key, value in events.iteritems():
           #value[0:3] is (event.time, event.node, event.content)  
           #               ele[0]      ele[1]      ele[2]
           eventslist.append((value[0], value[1], value[2], key))
       rankedevents = sorted(eventslist) 
       for ele in rankedevents:
                 #Event(name, node, time, content)
           event = Event(key, ele[1], ele[0], ele[2])
           if not self.__hasRec(matrix, event, self.ID):
                   if node.checkLocalConflict(ele[2]): 
                       recvConflictEvents.append(ele[2])

                   self.dc.addLog(ele[3],ele[1],ele[0],ele[2])
                   node.appOperation(ele[2]) #execute the operation
                   #we didn't change algorithm, but just records the conflicted events
        
       #NOTE: matrix should be updated AFTER above events has been executed.
       for j in range(self.n):
           matrix[self.ID][j] = max( matrix[self.ID][j], m[data["senderID"]][j]) 
       for j in range(self.n):
           for k in range(self.n):  
               matrix[j][k] = max( matrix[j][k], m[j][k]) 
       for i in range(self.n):
           for j in range(self.n):
               self.dc.updateTime(i, j, matrix[i][j])

       #After algorithm part, here we implement the conflict resolving
       #ALL events involved in conflicts should be deleted.
       if recvConflictEvents:
           resultDelList = [] 
           resultNodeList = [] 
           for conflictMsg in recvConflictEvents:
               logging.info("Found conflict events in Msg: %s\n" % conflictMsg)
               tmp_lists = conflictMsg.split("|")
               if len(tmp_lists)==6 and tmp_lists[0]=="add":
                   #add the name and participates
                   resultDelList.append("del|"+tmp_lists[1])
           return resultDelList
       else:
           return None

            

   def onAdd(self):
       #Insert an appointment
       #@TODO check conflict locally
       #
       pass 

   def onDelete(self):
       pass

   def notify(self):
       pass

   def onConflict(self):
       pass

   def onReceiveApp(self):
       pass

   def onRecover(self):
       pass
 
   def writeApp(self):
       pass
 
   def displayApp(self):
       pass