###############################################################################
# File:        UnitTest_guReport.py
# Appointment: unittests for guReport module 
# Project:     
# Author:      AR
# History:
# 19.14.2014 Created
###############################################################################
import unittest
import sys, os
import pygame

sys.path.append("../")

import guApp
import guListView
import guReport

import guShipsView
import guFleetsView
import guBombingView
import guGBView
import guBattleListView
import guStarsListView
import guTransportOrdersListView
import guProdOrdersListView
import guRatingListView
import guKnownNationsListView
import guReportMessagesListView
import guSciencesListView
import guMoneyTransactionsListView
import guAutoManagersListView
import guSpaceGroupsListView
import guShipCalc

from ctypes import *

# Typical report file
REPORT_FILE = "Federation__turn_00033.txt" # renamed in txt to be saved by SS

# Select report path depending where the test is called from
REPORT_PATH_FROM_GUI = "UnitTests/" + REPORT_FILE # from GUI dir
REPORT_PATH_FROM_GALAXYU = "Client/GUI/UnitTests/" + REPORT_FILE # from galaxy project dir
REPORT_PATH = (REPORT_PATH_FROM_GUI if not os.path.exists(REPORT_PATH_FROM_GALAXYU)\
               else REPORT_PATH_FROM_GALAXYU) if not os.path.exists(REPORT_FILE) else REPORT_FILE

REPORT_NATION = "Federation"
REPORT_TURN = 33
    

