###############################################################################
# File:        guShipCalc.py
# Appointment: Ship calculator
# Project:     GalaxyU
# Author:      AR
# History:
# 25.04.2019 guMaxMissileWHPercent returns double
# 17.11.2012 Created
###############################################################################
import guObjects
import guShipLayout
import guApp
import wxTools
import guTools
import pgWxDisplay
import guCmdEditor
import zx

import math
import pygame
import wx
import wx.lib.masked
import wx.grid
import copy


#===============================================================================

#===============================================================================
# Ship component edit dialog
#===============================================================================
class CShipComponentEdit(wxTools.CDialog):
    EDIT_MODE = 0
    ADD_MODE  = 1
    VIEW_MODE = 2
    
    #---------------------------------------------------------------------------
    # aMode: 0 - edit mode; 1 - add mode; 2 - view mode
    def __init__(self, parent, aShipComponent, aShip, aPos = None, aMode = EDIT_MODE):
        wxTools.CDialog.__init__(\
            self, parent, 
            ("Edit" if aMode == CShipComponentEdit.EDIT_MODE else \
                ("Add" if aMode == CShipComponentEdit.ADD_MODE else "View")) + " Ship Component", 
            (500, 300), aPos)
        
        self.Ship = aShip
        self.ShipComponent = aShipComponent
        self.IsEditable = aMode != CShipComponentEdit.VIEW_MODE
        
        # Types combo
        #============
        typePanel = wx.Panel(self.ControlsPanel, -1, size=(1, 50))
        typeSizer = wx.BoxSizer(wx.HORIZONTAL)
        typeSizer.Add(wx.StaticText(typePanel, label="Types:     "), 0, wx.LEFT)
        
        # Prepare components types list
        if self.ShipComponent is not None and aMode != CShipComponentEdit.ADD_MODE:
            # Ship component is defined - remove all types except component's one
            componentTypes = [self.ShipComponent.GetTypeName()]
        else:
            # Ship component is None: we are adding a new component
            # Exclude from the list single types already present in the ship
            componentTypes = []
            for c in guApp.Application.ShipComponentTypes.keys():
                # Avoid adding unknown or single components already presented in the ship
                if c != 0 and \
                        (not guApp.Application.API.guIsComponentTypeSingle(c) or \
                            len(aShip.FindComponents(c)) == 0):
                    componentTypes.append(guApp.Application.ShipComponentTypes[c])
                    if self.ShipComponent is None:
                        # Create ship component of the 1st type in the list
                        self.ShipComponent = guObjects.CShipComponent(0, c, 1, 1)
                        self.ShipComponent.Tech = \
                            guApp.Application.GetReport().GetNationTechs(\
                                self.Ship.NationName).GetTechForShipComponent(c)

        self.TypeCombo = wx.ComboBox(\
            typePanel,
            choices = componentTypes,
            style = wx.CB_READONLY,
            pos = (10, 10),
            id = 1000)
        
        if self.ShipComponent is not None:
            self.TypeCombo.SetStringSelection(self.ShipComponent.GetTypeName())
        else:
            self.TypeCombo.SetStringSelection(componentTypes[0])
        
        if len(componentTypes) == 1 or not self.IsEditable:
            self.TypeCombo.Disable() # no sense to select anything
        else:
            self.RegisterControl(self.TypeCombo);
        
        typeSizer.Add(self.TypeCombo, 1, wx.RIGHT)
        typePanel.SetSizer(typeSizer)
        self.ControlsSizer.Add(typePanel, 0, wx.EXPAND | wx.LEFT | wx.RIGHT)
        
        # Prepare other controls depending on the ship type
        #===================================================
        
        # Map of 'type panels' <type id: type pannel>
        self.TypePanels = {}
        self.__ComponentsPanel = wx.Panel(self.ControlsPanel, -1, size=self.GetSize())
        self.ControlsSizer.Add(self.__ComponentsPanel,  1, wx.EXPAND | wx.ALL)
        
        # Buttons
        #========
        if self.IsEditable:
            self.AddExitButton("Save", wx.ID_OK)
            self.AddExitButton("Cancel", wx.ID_CANCEL)
        else:
            self.AddExitButton("Ok", wx.ID_CANCEL)
        self.Prepare()
        
        # Events
        #=======
        self.TypeCombo.Bind(wx.EVT_COMBOBOX, self.__OnChangedType)

        # Prepare current panel
        self.__CurrentPanel = None
        self.__OnChangedType(None)


    #---------------------------------------------------------------------------
    def __OnChangedType(self, e):
        componentType = \
            guApp.Application.API.guGetShipComponentType(str(self.TypeCombo.GetValue()))
        self.ShipComponent.Tech = \
            guApp.Application.GetReport().GetNationTechs(\
                self.Ship.NationName).GetTechForShipComponent(componentType)
        self.__PreparePanel(componentType);
        

    #---------------------------------------------------------------------------
    # Prepares control panel for selected type
    def __PreparePanel(self, aType):
        if aType in self.TypePanels:
            if self.TypePanels[aType] != self.__CurrentPanel:
                # Remove current panel
                if self.__CurrentPanel is not None:
                    self.__CurrentPanel.SetSize((0,0))

                # Set new panel    
                self.__CurrentPanel = self.TypePanels[aType]
                self.__CurrentPanel.SetSize(self.__ComponentsPanel.GetSize())
        else:
            panel = wx.Panel(self.__ComponentsPanel, -1)
            panelSizer = wx.BoxSizer(wx.VERTICAL)
            
            # Common panel for mass
            massPanel = wx.Panel(panel, -1, size=(1, 50))
            massSizer = wx.BoxSizer(wx.HORIZONTAL)
            panelSizer.Add(massPanel, 0, wx.EXPAND | wx.LEFT | wx.RIGHT)
            
            # Helper: create 'mass' control
            def CreateMassCtrl(aPanel, aType):
                ctrlMass = wx.lib.masked.numctrl.NumCtrl(aPanel, 2000 + aType);
                ctrlMass.SetBounds(1, guApp.Application.API.guMaxShipComponentMass())
                ctrlMass.SetValue(self.ShipComponent.Mass)
                ctrlMass.SetFocus()
                self.RegisterControl(ctrlMass);
                if not self.IsEditable:
                    ctrlMass.Disable()
                return ctrlMass
            
            if aType == guObjects.CShipComponent.SHIP_COMPONENT_DRIVE or \
               aType == guObjects.CShipComponent.SHIP_COMPONENT_SHIELD or \
               aType == guObjects.CShipComponent.SHIP_COMPONENT_CARGO or \
               aType == guObjects.CShipComponent.SHIP_COMPONENT_REPAIR_UNIT:
                massSizer.Add(wx.StaticText(massPanel, label="Size:        "), 0, wx.LEFT)
                ctrlMass = CreateMassCtrl(massPanel, aType)
                massSizer.Add(ctrlMass, 0, wx.RIGHT)
                
            elif aType == guObjects.CShipComponent.SHIP_COMPONENT_LASER or \
                 aType == guObjects.CShipComponent.SHIP_COMPONENT_MISSILE:
                
                # Power
                massSizer.Add(wx.StaticText(massPanel, label="Power:    "), 0, wx.LEFT)
                ctrlMass = CreateMassCtrl(massPanel, aType)
                massSizer.Add(ctrlMass, 0, wx.LEFT)

                # Quantity
                massSizer.Add(wx.StaticText(massPanel, label="   Quantity:   "), 0, wx.LEFT)
                ctrlQuantity = wx.lib.masked.numctrl.NumCtrl(massPanel, 3000 + aType);
                if self.ShipComponent.Quantity < 1:
                    self.ShipComponent.Quantity = 1
                ctrlQuantity.SetBounds(1, guApp.Application.API.guMaxShipComponentQuantity())
                ctrlQuantity.SetValue(self.ShipComponent.Quantity)
                if not self.IsEditable:
                    ctrlQuantity.Disable()
                self.RegisterControl(ctrlQuantity);
                massSizer.Add(ctrlQuantity, 0, wx.LEFT)
                
                # Weapon target type
                weaponTypePanel = wx.Panel(panel, -1, size=(1, 50))
                panelSizer.Add(weaponTypePanel, 0, wx.EXPAND | wx.LEFT | wx.RIGHT)
                sb = wx.StaticBox(weaponTypePanel, label='Target Type')                
                sbs = wx.StaticBoxSizer(sb, orient=wx.HORIZONTAL)        
                rbAntiShip = wx.RadioButton(weaponTypePanel, 4000 + aType, label='Anti Ship', style=wx.RB_GROUP)
                sbs.Add(rbAntiShip)
                rbAntiMissile = wx.RadioButton(weaponTypePanel, 5000 + aType, label='Anti Missile')
                sbs.Add(rbAntiMissile)
                if self.ShipComponent.TargetType == guObjects.CShipComponent.TARGET_TYPE_ANTI_SHIP:
                    rbAntiShip.SetValue(True)
                else:
                    rbAntiMissile.SetValue(True)
                self.RegisterControl(rbAntiShip);
                self.RegisterControl(rbAntiMissile);
                if not self.IsEditable:
                    rbAntiShip.Disable()
                    rbAntiMissile.Disable()
                weaponTypePanel.SetSizer(sbs)
                
                # Warhead percentage (missiles only)
                if aType == guObjects.CShipComponent.SHIP_COMPONENT_MISSILE:
                    whPanel = wx.Panel(panel, -1, size=(1, 50))
                    panelSizer.Add(whPanel, 0, wx.EXPAND | wx.LEFT | wx.RIGHT)
                    wxSizer = wx.BoxSizer(wx.HORIZONTAL)
                    wxSizer.Add(wx.StaticText(whPanel, label="War head percentage:   "), 0, wx.LEFT)
                    ctrlWHP = wx.lib.masked.numctrl.NumCtrl(whPanel, 6000, size=(70,30));
                    if not self.IsEditable:
                        ctrlWHP.Disable()
                    if self.ShipComponent.WarHeadePercentage < 0:
                        self.ShipComponent.WarHeadePercentage = guObjects.CShipComponent.WHP_Default
                    ctrlWHP.SetBounds(0, guApp.Application.API.guMaxMissileWHPercent() * 100)
                    ctrlWHP.SetValue(self.ShipComponent.WarHeadePercentage * 100)
                    self.RegisterControl(ctrlWHP);
                    wxSizer.Add(ctrlWHP, 0, wx.LEFT)

                    wxSizer.Add(wx.StaticText(whPanel, label="Max launches:   "), 0, wx.LEFT)
                    ctrlMaxLaunches = wx.lib.masked.numctrl.NumCtrl(whPanel, 6001, size=(10,30));
                    if not self.IsEditable:
                        ctrlMaxLaunches.Disable()

                    if self.ShipComponent.MaxLaunchCount < 1:
                        self.ShipComponent.MaxLaunchCount = 1

                    ctrlMaxLaunches.SetBounds(1, guApp.Application.API.guMaxMissileLaunchCount())
                    ctrlMaxLaunches.SetValue(self.ShipComponent.MaxLaunchCount)
                    
                    self.RegisterControl(ctrlMaxLaunches);
                    wxSizer.Add(ctrlMaxLaunches, 0, wx.LEFT)
                    
                    whPanel.SetSizer(wxSizer)

            massPanel.SetSizer(massSizer)
            panel.SetSizer(panelSizer);
            self.TypePanels[aType] = panel
            self.__PreparePanel(aType) # should be found now

    #---------------------------------------------------------------------------
    # Redefined virtual from CDialog: saving data
    def OnSave(self):
        self.ShipComponent.Type = guApp.Application.API.guGetShipComponentType(str(self.TypeCombo.GetValue()))
        self.ShipComponent.Mass = 100 if self.ShipComponent.Type == guObjects.CShipComponent.SHIP_COMPONENT_COLONY_UNIT else self.GetControlValue(2000 + self.ShipComponent.Type) #TODO!!! we hard-code 100 for now, for new client it should come from api. Also - need better picture for colony_unit
        
        if self.ShipComponent.Type == guObjects.CShipComponent.SHIP_COMPONENT_LASER or \
           self.ShipComponent.Type == guObjects.CShipComponent.SHIP_COMPONENT_MISSILE:
            self.ShipComponent.Quantity = self.GetControlValue(3000 + self.ShipComponent.Type)
            self.ShipComponent.TargetType = guObjects.CShipComponent.TARGET_TYPE_ANTI_SHIP \
                                                        if self.GetControlValue(4000 + self.ShipComponent.Type) \
                                                        else guObjects.CShipComponent.TARGET_TYPE_ANTI_MISSILE
            if self.ShipComponent.Type == guObjects.CShipComponent.SHIP_COMPONENT_MISSILE:
                self.ShipComponent.WarHeadePercentage = float(self.GetControlValue(6000))/100
                self.ShipComponent.MaxLaunchCount = self.GetControlValue(6001)

