#!/usr/bin/env python
# -*- coding: utf-8 -*-

import threading
import Queue
import filedirtool
import xlrd
import os
import QueueObjs
import WarRun
import pkwarflog
import time
#import copy


from PKHero import PKHero
import Cmds_pb2


class PKWarT(threading.Thread):
    def __init__(self,t_name,usercaheTCID,threadmangert,warType = 1):#与用户线程池相同，每一个用户线程池绑一个PK战斗线程，当前PK战斗线程只处理自已的用户线程池中的PK战斗
        threading.Thread.__init__(self, name=t_name) 
        self.threadmangert = threadmangert                  #线程管理对象
        self.queuemangert = self.threadmangert.queumangert
        self.queueRequest = Queue.Queue(2000)
        self.queuemangert.saveThreadMailQueueWithName(t_name, self.queueRequest)    #保存PKWarT线程接收列队
        self.usercfName = self.threadmangert.userCacheFrontName + str(usercaheTCID)
        self.userCachTQuete = self.queuemangert.getThreadMailQueueWithName(self.usercfName)               #用户线程池接收列队
        
        #基础配置表
        self.configTables = self._getTables()
        
        self.upHeros = {}   #{上边英雄网络ID:英雄对象}
        self.downHeros = {} #{下边英雄网络ID:英雄对象}
        
        self.upWars = []        #上边战局[[出战英雄网络ID,出战英雄网络ID,..],[出战英雄网络ID,出战英雄网络ID,..],...]
        self.downWars = []      #下边战局[[出战英雄网络ID,出战英雄网络ID,..],[出战英雄网络ID,出战英雄网络ID,..],...]
        
        #战报数据
        self.csocket = None #请求战斗的客户端socket
        self.warAttackAccount = None        #请求战斗的攻击方
        self.warBeAttackAccount = None      #请求战斗的被攻击方
        self.warType = warType              #战斗类型1.军机处对战,2.风云争霸,3.帮战
        self.warData = []                   #战报数据
        self.middleWinData = []             #战局情况[[[1,2,...],[1,2,...]],[[1,2,...],[1,2,...]],[[1,2,...],[1,2,...]],...],1.战斗存活
        self.warMapPointtab = self.getConfigDataWithTableNameAndID('tab_warMap', self.warType)
        self.mapWidth = int(self.warMapPointtab['mapwidth'])
        self.allHeroCount = int(self.warMapPointtab['heroCount'])           #所以出战英雄数量
        self.onceWarCount = int(self.warMapPointtab['onceWarCount'])        #单次出战英雄数量
        
        #战斗过程数据
        self.upOnceWarHeros = []            #上方英雄数据
        self.downOnceWarHeros = []          #下方英雄数据
    
        
        #mysql
        self.warSaveAccounts = {}
        self.mysqlUnUsedQueues = {}
        mysqlqueue,mysqlname = self.threadmangert.getCanUseMysqlThreadForOther(self.getName()) #mysql数据请求，需要时再请求，不用时马上释放连接,所以这里不作请求#mysql请求线程名                     
        
        if mysqlqueue == None or mysqlname == None:
            print '错误:mysql线程请求错误,UserMangerT未请求到可用Mysql连接线程(UserMangerT)'
        self.mysqlUnUsedQueues[mysqlname] = mysqlqueue              #已请求到的未使用的mysql连接
        self.mysqlUsedQueues = {}                                   #正在使用的mysql连接
        self.mysqlRequests = {}                                     #mysql请求编号{account:mysqlname}
        
        self.userMysqlAsks = {}         #map:{account:askid}
        self.callBackFunc = {}          #mqp:{account:callbackFunc}
        
    
    def resetWarHero(self,herodatas,isRobot = False):#使用英雄数据初始化英雄对象,被攻击方是否是机器人
        #双方英雄数据{upheros:[PKHheroData,...],downheros:[PKHheroData,...]}
        if isRobot:
            pass
        else:#初始化战斗上下方英雄
            self.upHeros.clear()
            self.downHeros.clear()
            self.upWars = []        #上边战局[[出战英雄网络ID,出战英雄网络ID,..],[出战英雄网络ID,出战英雄网络ID,..],...]
            self.downWars = []      #下边战局[[出战英雄网络ID,出战英雄网络ID,..],[出战英雄网络ID,出战英雄网络ID,..],...]
            tmpupWar = []
            tmpdownWar = []
            for uhx in range(len(herodatas['upheros'])):
                heronidtmp = herodatas['upheros'][uhx].heroNID
                self.upHeros[heronidtmp] = PKHero(self,herodatas['upheros'][uhx],uhx,self.onceWarCount,pkwarflog.flog_upHero)
                if uhx%self.onceWarCount == 0:
                    if tmpupWar:
                        self.upWars.append(tmpupWar)
                    tmpupWar = [heronidtmp]
                    
                else:
                    tmpupWar.append(heronidtmp)
                    if uhx == len(herodatas['upheros']) - 1:
                        self.upWars.append(tmpupWar)
            for dhx in range(len(herodatas['downheros'])):
                heronidtmp = herodatas['downheros'][dhx].heroNID
                self.downHeros[heronidtmp] = PKHero(self,herodatas['downheros'][dhx],dhx,self.onceWarCount,pkwarflog.flog_downHero)
                if dhx%self.onceWarCount == 0:
                    if tmpdownWar:
                        self.downWars.append(tmpdownWar)
                    tmpdownWar = [heronidtmp]
                else:
                    tmpdownWar.append(heronidtmp)
                    if dhx == len(herodatas['downheros']) - 1:
                        self.downWars.append(tmpdownWar)
        self.initWarHero()
    def initWarHero(self):                      #初始化参战英雄
        self.warData = []                       #战报数据
        self.upOnceWarHeros = self.upWars.pop(0)
        self.downOnceWarHeros = self.downWars.pop(0)
        self.warStart()                         
    def warStart(self):                         #开始一场战斗
        uheros = []
        dheros = []
        for uh in self.upOnceWarHeros:
            uheros.append(self.upHeros[uh])
        for dh in self.downOnceWarHeros:
            dheros.append(self.downHeros[dh])
        warrun = WarRun.WarRun(self,uheros,dheros)
        warrun.start()
        print 'war start time:%f'%(time.time())
    def warEnd(self,wardata):#战斗结束
        warprodata =  Cmds_pb2.WarData()
        wardata.getProtobufWarData(warprodata)
        print warprodata
        print 'war end time:%f'%(time.time())
    def receiveMysqlRespone(self,mysqlobj):
        tmpkey = self.getName() + str(mysqlobj.account)
        self.callBackFunc[tmpkey](self.userMysqlAsks[tmpkey],mysqlobj) #返回数据库操作数据
    def receiveUserCacheTWarData(self,pkHeroDataObj):
        self.warAttackAccount = pkHeroDataObj.account
        self.warBeAttackAccount = pkHeroDataObj.beAccount
        self.warType = pkHeroDataObj.dataType
        self.csocket = pkHeroDataObj.csocket
        self.resetWarHero(pkHeroDataObj.data, isRobot = pkHeroDataObj.isRobot)
        
    def saveWarDataToMysql(self,askid,cmdstr1,cmdstrend):#保存战斗结果到数据库
        askkey = self.getName() + str(self.warAttackAccount)
        self.userMysqlAsks[askkey] = askid
        self.callBackFunc[askkey] = cmdstrend
        cmdstrs = [cmdstr1,cmdstrend]
        mysqlaskobj = QueueObjs.MysqlAskObj(askid,cmdstrs,5,self.warAttackAccount)
        if len(self.mysqlUnUsedQueues) > 0:
            mysqlname,mysqlqueue = self.mysqlUnUsedQueues.popitem()
            self.mysqlUsedQueues[mysqlname] = mysqlqueue
            self.mysqlRequests[self.warAttackAccount] = mysqlname                      
            queueobj = QueueObjs.QueueMangerObj(mysqlaskobj,QueueObjs.Flog_MysqlAskObj,self.getName(),mysqlname,True)
            #mysqlqueue.put(copy.deepcopy(queueobj))
            mysqlqueue.put(queueobj)
        else:
            mysqlqueue,mysqlname = self.threadmangert.getCanUseMysqlThreadForOther(self.getName())
            if mysqlqueue == None or mysqlname == None:
                print '错误:mysql线程请求错误,PKWarT未请求到可用Mysql连接线程(UserCacheT)'
            else:
                self.mysqlUsedQueues[mysqlname] = mysqlqueue
                self.mysqlRequests[self.warAttackAccount] = mysqlname
                queueobj = QueueObjs.QueueMangerObj(mysqlaskobj,QueueObjs.Flog_MysqlAskObj,self.getName(),mysqlname,True)
                #mysqlqueue.put(copy.deepcopy(queueobj))
                mysqlqueue.put(queueobj)
    #读取excel数据表到list
    def _getTables(self):
        tables = {}
        excelf = filedirtool.cur_file_dir() + os.sep + 'configTables' + os.sep + 'pkwarscheme.xlsx'
        xlrd.Book.encoding = "cp1252"
        wb = xlrd.open_workbook(excelf)
        for sheetName in wb.sheet_names():
            if len(sheetName) > 4 and sheetName[:4]=="tab_":#基础配置表
                sheet = wb.sheet_by_name(sheetName)
                tabtmp = {}
                tabcname = []
                for i in range(0,sheet.ncols):            
                    if sheet.cell(0,i).value=='':
                        nclows=i
                        break
                    else:
                        tabcname.append(str(sheet.cell(0,i).value))
                        nclows=sheet.ncols               
                for rownum in range(0,sheet.nrows):
                    if rownum > 3:
                        tmplines = {}
                        for nnumber in range(0,nclows):
                            tmplines[tabcname[nnumber]] = sheet.cell(rownum,nnumber).value
                        tabtmp[int(sheet.cell(rownum,0).value)] = tmplines
                tables[sheetName] = tabtmp
        return tables
    def getConfigDataWithTableNameAndID(self,tabName,confID):
        if self.configTables.has_key(tabName) and self.configTables[tabName].has_key(confID):
            return self.configTables[tabName][confID]
        else:
            return None
    def getConfigTableWithTableName(self,tabName):
        if self.configTables.has_key(tabName):
            return self.configTables[tabName]
        else:
            return None
    def run(self):
        while True:
            if not self.queueRequest.empty():
                queueobj = self.queueRequest.get_nowait()
                if self.mysqlUsedQueues.has_key(queueobj.fromTName):            #收到mysql发来数据
                    mysqlname = queueobj.fromTName
                    mysqlqueu = self.mysqlUsedQueues.pop(mysqlname)
                    if len(self.mysqlUnUsedQueues) > 1:
                        self.threadmangert.releasMysqlControlForThreadName(self.getName(),mysqlname)
                    else:
                        self.mysqlUnUsedQueues[mysqlname] = mysqlqueu
                    self.receiveMysqlRespone(queueobj.data)
                elif queueobj.fromTName == self.usercfName:#用户数据线程发来的战斗请求数据
                    self.receiveUserCacheTWarData(queueobj.data)

