# This file is based on celstrap.py and pyceguitest.py

import sys, time, traceback
from pycel import *

pcclasses = ["pcworld.region", "pc2d.tooltip", "pcobject.mesh", "solid", \
             "zonemanager", "trigger", "quest", "light", "inventory", \
             "defaultcamera", "gravity", "movable", "pccommandinput", \
             "linmove", "actormove", "colldet", "timer", "billboard" ]

# The class that implements the main application behaviour.
# if you want to make your own just copy it and set the same name for
# the file as for the class. ie: celstrap.py has class celstrap.

# To use this the player must have a camera property class and must be 
# called "camera" :(. Have to find a better way to manage the player.

class InitialEntity:

    api_version = 2 # use new version of message callbacks.

    def __init__ (self, celEntity):
        print "Initializing game..."
        self.entity = celEntity
        # Keep a var pointing to this entity
        self.entity = celEntity
        # Load config file containing the key bindings
        self.input = celCommandInput (self.entity)
        #self.input.LoadConfig("Bootstrap")
        self.input.LoadConfig ("CELStartCEGUI")

        self.loadMovieRecorder ()
        # graphic interfaces
        self.font = Graphics2D.GetFontServer ().LoadFont ("*large")
        # check for tooltip
        self.logs = []
        # the zone manager entity
        self.game_entity = CreateEntity ("ZoneManager", None, None)

        # create the tooltip for logs
        self.createTooltip ()
        self.do_save = False
        self.map = "level.xml"
        #self.loadMap (self.map)

        if not self.InitCegui():
            sys.exit(1)

        # This timer will be used to render CEGUI stuff every frame (or 2)
        self.timer = celTimer (self.entity)
        self.timer.WakeUpFrame (2) # 1 and 2 is OK, 2 speeds a bit, 3 is not OK

        print "End initializing game..."

    def loadMovieRecorder (self):
        # Load the movierecorder plugin if available
        self.mr = oreg.Get (iMovieRecorder)
        if not self.mr:
            plugmgr = oreg.Get (iPluginManager)
            self.mr = plugmgr.LoadPlugin ( \
                "crystalspace.utilities.movierecorder", iMovieRecorder)
            if self.mr:
                oreg.Register (self.mr, "iMovieRecorder")
            else:
                self.mr = None

    # doing it better
    def createTooltip (self):
        self.tooltip = celToolTip (self.entity)
        self.tooltip.SetBackgroundColor (-1, -1, -1)
        self.tooltip.SetTextColor (255, 255, 255)
        self.tooltip.Show (20, 20)
        self.log_event ("celstart started")
        self.log_event ("i: start record")
        self.log_event ("o: stop record")
        self.log_event ("p: pause record")

    # TODO this way to load the map is not very nice, but
    # it is the same celtest uses, i don't know about
    def loadMap (self, map_file):
        # Set 2D mode so we can clear then print on the screen
        if (not Graphics3D.BeginDraw (CSDRAW_2DGRAPHICS)):
            return
        Graphics2D.Clear (0)
        Graphics2D.Write (self.font, 100, 100, \
            Graphics2D.FindRGB (255, 255, 255), \
            Graphics2D.FindRGB (0,0,0), "Loading " + str (map_file))
        Graphics2D.Print (csRect (0, 0, 640, 480))
        Graphics3D.FinishDraw ()
        # XXX ugly hardcoded name for the player
        self.playername = "camera"
        # create an initial environment to load the map
        zoneManager = celZoneManager (self.game_entity)
        Vfs.ChDirAuto ("/tmp/celstart/")
        zoneManager.Load ("/tmp/celstart", map_file)
        # the map won't load until we put a dummy camera into
        # the region
        dummy = CreateEntity ("dcamera", None, None)
        dummy_cam = celDefaultCamera (dummy)
        self.startregion = zoneManager.LastStartRegionName
        self.startname = zoneManager.LastStartName
        dummy_cam.SetZoneManager (zoneManager, True, self.startregion, "")

        # now the map is loaded we want to find the real
        # player entity and do some setup.
        actor = Entities[self.playername]
        if celGetMesh (actor):
            zoneManager.PointMesh (self.playername, self.startregion, \
                self.startname)
        else:
            zoneManager.PointCamera (self.playername, self.startregion, \
                self.startname)
        # kill the dummy camera
        RemoveEntity (dummy)

    # video record commands
    def pccommandinput_startrecord1 (self, pc, args):
        self.log_event ("start recording")
        if self.mr:
            self.mr.Start ()

    def pccommandinput_stoprecord1 (self, pc, args):
        self.log_event ("stop recording")
        if self.mr:
            self.mr.Stop ()

    def pccommandinput_pauserecord1 (self, pc, args):
        if self.mr:
            if self.mr.IsPaused ():
                self.log_event ("unpause recording")
                self.mr.UnPause ()
            else:
                self.log_event ("pause recording")
                self.mr.Pause ()

    def pccommandinput_blah1 (self, pc, args):
        print 'Blah !'

    def pccommandinput_blah0 (self, pc, args):
        # Ignore "release keypress" event
        pass

    def pccommandinput_blah_(self, pc, args):
        # ignore "autorepeat keypress" event
        pass

    def log_event (self, event):
        self.logs.append (event)
        if len(self.logs) > 5:
            self.logs.pop (0)
            tooltip_text = "\n".join(self.logs)
            self.tooltip.Show (20, 20)
            self.tooltip.SetText (tooltip_text)

    # this are callbacks for pczonemanager (not used at the moment
    # as the zonemanager is a separate entity)
    #def pczonemanager_startloading (self, pc, args):
    #    self.log_event ("start loading")
    #def pczonemanager_stoploading (self, pc, args):
    #    self.log_event ("stop loading")
    #def pczonemanager_addregion (self, pc, args):
    #    self.log_event ("add region")
    #def pczonemanager_remregion (self, pc, args):
    #    self.log_event ("remove region")

    # starting command, here we can pass map name, player name...
    def load (self, pc, args):
        # mount the file at some path in vfs
        self.map = args[getid("cel.parameter.parameter1")]
        #vfs.ChDirAuto("/celstrap/");
        self.loadMap (self.map)

    def InitCegui (self):
        global Cegui
        Cegui = oreg.Get (iCEGUI)
        if not Cegui:
            #Report(CS_REPORTER_SEVERITY_ERROR, \
            print "Cegui plugin not present in registry!"
            return False
        # init cs cegui system
        Cegui.Initialize ()
        winMgr = Cegui.WindowManager
        sysPtr = Cegui.System
        Vfs.ChDir ("/ceguitest/0.5/")
        # load scheme
        Cegui.SchemeManager.loadScheme ("ice.scheme")
        # set cursor
        sysPtr.DefaultMouseCursor = ("ice", "MouseArrow")
        # load font
        cegui_font = Cegui.FontManager.createFont ("FreeType", "Vera", \
            "/fonts/ttf/Vera.ttf")
        cegui_font.setProperty ("PointSize", "10")
        cegui_font.load ()
        # load layout
        sysPtr.GUISheet = winMgr.loadWindowLayout ("ice.layout")
        # subscribe some events
        btn = winMgr.getWindow ("Demo7/Window1/Quit")
        btn.subscribeEvent (cegui.PushButton.EventClicked, self.onQuit)
        btn = winMgr.getWindow ("Demo7/Window1/Editbox")
        btn.subscribeEvent (cegui.Editbox.EventTextAccepted, self.onBar)
        btn.subscribeEvent (cegui.Editbox.EventTextChanged, self.onBar)
        btn = winMgr.getWindow ("Demo7/Window1/Checkbox")
        btn.subscribeEvent (cegui.Checkbox.EventActivated, self.onBar)
        btn.subscribeEvent (cegui.Checkbox.EventEnabled, self.onBar)
        btn.subscribeEvent (cegui.Checkbox.EventMouseClick, self.onBar)
        btn = winMgr.getWindow ("Demo7/Window3/MLEditbox")
        btn.subscribeEvent (cegui.MultiLineEditbox.EventTextChanged, self.onBar)
        btn = winMgr.getWindow ("Demo7/Window1/Slider1")
        btn.subscribeEvent (cegui.Slider.EventValueChanged, self.onSlider)
        return True

    def onQuit (self, args):
        print args.__dict__
        print "TODO: implement quit..."

    def onBar (self, args):
        print "changed textbox", args.Window.Name

    def onSlider (self, args):
        btn1 = args.Window
        print btn1.Name, "value", btn1.CurrentValue

    def pctimer_wakeupframe (self, pc, args):
        # Clear the screen and begin drawing in 3D mode
        Graphics2D.Clear(0)
        Graphics3D.BeginDraw(Engine.GetBeginDrawFlags() | CSDRAW_3DGRAPHICS)
        # render cegui interface
        Cegui.Render()
        Graphics3D.FinishDraw ()