#===============================================================================


#===============================================================================
# Ship components list control
#===============================================================================
class CShipComponentsCtrl(wxTools.CListCtrl):
    #---------------------------------------------------------------------------
    def __init__(self, parent, aShip, aOnChangeEvent = None, aIsEditable = True):
        wxTools.CListCtrl.__init__(self, parent)
        
        self.OnChangeEvent = aOnChangeEvent # can be set to react when something has changed with the ship
        self.IsEditable = aIsEditable
        
        self.Ship = aShip
        self.SetItemCount(len(self.Ship.Components))
        
        # Add columns
        self.AddColumn(\
            "ID", 30, 
            lambda row, col: str(self.Ship.Components[row].Id))
        self.AddColumn(\
            "Type", 100, 
            lambda row, col: self.Ship.Components[row].GetTypeName())
        self.AddColumn(\
            "Tech", 50,
            lambda row, col: \
                "{0:.2f}".format(self.Ship.Components[row].Tech), wx.LIST_FORMAT_RIGHT, True)
        self.AddColumn(\
            "Mass", 100,
            lambda row, col: \
                "{0:.2f}".format(self.Ship.Components[row].CalcMass()), wx.LIST_FORMAT_RIGHT, True)
        self.AddColumn(\
            "Shot Power", 100,
            # Here is a trick. For ship types (self.Ship.Id == 0) techs are calculated in here
            # So, ShotPower is returned *without techs*
            lambda row, col: \
                "{0:.3f}".format(\
                    self.Ship.Components[row].ShotPower * \
                        (self.Ship.Components[row].Tech if self.Ship.Id == 0 else 1)),
                wx.LIST_FORMAT_RIGHT, True)
        self.AddColumn(\
            "D/Mass", 60,
            lambda row, col: \
                "{0:.2f}".format(self.Ship.Components[row].DestroyedMass), wx.LIST_FORMAT_RIGHT, True)
        self.AddColumn(\
            "Efficiency", 80,
            lambda row, col: "{0:.2f}".format(self.Ship.Components[row].Efficiency),
            wx.LIST_FORMAT_RIGHT, True)
        self.AddColumn(\
            "Description", 500,
            lambda row, col: self.Ship.Components[row].GetCommandString(),wx.LIST_FORMAT_LEFT)
        
        # Special key events
        if self.IsEditable:
            self.SpecialKeyEvents[wx.WXK_INSERT] = self.__OnInsert
            self.SpecialKeyEvents[wx.WXK_DELETE] = self.__OnDelete

    #---------------------------------------------------------------------------
    def __OnChange(self):
        if self.OnChangeEvent is not None:
            self.OnChangeEvent()

    
    #---------------------------------------------------------------------------
    # Special key events
    def __OnInsert(self, e):
        # Adding a new component
        dlg = CShipComponentEdit(\
            self, None if self.GetSelectedDataItem() < 0 or \
            guApp.Application.API.guIsComponentTypeSingle(\
                self.Ship.Components[self.GetSelectedDataItem()].Type) else \
                copy.deepcopy(self.Ship.Components[self.GetSelectedDataItem()]), 
                self.Ship, self.GetItemScreenPos(0), CShipComponentEdit.ADD_MODE)
        if dlg.ShowModal() == wx.ID_OK:
            # Add a component
            dlg.ShipComponent.SetDefaultShotPower()
            self.Ship.Components.append(dlg.ShipComponent)
            self.SetItemCount(len(self.Ship.Components))
            self.__OnChange()
        
        dlg.Destroy()

    #---------------------------------------------------------------------------
    def __OnDelete(self, e):
        if len(self.Ship.Components) > 1:
            item = self.GetSelectedDataItem()
            if item >= 0 and \
                    wxTools.AskYesNo(\
                        self,
                        "Would you like to delete this component?",
                        "Removing Component", 
                        aPos = self.GetItemScreenPos(item)) == wx.ID_YES:
                del self.Ship.Components[item]
                l = len(self.Ship.Components)
                self.SetItemCount(l)
                if item >= len(self.Ship.Components):
                    self.Focus(l - 1)
                    self.Select(l - 1)
                    self.Refresh()
                self.__OnChange()
    
    
    #---------------------------------------------------------------------------
    # Redefined virtual
    def OnEdit(self, aPos):
        dlg = CShipComponentEdit(\
            self, self.Ship.Components[self.GetSelectedDataItem()], self.Ship, aPos, 
            CShipComponentEdit.EDIT_MODE if self.IsEditable else \
            CShipComponentEdit.VIEW_MODE)
        if dlg.ShowModal() == wx.ID_OK:
            self.Ship.Components[self.GetSelectedDataItem()].SetDefaultShotPower()
            self.__OnChange()
            self.Refresh()
        dlg.Destroy()
        
