##########################################################
# proTyres App definition by Jens Roos (Wergilius at AC forum)
#
# 2.0.0 200528
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# For GNU General Public License see <http://www.gnu.org/licenses/>.
######################################################################

import ac
from lib.proTyres_def import *

#debug window
class tyreDebugStats:
  def __init__(self,appWindow,x,y,cfg, pos):
    self.posX = x
    self.posY = y

    #indicator postion (actual tyre, LF,RF,LF,RR)
    self.lblTempLevels=ac.addLabel(appWindow,pos+":")
    ac.setPosition(self.lblTempLevels, x, y)
    ac.setCustomFont(self.lblTempLevels, "consolas", 0, 0)
    ac.setFontSize(self.lblTempLevels, cfg.FontSize+1)
    ac.setFontAlignment(self.lblTempLevels, "left")
    ac.setFontColor(self.lblTempLevels, *(cfg.AppTextColor))

    #all temp values
    self.lblTempLevels=ac.addLabel(appWindow,"000.0 - 000.0/000.0/000.0/000.0")
    ac.setPosition(self.lblTempLevels, x+cfg.FontSize*2, y)
    ac.setCustomFont(self.lblTempLevels, "consolas", 0, 0)
    ac.setFontSize(self.lblTempLevels, cfg.FontSize+1)
    ac.setFontAlignment(self.lblTempLevels, "left")
    ac.setFontColor(self.lblTempLevels, *(cfg.AppTextColor))

    #all grip levels
    self.lblGripLevels=ac.addLabel(appWindow,"000.0 - 000.0/000.0/000.0/000.0")
    ac.setPosition(self.lblGripLevels, x+cfg.FontSize*22, y)
    ac.setCustomFont(self.lblGripLevels, "consolas", 0, 0)
    ac.setFontSize(self.lblGripLevels, cfg.FontSize+1)
    ac.setFontAlignment(self.lblGripLevels, "left")
    ac.setFontColor(self.lblGripLevels, *(cfg.AppTextColor))

    #wear and dirt levels
    self.lblWearDirtLevels=ac.addLabel(appWindow,"100.0/00.0")
    ac.setPosition(self.lblWearDirtLevels, x+cfg.FontSize*42, y)
    ac.setCustomFont(self.lblWearDirtLevels, "consolas", 0, 0)
    ac.setFontSize(self.lblWearDirtLevels, cfg.FontSize+1)
    ac.setFontAlignment(self.lblWearDirtLevels, "left")
    ac.setFontColor(self.lblWearDirtLevels, *(cfg.AppTextColor))

  #update actual values
  def setLabelValue(self,cfg,tyre,ind):
    #if selected tyre has been validated and all related paramters found
    if tyre.isValid:
      nt = ""
      if ind.isNew:
        nt="|"
      ac.setText(self.lblTempLevels, fmt51(ind.TempAvg.Value)+" - "+fmt51(ind.TempAvg.Value)+"/"+fmt51(ind.TempIn.Value)+"/"+fmt51(ind.TempMid.Value)+"/"+fmt51(ind.TempOut.Value))
      ac.setText(self.lblGripLevels, fmt51(ind.GripAvg)+" - "+fmt51(ind.GripAvg)+"/"+fmt51(ind.GripIn)+"/"+fmt51(ind.GripMid)+"/"+fmt51(ind.GripOut))
      ac.setText(self.lblWearDirtLevels, nt+fmt51(ind.Wear.raw)+"/"+fmt41(ind.Dirty.raw))