###############################################################################
class Test_guReport(unittest.TestCase):
    #--------------------------------------------------------------------------
    @classmethod
    def setUpClass(cls):
        cls.__report = guApp.Application.GetReport()
        cls.__report.Load(c_char_p(REPORT_PATH))
        pygame.init()

    #--------------------------------------------------------------------------
    def test_ReportParams(self):
        self.assertTrue(self.__report is not None)
        self.assertEqual(REPORT_NATION, self.__report.NationName)
        self.assertEqual(REPORT_TURN, self.__report.Turn)
        self.assertEqual(REPORT_PATH, self.__report.FileName)
        self.assertTrue(not self.__report.IsGM())

    #--------------------------------------------------------------------------
    def test_GetGrayingKoef(self):
        self.assertEqual(1.5, guReport.GetGrayingKoef(True))
        self.assertEqual(2, guReport.GetGrayingKoef(False))

    #--------------------------------------------------------------------------
    def test_FadeColour(self):
        self.assertEqual((255, 255, 255), guReport.FadeColour((255, 255, 255), 1)) # no change: k==1
        self.assertEqual((127, 127, 127), guReport.FadeColour((255, 255, 255), 2))
        self.assertEqual((5, 2, 1), guReport.FadeColour((10, 4, 2), 2))
        self.assertEqual((2, 1, 0), guReport.FadeColour((5, 2, 0), 2))

    #--------------------------------------------------------------------------
    def test_GetNationColour(self):
        self.assertEqual(self.__report.NATION_COLOUR, self.__report.GetNationColour(REPORT_NATION))
        self.assertEqual(self.__report.NATION_COLOUR, self.__report.GetNationColour(REPORT_NATION, False))
        self.assertEqual(\
            guReport.FadeColour(self.__report.NATION_COLOUR, 2),
            self.__report.GetNationColour(REPORT_NATION, True))

    #--------------------------------------------------------------------------
    def test_PeaceState(self):
        self.assertTrue(self.__report.IsInPeace(REPORT_NATION))
        self.assertTrue(self.__report.IsStatePeace(REPORT_NATION, REPORT_NATION))
        self.assertFalse(self.__report.IsStatePeace(REPORT_NATION, 'some nation'))
        self.assertEqual('', self.__report.GetDiplomaticState(REPORT_NATION))
        
    #--------------------------------------------------------------------------
    def test_KnownNations(self):
        enemiesCounter = 0
        for kn in self.__report.KnownNations:
            self.assertEqual(REPORT_NATION, kn.NationName) # supposed to be report nation here 
            if not self.__report.IsInPeace(kn.KnownNationName):
                self.assertEqual(self.__report.ENEMY_COLOUR, self.__report.GetNationColour(kn.KnownNationName))
                self.assertEqual('war', self.__report.GetDiplomaticState(kn.KnownNationName))
                enemiesCounter += 1
                
        self.assertTrue(enemiesCounter > 0) # it must be at least one enemy

    #--------------------------------------------------------------------------
    def test_Stars(self):
        self.assertTrue(len(self.__report.VisibleStars) > 0)
        countOwn = countKnown = 0
        colourChecked = False
        for star in self.__report.VisibleStars:
            if star.IsOwn():
                countOwn += 1
                self.assertFalse(star.IsKnown()) # should not be known
                self.assertFalse(star.IsActualKnown()) # should not be known
                self.assertTrue(star.IsInvestigated())
                self.assertEqual(REPORT_NATION, star.GetOwner())
                self.assertEqual(REPORT_TURN, star.CalcLastReportedAgo())
                self.assertTrue(star.CalcActivePopulation() > 0)
                self.assertEqual(self.__report.NATION_COLOUR, self.__report.GetStateColour(star))
            elif star.IsKnown():
                countKnown += 1
                self.assertFalse(star.IsOwn()) # should not be own
                self.assertTrue(star.IsActualKnown() == (star.LastKnownAt == REPORT_TURN))
                self.assertTrue(star.IsInvestigated())
                if star.CalcActivePopulation() > 0: #inhabited
                    owner = star.GetOwner()
                    self.assertTrue(owner != "")
                    self.assertTrue(owner != REPORT_NATION)
                    if self.__report.IsInPeace(owner):
                        self.assertEqual(guReport.FadeColour(\
                            self.__report.NEUTRAL_COLOUR, guReport.GetGrayingKoef(star.IsActualKnown())),
                            self.__report.GetStateColour(star))
                    else:
                        self.assertEqual(guReport.FadeColour(\
                            self.__report.ENEMY_COLOUR, guReport.GetGrayingKoef(star.IsActualKnown())),
                            self.__report.GetStateColour(star))
                    colourChecked = True
                else:
                    self.assertEqual("", star.GetOwner())
        self.assertTrue(countOwn > 0)
        self.assertTrue(countKnown > 0)
        self.assertTrue(colourChecked)

    #--------------------------------------------------------------------------
    def test_GetJoiningFleetFromAssignment(self):
        self.assertEqual("", guReport.CReport.GetJoiningFleetNameFromAssignment(""))
        self.assertEqual("", guReport.CReport.GetJoiningFleetNameFromAssignment("jjwejew rjjr"))
        self.assertEqual("", guReport.CReport.GetJoiningFleetNameFromAssignment("iiwe joining fleet "))
        self.assertEqual("", guReport.CReport.GetJoiningFleetNameFromAssignment("iiwe joining fleet ''"))
        self.assertEqual("", guReport.CReport.GetJoiningFleetNameFromAssignment("iiwe joining fleet 'F1"))
        self.assertEqual("", guReport.CReport.GetJoiningFleetNameFromAssignment("iiwe joining fleet F1"))
        self.assertEqual("", guReport.CReport.GetJoiningFleetNameFromAssignment("iiwe joining fleet F1'"))
        self.assertEqual("F1", guReport.CReport.GetJoiningFleetNameFromAssignment("iiwe joining fleet 'F1'"))
        self.assertEqual("", guReport.CReport.GetJoiningFleetNameFromAssignment("iiwe Joining fleet 'F1'"))
        self.assertEqual("", guReport.CReport.GetJoiningFleetNameFromAssignment("iiwe joining Fleet 'F1'"))

    #--------------------------------------------------------------------------
    # ListCtrls coverage tests
    #--------------------------------------------------------------------------

    def test_Call_StarsListView(self):
        guStarsListView.ShowStarsList().Close()
        guStarsListView.ShowYourColoniesList().Close()
        guStarsListView.ShowUninhabitedSystemsList().Close()
        guStarsListView.ShowAlienColoniesList().Close()
        guStarsListView.ShowKnownSystemsList().Close()
        guStarsListView.ShowNotInvestigatedSystemsList().Close()
        
    def test_Call_ShipsListView(self):
        guShipsView.OwnShipsList().Close();
        guShipsView.OtherShipsList().Close();
        guShipsView.AllShipsList().Close();
        
    def test_Call_FleetsListView(self):
        guFleetsView.FleetsList(lambda: guApp.Application.GetReport().Fleets, "Fleets").Close()
        
    def test_Call_BombingListView(self):
        guListView.CListViewFrame(\
            None,
            lambda: guApp.Application.GetReport().GetBombRecords(0),
            lambda panel, array: guBombingView.CBombViewCtrl(panel, array),
            "CBombViewFrame", "All bombings").Show()
                                  
    def test_Call_ShowGroundBattlesListView(self):
        guGBView.ShowGroundBattles(0).Close()
        
    def test_Call_ShowSpaceBattlesListView(self):
        guBattleListView.ShowSpaceBattles().Close()
        
    def test_Call_ShowTransportOrdersListView(self):
        guTransportOrdersListView.ShowTransportOrdersList().Close()
        
    def test_Call_ShowProdOrdersListView(self):
        guProdOrdersListView.ShowProdOrdersList('List of production orders', 0).Close()
    
    def test_Call_ShowRatingListView(self):
        guRatingListView.ShowRatingList().Close()
        
    def test_Call_ShowKnownNationsListView(self):
        guKnownNationsListView.ShowKnownNationsList().Close()
        
    def test_Call_ShowReportMessagesListView(self):
        guReportMessagesListView.ShowReportMessagesList()
        
    def test_Call_ShowSciencesListView(self):
        guSciencesListView.ShowSciencesList()
        
    def test_Call_ShowMoneyTransactionsListView(self):
        guMoneyTransactionsListView.ShowMoneyTransactionsList()
        
    def test_Call_ShowAutoManagersListView(self):
        guAutoManagersListView.ShowList()
        
    def test_Call_ShowSpaceGroupsListView(self):
        guSpaceGroupsListView.ShowOwnSpaceGroupsList().Close();
        guSpaceGroupsListView.ShowApproachingSpaceGroupsList().Close();
        guSpaceGroupsListView.ShowSpaceGroupsList().Close();

    def test_Call_ShowCShipDesignerFrame(self):
        guShipCalc.CShipDesignerFrame(None, self.__report.Ships[0]).Show()
                
    def test_Call_ShowCShipTypesViewCtrl(self):
        guListView.CListViewFrame(\
            None,
            lambda: self.__report.ShipTypes,
            lambda panel, array: guShipsView.CShipTypesViewCtrl(panel, array),
            "CShipTypesViewFrame", "All ship types").Show()

################################################################################
if __name__ == "__main__":
    unittest.main()