#===============================================================================


#===============================================================================
# Ship designer dialog
#===============================================================================
class CShipDesignerFrame(guTools.CCfgFrame):
    #---------------------------------------------------------------------------
    def __init__(self, parent, aShip = None, aIsEditable = False):
        guTools.CCfgFrame.__init__(self, parent, guApp.Application.Config, "GUI", "CShipDesignerFrame")

        self.IsEditable = aIsEditable
        
        # Min window size
        self.SetMinSize((700, 400))

        if aShip is None:
            self.IsEditable = True # new ship is always editable
            self.SetTitle("Design a new ship")
            aShip = guObjects.CShip(0, guApp.Application.GetReport().NationName)
            # Just add one component (caoont be empty)
            aShip.Components.append(guObjects.CShipComponent(\
                1, 
                guObjects.CShipComponent.SHIP_COMPONENT_DRIVE,
                1, 1,0, guApp.Application.GetReport().GetNationTechs().TechDrive))
        else:
            self.SetTitle(aShip.NationName + ":" + ((" #" + str(aShip.Id)) if aShip.Id != 0 else "") + " " + \
                          ("" if aShip.Name == "" or \
                                 aShip.Name == "?" or \
                                 aShip.Name == aShip.TypeName else \
                           "(" + aShip.Name + ") ") +  aShip.TypeName)

        if aShip.Id == 0: # made up ship, has no techs - add them
            ratingInfo = guApp.Application.GetReport().GetNationTechs(aShip.NationName)
            for c in aShip.Components:
                c.Tech = ratingInfo.GetTechForShipComponent(c.Type)

        self.__originalShip = aShip # ship before editting
        self.Ship = copy.deepcopy(aShip)

        # Add controls
        #=============
        
        ## Component's grid panel
        componentsPanel = wx.Panel(\
            self, -1,
            size = (self.GetClientSize().GetWidth(),
            self.GetClientSize().GetHeight()/2))
        shipGrid = CShipComponentsCtrl(componentsPanel, self.Ship, None, self.IsEditable)
        shipGrid.SetSize(componentsPanel.GetClientSize())
        shipGrid.SpecialKeyEvents[wx.WXK_ESCAPE] = lambda event: self.__OnClose(event)

        gridSizer = wx.BoxSizer(wx.VERTICAL)
        gridSizer.Add(shipGrid, 1, wx.EXPAND | wx.ALL)
        shipGrid.SetFocus()
        componentsPanel.SetSizer(gridSizer)

        ## Ship image/info panel
        imageInfoPanel = wx.Panel(\
            self, -1, size=(self.GetClientSize().GetWidth(), guObjects.CShip.SHIP_IMAGE_SIZE*1.5))
        self.ImagePanel = wx.Panel(\
            imageInfoPanel, -1,
            size=(imageInfoPanel.GetClientSize().GetWidth()/2, imageInfoPanel.GetClientSize().GetHeight()))
        self.__Screen = pgWxDisplay.CPygameDisplay(self.ImagePanel, -1, self.__DrawShipImage)
        screenSizer = wx.BoxSizer(wx.VERTICAL)
        screenSizer.Add(self.__Screen, 1, wx.EXPAND | wx.ALL)
        self.ImagePanel.SetSizer(screenSizer)

        shipGrid.OnChangeEvent = self.__OnChange
        
        self.InfoPanel = wx.Panel(\
            imageInfoPanel, -1,
            size=(imageInfoPanel.GetClientSize().GetWidth()/2, imageInfoPanel.GetClientSize().GetHeight()))
        
        # Helper - adds simple control
        def AddControlRow(aPanel, aSizer, aLabel):
            speedPanel = wx.Panel(aPanel, -1, size=(1, 25))
            aSizer.Add(speedPanel, 1, wx.EXPAND | wx.RIGHT | wx.LEFT)
            wx.StaticText(speedPanel, label=aLabel, pos=(0,0))
            ctrl = wx.lib.masked.numctrl.NumCtrl(speedPanel, fractionWidth=3, pos=(150,0));
            ctrl.Disable() # currently for information only
            return ctrl

        infoSizer = wx.BoxSizer(wx.VERTICAL)
        self.EfficiencyCtrl = AddControlRow(self.InfoPanel, infoSizer,       "Efficiency:")
        self.MassCtrl = AddControlRow(self.InfoPanel, infoSizer,             "Mass:")
        self.MassMaxLoadedCtrl = AddControlRow(self.InfoPanel, infoSizer,    "Mass with full cargo:")
        self.ShieldCtrl = AddControlRow(self.InfoPanel, infoSizer,           "Shield:")
        self.BombingCtrl = AddControlRow(self.InfoPanel, infoSizer,          "Bombing:")
        self.LaserMaxShotCtrl = AddControlRow(self.InfoPanel, infoSizer,     "Laser max power:")
        self.MissileMaxShotCtrl = AddControlRow(self.InfoPanel, infoSizer,   "Missile max power:")
        self.SpeedCtrl = AddControlRow(self.InfoPanel, infoSizer,            "Speed:")
        self.SpeedMaxLoadedCtrl = AddControlRow(self.InfoPanel, infoSizer,   "Speed with full cargo:")
        self.MaxCargoCapacityCtrl = AddControlRow(self.InfoPanel, infoSizer, "Max Cargo capacity:")
        self.CargoFreeSpaceCtrl = AddControlRow(self.InfoPanel, infoSizer,   "Cargo free space:")
        self.LoadedCargoCtrl = AddControlRow(self.InfoPanel, infoSizer,      "Loaded Cargo:")
        self.__OnChange() # force recalc

        self.InfoPanel.SetSizer(infoSizer)
        
        imageInfoSizer = wx.BoxSizer(wx.HORIZONTAL)
        imageInfoSizer.Add(self.ImagePanel, 1, wx.EXPAND | wx.LEFT)
        imageInfoSizer.Add(self.InfoPanel, 1, wx.EXPAND | wx.RIGHT)
        imageInfoPanel.SetSizer(imageInfoSizer)

        ## Control panel
        controlPanel = wx.Panel(self, -1, size=(self.GetClientSize().GetWidth(), 40))
        buttonsSizer = wx.BoxSizer(wx.HORIZONTAL)
        buttonsSizer.AddStretchSpacer()        
        if self.IsEditable:
            buttonOk = wx.Button(controlPanel, wx.ID_OK, label = "Save to order")
            buttonOk.Bind(wx.EVT_BUTTON, lambda event: self.__OnSaveToOrder())
            buttonsSizer.Add(buttonOk, 0, wx.CENTRE)
        buttonCancel = wx.Button(controlPanel, wx.ID_CANCEL, label = "Cancel" if self.IsEditable else "Ok")
        buttonCancel.Bind(wx.EVT_BUTTON, lambda event: self.__OnClose(event))
        buttonsSizer.Add(buttonCancel, 0, wx.CENTRE)
        buttonsSizer.AddStretchSpacer()      
        controlPanel.SetSizer(buttonsSizer)
        
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(componentsPanel, 1, wx.EXPAND | wx.ALL)
        vbox.Add(imageInfoPanel, 0, wx.EXPAND | wx.LEFT | wx.RIGHT)
        vbox.Add(controlPanel, 0, wx.EXPAND | wx.LEFT | wx.RIGHT)
        
        self.SetSizer(vbox)
        
        shipGrid.Select(0)
        
        # Events
        #=============
        self.Bind(wx.EVT_SIZE, self.__OnSize)

        # Unregister itself when closing        
        self.OnSaveCfg = lambda: guApp.Application.WindowsCollection.Unregister(self)

        # To make it working on Windows thisstupidity is necessary
        # to make the all controls be correctly displayed 
        if zx.IsWindows():
            stupido = self.GetSize()
            self.SetSize((stupido[0]+1, stupido[1])) # force resize to redraw all
            self.SetSize(stupido) # set old size back
            self.SetMaxSize((700, 600))


    #---------------------------------------------------------------------------
    def __OnClose(self, e):
        if self.IsEditable and self.Ship != self.__originalShip:
            if wxTools.AskYesNo(self, 
                                "Would you like to quit? Your changes will be lost if not saved in the order.", 
                                "Exit Ship Designer") != wx.ID_YES:
                e.Veto()
                return
        self.Close()

    #---------------------------------------------------------------------------
    def __OnSaveToOrder(self):
        # Get cmd editor
        cmdEditor = guCmdEditor.CCmdEditor.Call()
        
        # Set position to insert the type creation command
        cmdEditor.textCtrl.SetInsertionPoint(cmdEditor.GetInsertPoint())

        # Insert command        
        cmdEditor.textCtrl.WriteText("\n// New ship type \n")
        cmdEditor.textCtrl.WriteText("create ship type --name MyTypeName --code " + self.Ship.GetComponentsCommandString() + ";\n")
    

    #---------------------------------------------------------------------------
    def __OnChange(self):
        # Reset ship
        self.Ship.Reset()
        # Repaint the ship
        self.__Screen.RePaint()
        # Recalculate data
        self.EfficiencyCtrl.SetValue(self.Ship.Efficiency)
        self.MassCtrl.SetValue(self.Ship.ShipTypeCalcMass())
        self.MassMaxLoadedCtrl.SetValue(self.Ship.ShipTypeCalcMaxLoadedMass())
        self.SpeedCtrl.SetValue(\
            self.Ship.ShipTypeCalcSpeed() if self.IsEditable else self.Ship.GetSpeed())
        self.SpeedMaxLoadedCtrl.SetValue(\
            self.Ship.ShipTypeCalcMaxLoadedSpeed() if self.IsEditable else self.Ship.GetMaxLoadedSpeed())
        self.ShieldCtrl.SetValue(\
            self.Ship.ShipTypeCalcShield() if self.IsEditable else self.Ship.GetShield())
        self.BombingCtrl.SetValue(\
            self.Ship.ShipTypeCalcBombing() if self.IsEditable else self.Ship.GetBombing())
        self.LaserMaxShotCtrl.SetValue(\
            self.Ship.ShipTypeCalcLaserMaxShot() if self.IsEditable else self.Ship.GetLaserMaxShot())
        self.MissileMaxShotCtrl.SetValue(\
            self.Ship.ShipTypeCalcMissileMaxShot() if self.IsEditable else self.Ship.GetMissileMaxShot())
        self.MaxCargoCapacityCtrl.SetValue(\
            self.Ship.ShipTypeCalcMaxCargoCapacity() if self.IsEditable else self.Ship.GetMaxCargoCapacity())
        self.CargoFreeSpaceCtrl.SetValue(\
            self.Ship.ShipTypeCalcCargoFreeSpace() if self.IsEditable else self.Ship.GetCargoFreeSpace())
        self.LoadedCargoCtrl.SetValue(\
            self.Ship.ShipTypeCalcLoadedCargo() if self.IsEditable else self.Ship.GetLoadedCargo())

    #---------------------------------------------------------------------------
    def __OnSize(self, e):
        self.__Screen.RePaint()
        e.Skip()
    
    #---------------------------------------------------------------------------
    # Draws ship image
    def __DrawShipImage(self, aScreen):
        shipImage = guObjects.CShipType.CreateImage((255,255,255), guShipLayout.CShipLayout(self.Ship.Components))
        screenDiameter = math.pow(self.Ship.ShipTypeCalcMass(), 1.0/3)*20
        if screenDiameter > guObjects.CShip.SHIP_IMAGE_SIZE:
            screenDiameter = guObjects.CShip.SHIP_IMAGE_SIZE
            
        shipImage = pygame.transform.scale(shipImage, (int(screenDiameter), int(screenDiameter)))
        rect = shipImage.get_rect()
        rect.centerx = self.ImagePanel.GetClientSize().GetWidth()/2
        rect.centery = self.ImagePanel.GetClientSize().GetHeight()/2
        aScreen.blit(shipImage, rect)

    
#===============================================================================