#main window
class appMainWindow:
  def __init__(self):
    self.App = False
    self.Visible = 50
    self.Forced = False
    self.InfoVisible = False
    self.CfgVisible = False
    self.PbVisible = False
    self.bttnMode = 0
    self.bttnInfo = 0
    self.bttnCfg = 0
    
  #if debug is used, create window and labels  
  def createButtons(self,cfg,tyre,appName):

    bw=""
    if cfg.bwButton:
      bw="bw"

    #reminder, button positions is also set in function changeModeApp
    #create button if enabled
    if not cfg.DisableButton&DISPLAY:
      #display mode button
      self.bttnMode = ac.addButton(self.App,"")
      ac.setSize(self.bttnMode,cfg.BttnSize,cfg.BttnSize)
      ac.drawBorder(self.bttnMode, 0)
      #use suitble button when scaling
      if cfg.Scale<=1.0:
        ac.setBackgroundTexture(self.bttnMode,"apps/python/"+appName+"/img/mode10"+bw+".png")
      elif cfg.Scale<=1.5:
        ac.setBackgroundTexture(self.bttnMode,"apps/python/"+appName+"/img/mode15"+bw+".png")
      else:
        ac.setBackgroundTexture(self.bttnMode,"apps/python/"+appName+"/img/mode20"+bw+".png")
      ac.setBackgroundOpacity(self.bttnMode, 0)

      if cfg.DisplayMode[0]&COMPACT:
        ac.setPosition(self.bttnMode, 1, cfg.MainCmpHeight+2)
      else:
        #ac.setPosition(self.bttnMode, cfg.FontSpace, cfg.MainHeight-cfg.FontSize-cfg.FontSpace)
        ac.setPosition(self.bttnMode, 2, cfg.MainHeight+2)

    #create button if enabled     
    if not cfg.DisableButton&CONFIG:
      #if button is used with current settings
      if cfg.configMenu&OPEN==0:
        #config button
        self.bttnCfg = ac.addButton(self.App,"")
        ac.setSize(self.bttnCfg,cfg.BttnSize,cfg.BttnSize)
        ac.drawBorder(self.bttnCfg, 0)
        #use suitble button when scaling
        if cfg.Scale<=1.0:
          ac.setBackgroundTexture(self.bttnCfg,"apps/python/"+appName+"/img/setup10"+bw+".png")
        elif cfg.Scale<=1.5:
          ac.setBackgroundTexture(self.bttnCfg,"apps/python/"+appName+"/img/setup15"+bw+".png")
        else:
          ac.setBackgroundTexture(self.bttnCfg,"apps/python/"+appName+"/img/setup20"+bw+".png")
        ac.setBackgroundOpacity(self.bttnCfg, 0)

        x=0
        #check if display or config button is disabled
        if not cfg.DisableButton&DISPLAY:
          x+=1
        #config button
        if cfg.DisplayMode[0]&COMPACT:
          ac.setPosition(self.bttnCfg, 1+cfg.BttnSize*x+cfg.FontSpace*x, cfg.MainCmpHeight+2)
        else:
          #ac.setPosition(bttnCfg, cfg.FontSize*x+cfg.FontSpace*(x+1), cfg.MainHeight-cfg.FontSize-cfg.FontSpace)
          ac.setPosition(self.bttnCfg, 2+cfg.BttnSize*x+cfg.FontSpace*x, cfg.MainHeight+2)
        ac.setVisible(self.bttnCfg,1)

    #create button if enabled and eol     
    if not cfg.DisableButton&INFO and cfg.useEOL:
      #info button
      self.bttnInfo = ac.addButton(self.App,"")
      ac.setSize(self.bttnInfo,cfg.BttnSize,cfg.BttnSize)
      ac.drawBorder(self.bttnInfo, 0)
      #use suitble button when scaling
      if cfg.Scale<=1.0:
        ac.setBackgroundTexture(self.bttnInfo,"apps/python/"+appName+"/img/info10"+bw+".png")
      elif cfg.Scale<=1.5:
        ac.setBackgroundTexture(self.bttnInfo,"apps/python/"+appName+"/img/info15"+bw+".png")
      else:
        ac.setBackgroundTexture(self.bttnInfo,"apps/python/"+appName+"/img/info20"+bw+".png")
      ac.setBackgroundOpacity(self.bttnInfo, 0)

      if cfg.DisplayMode[0]&EXTEND:
        x=0
        #check if display or config button is disabled
        if not cfg.DisableButton&DISPLAY:
          x+=1
        if not cfg.DisableButton&CONFIG and not cfg.configMenu&OPEN:
          x+=1
        #info button
        if cfg.DisplayMode[0]&COMPACT+EXTEND==COMPACT+EXTEND:
          ac.setPosition(self.bttnInfo, 1+cfg.BttnSize*x+cfg.FontSpace*x, cfg.MainCmpHeight+2)
        else:
          #ac.setPosition(self.bttnInfo, cfg.FontSize*x+cfg.FontSpace*(x+1), cfg.MainHeight-cfg.FontSize-cfg.FontSpace)
          ac.setPosition(self.bttnInfo, 2+cfg.BttnSize*x+cfg.FontSpace*x, cfg.MainHeight+2)
        ac.setVisible(self.bttnInfo,1)
      else:
        ac.setVisible(self.bttnInfo,0)


