###############################################################################
# File:        guApp.py
# Appointment: application module
# Project:     GalaxyU
# Author:      AR
# History:
# 25.04.2019 guMaxMissileWHPercent returns double
# 10.10.2013 Added bombing support
# 31.01.2013 Added Report
# 11.05.2012 Created
###############################################################################
import zx
import zxLog
import wxTools
import pgTools
import guReport
import guStarMap

# Std modules
import os
import wx
import ctypes
import pygame
from ctypes import *

# Message used to refresh windows data
MESSAGE_REFRESH_DATA = "RefreshData"
MESSAGE_REFRESH_STAR_MAP_DATA = "RefreshStarMapData"

#------------------------------------------------------------------------------
# Returns app version string
def GetVersionStr():
    return "Version: 1.50.31.96 (25.04.2019)"


#==============================================================================
# Global application object
#==============================================================================
class CApplication(wx.App):
    # Location of system images
    DATA_BIN_PATH = "Data/bin/"
    IMAGES_PATH = DATA_BIN_PATH + "Images/"
    ICONS_PATH = IMAGES_PATH + "Icons/"
    PLANETS_DIR_NAME = DATA_BIN_PATH + "Planets"
    STARS_DIR_NAME = DATA_BIN_PATH + "Stars"

    # OtherImages index
    IMAGE_SMOKE = 0
    IMAGE_LASER_FLASH = 1

    #--------------------------------------------------------------------------
    def __init__(self):
        print "__________CApplication::INIT"
        # wx application
        self.wxApp = wx.App()

        # Load API
        self.API = ctypes.CDLL(os.path.join(os.getcwd(), "galaxyAPI." + 
                               ("dll" if zx.IsWindows() else "so")))
        
        # Set functions types
        
        self.API.guGetReportNation.restype = c_char_p
        self.API.guGetNationFlag.restype = c_char_p
        self.API.guGetShipComponentTypeName.restype = c_char_p
        self.API.guCalcComponentMass.restype = c_double
        self.API.guCalcShipTypeParam.restype = c_double
        self.API.guIsPeaceState.restype = c_bool
        self.API.guGetBattleSequence.restype = c_bool
        self.API.guImitateBattle.restype = c_bool
        self.API.guGetBombings.restype = c_bool
        self.API.guGetManagers.restype = c_bool
        self.API.guGetGroundBattles.restype = c_bool
        self.API.guGetGroundMiniBattle.restype = c_bool
        self.API.guExecuteCommands.restype = c_bool
        self.API.guGetShipParam.restype = c_double
        self.API.guMaxMissileWHPercent.restype = c_double
        self.API.guGetAPIVersion.restype = c_char_p
        self.API.guGetServerVersion.restype = c_char_p
        self.API.guGetSectorMarkStarGalaxyName.restype = c_char_p

        # Known ship component types
        self.ShipComponentTypes = {}
        for i in range(self.API.guGetLastKnownShipComponentType() + 1):
            self.ShipComponentTypes[i] = self.API.guGetShipComponentTypeName(i)

        # Config wrapper
        self.Config = zx.Config(self.API)
        if self.Config.GetItem("Trace.Redirect", "0") == "1":
            self.wxApp.RedirectStdio()
        
        # Report object
        self.__Report = None # cannot be created here (due to some init order)

        # Application star map
        self.__starMapView = None
        
        # Main frame window
        self.__MainFrame = None
        
        # Windows collection
        self.WindowsCollection = wxTools.CWindowsCollection()
        
        # Application log
        self.__Log = zxLog.CLog()

        
        # Collections of images
        #----------------------
        
        # Explosion
        self.ExplosionImages = pgTools.CImageCollection(self.IMAGES_PATH)
        for i in range(0, 5):
            self.ExplosionImages.Load('explosion' + str(i) + '.png');
                
        # Population images
        self.PopulationImages = pgTools.CImageCollection(self.IMAGES_PATH)
        for c in ["red", "white", "blue"]:
            self.PopulationImages.Load("population_" + c + ".png")
            
        # Other images
        self.OtherImages = pgTools.CImageCollection(self.IMAGES_PATH)
        self.OtherImages.Load("smoke.png")
        self.OtherImages.Load("laserflash.png")
        
        if not os.path.exists(self.PLANETS_DIR_NAME):
            os.makedirs(self.PLANETS_DIR_NAME)
        if not os.path.exists(self.STARS_DIR_NAME):
            os.makedirs(self.STARS_DIR_NAME)

    #---------------------------------------------------------------------------
    def Stop(self):
        print "__________CApplication::api shutdown"
        self.API.guShutDown() # shut down the API

    #---------------------------------------------------------------------------
    # Sets main frame window
    def SetMainWindow(self, aMainFrame):
        self.__MainFrame = aMainFrame
        
        
    #---------------------------------------------------------------------------
    # Returns main frame window
    def GetMainWindow(self):
        return self.__MainFrame
         
    #---------------------------------------------------------------------------
    def GetReport(self):
        if self.__Report is None:
            self.__Report = guReport.CReport(self.API)
        return self.__Report

    #--------------------------------------------------------------------------
    # Returns the star map
    def GetStarMap(self):
        if self.__starMapView is None:
            self.__starMapView = guStarMap.CMapViewFrame(self.__MainFrame)
        return self.__starMapView
        
    #--------------------------------------------------------------------------
    # Opens the star map
    def OpenStarMap(self):
        self.GetStarMap()
        # Because it can be destroyed after close action - try to show to be sure
        try:
            self.__starMapView.Show()
        except:
            # yes - object is invalid - set for recreation
            self.__starMapView = None
        self.GetStarMap()
        self.__starMapView.Show()
        self.__starMapView.Raise() # raise window to the top

    #---------------------------------------------------------------------------
    def CloseStarMap(self):
        if self.__starMapView is not None:
            # Here can be an exception if window was explicitly closed
            try:
                self.__starMapView.NeedVetoOnClose = False # reset veto to close it propery
                self.__starMapView.Close(force = True)
            except:
                pass
            self.__starMapView = None
            

    #---------------------------------------------------------------------------
    def RefreshStarMap(self):
        # Remove old map view - this will close all dependent windows
        self.CloseStarMap()
        self.WindowsCollection.CloseAll(); # to refresh collection
        # Open new map
        self.OpenStarMap()
        # Raise star map to front
        self.GetStarMap().Raise()

    #---------------------------------------------------------------------------
    # Log
    def Log(self, aSeverity, aMessage, aLevel = zxLog.LEVEL_NORMAL):
        self.__Log.Log(aSeverity, aMessage, aLevel)
        
    #---------------------------------------------------------------------------
    # Adds log target
    def AddLogTarget(self, aLogTarget):
        self.__Log.AddTarget(aLogTarget)
        
    #---------------------------------------------------------------------------
    # Returns a log object
    def GetLog(self):
        return self.__Log

    #---------------------------------------------------------------------------
    # Returns credentials cfg path
    def GetCredentialsCfgPath(self):
        return "LogInCredentials." + self.GetReport().NationName + "."

    #---------------------------------------------------------------------------
    # Returns user email from cfg
    def GetUserEmail(self):
        return self.Config.GetItem(self.GetCredentialsCfgPath() + "Email", "MyEmail@bbc.co.uk")

    #---------------------------------------------------------------------------
    # Returns user password from cfg
    def GetUserPassword(self):
        return self.Config.GetItem(self.GetCredentialsCfgPath() + "Password", "MyPassword")

#-------------------------------------------------------------------------------
Application = CApplication()