from ThreadManger import ThreadManger
#战斗线程测度
if __name__ == '__main__':
    tmanger = ThreadManger.GetInstance()
    testtname = tmanger.userCacheFrontName + str(122)
    queutest = Queue.Queue()
    tmanger.queumangert.saveThreadMailQueueWithName(testtname, queutest)    #保存PKWarT线程接收列队
    pkwarthread = PKWarT('pkwart',122,tmanger)   #(self,t_name,usercaheTCID,threadmangert,warType = 1):#与用户线程池相同，每一个用户线程池绑一个PK战斗线程，当前PK战斗线程只处理自已的用户线程池中的PK战斗
    pkqueue = tmanger.queumangert.getThreadMailQueueWithName('pkwart')
    
    pkHerodatas = {}
    upherodata1 = QueueObjs.PKHheroData(1,42001,10,1,1001,2,[])   #(self,heroNid,heroCid,herolevel,heroStar,pSkillCID,pSkillLevel,pEquipDatas):
    upherodata2 = QueueObjs.PKHheroData(2,42002,10,1,1001,2,[])   #(self,heroNid,heroCid,herolevel,heroStar,pSkillCID,pSkillLevel,pEquipDatas):
    upherodata3 = QueueObjs.PKHheroData(3,42003,10,1,1001,2,[])   #(self,heroNid,heroCid,herolevel,heroStar,pSkillCID,pSkillLevel,pEquipDatas):
    
    pkHerodatas['upheros'] = [upherodata1,upherodata2,upherodata3]
    
    downherodata1 = QueueObjs.PKHheroData(4,42001,10,1,1001,2,[])   #(self,heroNid,heroCid,herolevel,heroStar,pSkillCID,pSkillLevel,pEquipDatas):
    downherodata2 = QueueObjs.PKHheroData(5,42002,10,1,1001,2,[])   #(self,heroNid,heroCid,herolevel,heroStar,pSkillCID,pSkillLevel,pEquipDatas):
    downherodata3 = QueueObjs.PKHheroData(6,42003,10,1,1001,2,[])   #(self,heroNid,heroCid,herolevel,heroStar,pSkillCID,pSkillLevel,pEquipDatas):
    pkHerodatas['downheros'] = [downherodata1,downherodata2,downherodata3]
    pkheroobj = QueueObjs.PKHeroDataObj(pkHerodatas,1,'testup',100,'testdown',102,122,False)#(self,heroDatas,dataType,account,token,beAccount,beToken,cID,isRobot = False,csocket = None):
    queueojb = QueueObjs.QueueMangerObj(pkheroobj,QueueObjs.flog_pkHerosData,testtname,'pkwart')#(self,dat,datType,fromTName,toTName,isBack = False):
    pkqueue.put(queueojb)
    pkwarthread.setDaemon(True)
    pkwarthread.start()
    while True:
        pass