#debug window
class appDebugWindow:
  def __init__(self):
    self.App = False
    self.Visible = 0

  #if debug is used, create window and labels  
  def createAppLabels(self,cfg,tyre,appName,ptv):
 
    #tyre debug window
    self.App = ac.newApp(appName+" debug")
    ac.drawBorder(self.App, 0)
    ac.setTitle(self.App, "")
    ac.setIconPosition(self.App, 0, -10000)
    ac.setSize(self.App, cfg.DebugWidth, cfg.DebugHeight)
    ac.setVisible(self.App, False)

    #debug top left position of text
    posX = 5*cfg.Scale
    posY = 3*cfg.Scale

    #debug car name
    self.lblCar = ac.addLabel(self.App,"CAR: "+tyre.Car)
    ac.setPosition(self.lblCar, posX, posY)
    ac.setCustomFont(self.lblCar, cfg.Font[0],cfg.Font[1],cfg.Font[2])
    ac.setFontSize(self.lblCar, cfg.FontSize)
    ac.setFontAlignment(self.lblCar, "left")
    ac.setFontColor(self.lblCar, *(cfg.AppTextColor))

    #debug tyre compound long
    self.lblCompound = ac.addLabel(self.App,"n/a")
    ac.setPosition(self.lblCompound, posX, posY+cfg.FontSize*1+cfg.FontSpace*1)
    ac.setCustomFont(self.lblCompound, cfg.Font[0],cfg.Font[1],cfg.Font[2])
    ac.setFontSize(self.lblCompound, cfg.FontSize)
    ac.setFontAlignment(self.lblCompound, "left")
    ac.setFontColor(self.lblCompound, *(cfg.AppTextColor))

    #debug tyre compound summary
    self.lblTyre = ac.addLabel(self.App,"n/a")
    ac.setPosition(self.lblTyre, posX, posY+cfg.FontSize*2+cfg.FontSpace*2)
    ac.setCustomFont(self.lblTyre, cfg.Font[0],cfg.Font[1],cfg.Font[2])
    ac.setFontSize(self.lblTyre, cfg.FontSize)
    ac.setFontAlignment(self.lblTyre, "left")
    ac.setFontColor(self.lblTyre, *(cfg.AppTextColor))

    #create labels for pressure offsets
    if not cfg.DisableButton&CONFIG:
      self.lblOffset = ac.addLabel(self.App,"n/a")
      ac.setPosition(self.lblOffset, posX, posY+cfg.FontSize*3+cfg.FontSpace*3)
      ac.setCustomFont(self.lblOffset, cfg.Font[0],cfg.Font[1],cfg.Font[2])
      ac.setFontSize(self.lblOffset, cfg.FontSize)
      ac.setFontAlignment(self.lblOffset, "left")
      ac.setFontColor(self.lblOffset, *(cfg.AppTextColor))

    if cfg.useEOL:
      #debug tyre eol summary
      self.lblEOL = ac.addLabel(self.App,"n/a")
      ac.setPosition(self.lblEOL, posX, posY+cfg.FontSize*4+cfg.FontSpace*4)
      ac.setCustomFont(self.lblEOL, cfg.Font[0],cfg.Font[1],cfg.Font[2])
      ac.setFontSize(self.lblEOL, cfg.FontSize)
      ac.setFontAlignment(self.lblEOL, "left")
      ac.setFontColor(self.lblEOL, *(cfg.AppTextColor))

      #debug driven distance
      self.lblEOLDist = ac.addLabel(self.App,"n/a")
      ac.setPosition(self.lblEOLDist, posX, posY+cfg.FontSize*5+cfg.FontSpace*5)
      ac.setCustomFont(self.lblEOLDist, cfg.Font[0],cfg.Font[1],cfg.Font[2])
      ac.setFontSize(self.lblEOLDist, cfg.FontSize)
      ac.setFontAlignment(self.lblEOLDist, "left")
      ac.setFontColor(self.lblEOLDist, *(cfg.AppTextColor))

      #debug pitbox
      self.lblPitBox = ac.addLabel(self.App,"n/a")
      ac.setPosition(self.lblPitBox, posX, posY+cfg.FontSize*6+cfg.FontSpace*6)
      ac.setCustomFont(self.lblPitBox, cfg.Font[0],cfg.Font[1],cfg.Font[2])
      ac.setFontSize(self.lblPitBox, cfg.FontSize)
      ac.setFontAlignment(self.lblPitBox, "left")
      ac.setFontColor(self.lblPitBox, *(cfg.AppTextColor))

    #debug labels for indicators
    #debug temp
    self.lblIndicator1 = ac.addLabel(self.App,"TEMP AVG - CORE/IN/MID/OUT")
    ac.setPosition(self.lblIndicator1, posX+cfg.FontSize*2, posY+cfg.FontSize*8+cfg.FontSpace*6)
    ac.setCustomFont(self.lblIndicator1, cfg.Font[0],cfg.Font[1],cfg.Font[2])
    ac.setFontSize(self.lblIndicator1, cfg.FontSize)
    ac.setFontAlignment(self.lblIndicator1, "left")
    ac.setFontColor(self.lblIndicator1, *(cfg.AppTextColor))

    #debug grip
    self.lblIndicator2 = ac.addLabel(self.App,"GRIP AVG - CORE/IN/MID/OUT")
    ac.setPosition(self.lblIndicator2, posX+cfg.FontSize*22, posY+cfg.FontSize*8+cfg.FontSpace*6)
    ac.setCustomFont(self.lblIndicator2, cfg.Font[0],cfg.Font[1],cfg.Font[2])
    ac.setFontSize(self.lblIndicator2, cfg.FontSize)
    ac.setFontAlignment(self.lblIndicator2, "left")
    ac.setFontColor(self.lblIndicator2, *(cfg.AppTextColor))

    #debug wear and dirty
    self.lblIndicator3 = ac.addLabel(self.App,"WEAR/DIRTY")
    ac.setPosition(self.lblIndicator3, posX+cfg.FontSize*42, posY+cfg.FontSize*8+cfg.FontSpace*6)
    ac.setCustomFont(self.lblIndicator3, cfg.Font[0],cfg.Font[1],cfg.Font[2])
    ac.setFontSize(self.lblIndicator3, cfg.FontSize)
    ac.setFontAlignment(self.lblIndicator3, "left")
    ac.setFontColor(self.lblIndicator3, *(cfg.AppTextColor))

    #proTyres version
    self.lblVersion = ac.addLabel(self.App,appName+" v"+ptv)
    ac.setPosition(self.lblVersion, cfg.DebugWidth-posX, posY)
    ac.setCustomFont(self.lblVersion, cfg.Font[0],cfg.Font[1],cfg.Font[2])
    ac.setFontSize(self.lblVersion, int(cfg.FontSize*0.9))
    ac.setFontAlignment(self.lblVersion, "right")
    ac.setFontColor(self.lblVersion, *(cfg.AppTextColor))

    #debug create indicators
    self.Tyre = [0,0,0,0]
    self.Tyre[0] = tyreDebugStats(self.App, posX, posY+cfg.FontSize*9+cfg.FontSpace*7, cfg, "LF")
    self.Tyre[1] = tyreDebugStats(self.App, posX, posY+cfg.FontSize*10+cfg.FontSpace*8, cfg, "RF")
    self.Tyre[2] = tyreDebugStats(self.App, posX, posY+cfg.FontSize*11+cfg.FontSpace*9, cfg, "LR")
    self.Tyre[3] = tyreDebugStats(self.App, posX, posY+cfg.FontSize*12+cfg.FontSpace*10, cfg, "RR")

  #update actual values
  def setLabelValue(self,cfg,tyre,tyreBox,tw,ld,pl,rt,at):
    ts=0
    for i in range(0,4):
      self.Tyre[i].setLabelValue(cfg, tyre, tyreBox[i])
      ts+=tyreBox[i].Wear.raw

    if tyre.isValid and not cfg.DisableButton&CONFIG:
      ac.setText(self.lblOffset, "OFFSETS: FRONT {:.0f}psi, REAR {:.0f}psi, REFERENCE {:.1f}°C (CURRENT READING AIR {}°C, ROAD {}°C)".format(
        tyre.OffsetPressure[0], tyre.OffsetPressure[1], tyre.SavedRoadTemp/10.0, at, rt))

    if tyre.isValid and cfg.useEOL:
      #debug compound summary labels      
      ac.setText(self.lblEOLDist, "DRIVEN DISTANCE/DYNAMIC GAIN: {:.1f}KM/{:.1f}% (HIGH {:.1f}% MID {:.1f}% LOW {:.1f}%)".format(tyre.eolBar.raw,tyre.eol[tyre.eolIdx].DynGain[0]*100,tyre.eol[tyre.eolIdx].DynGain[7]*100,tyre.eol[tyre.eolIdx].DynGain[5]*100,tyre.eol[tyre.eolIdx].DynGain[3]*100))
      if (tw>0):
        ld /= 1000
        ac.setText(self.lblEOL, "ESTIMATED: HIGH {:.0f} Laps ({:.0f}Km) MID {:.0f} Laps ({:.0f}Km) LOW {:.0f} Laps ({:.0f}Km) END {:.0f} Laps ({:.0f}Km) (x{:.1f})".format(
        tyre.eol[tyre.eolIdx].Levels[3]/tw/ld/tyre.eol[tyre.eolIdx].DynGain[7],tyre.eol[tyre.eolIdx].Levels[3]/tw/tyre.eol[tyre.eolIdx].DynGain[7], 
        tyre.eol[tyre.eolIdx].Levels[2]/tw/ld/tyre.eol[tyre.eolIdx].DynGain[5],tyre.eol[tyre.eolIdx].Levels[2]/tw/tyre.eol[tyre.eolIdx].DynGain[5], 
        tyre.eol[tyre.eolIdx].Levels[1]/tw/ld/tyre.eol[tyre.eolIdx].DynGain[3],tyre.eol[tyre.eolIdx].Levels[1]/tw/tyre.eol[tyre.eolIdx].DynGain[3],
        tyre.eol[tyre.eolIdx].Levels[0]/tw/ld/tyre.eol[tyre.eolIdx].DynGain[1],tyre.eol[tyre.eolIdx].Levels[0]/tw/tyre.eol[tyre.eolIdx].DynGain[1],tw))
        #tyre.eol[tyre.eolIdx].Km[-1]/tw/ld/tyre.eol[tyre.eolIdx].DynGain,tyre.eol[tyre.eolIdx].Km[-1]/tw/tyre.eol[tyre.eolIdx].DynGain,tw))
      else:
        ac.setText(self.lblEOL, "ESTIMATED EOL: TYRE WEAR IS OFF")

      if pl==0:
        ac.setText(self.lblPitBox,"")
      else:
        p=""
        if tyre.isInPit:
          p+=" (STOP)"
        if tyre.isInPitBox:
          p+=" (PITBOX)"
        if tyre.isNew&DIRECT:
          p+=" (SET)"
        ac.setText(self.lblPitBox,"PITLANE"+p+" w{:.4f} d{:.3f}".format(abs(ts-tyre.WearValue*4),getDeltaPos(tyre.PosPit)))
          

