Code Search for Developers
 
 
  

SKE.cpp from Spatial Knowledge Experiments at Krugle


Show SKE.cpp syntax highlighted

 /*
    Copyright (C) 2003, 2004, 2005 by Luca Cappa
    Written by Luca Cappa groton@users.sourceforge.net
  
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
  
    This library 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
    Library General Public License for more details.
  
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

//
//
// I N C L U D E S
//

/*
Left-handed coords (use the left hand rule, except for rotating around Y axis).

  Rotations:
  Z
  ^
  |
  |
  +----->X
  Y
  Around Y: counter CW with positive angle of rotation. (Notice I wrote counter CW and not CW).
  
    Y
    ^
    |
    |
    +----->Z
    X
    Around X: CW with positive angle of rotation.
    
      X
      ^
      |
      |
      +----->Y
      Z
      Around Z: CW is a positive angle of rotation.
*/

#include "cssysdef.h"

#include "csutil/sysfunc.h"
#include "csutil/cscolor.h"
#include "csutil/cmdhelp.h"
#include "csutil/cspmeter.h"
#include "csutil/csstring.h"
#include "csutil/scfstr.h"
#include "csutil/xmltiny.h"
#include "csutil/schedule.h"
#include "csutil/array.h"
#include "csutil/stringarray.h"
#include "csutil/event.h"

#include "csgfx/memimage.h"
#include "csgfx/rgbpixel.h"

#include "cstool/csview.h"
#include "cstool/initapp.h"
#include "cstool/collider.h"
#include "cstool/cspixmap.h"

#include "iutil/vfs.h"
#include "iutil/eventq.h"
#include "iutil/event.h"
#include "iutil/objreg.h"
#include "iutil/csinput.h"
#include "iutil/virtclk.h"
#include "iutil/plugin.h"
#include "iutil/string.h"

#include "iengine/engine.h"
#include "iengine/sector.h"
#include "iengine/camera.h"
#include "iengine/light.h"
#include "iengine/texture.h"
#include "iengine/mesh.h"
#include "iengine/movable.h"
#include "iengine/material.h"

#include "imesh/thing.h"
#include "imesh/object.h"
#include "imesh/sprite3d.h"
#include "imesh/particle.h"
#include "imesh/particles.h"
#include "imesh/partsys.h"
#include "imesh/snow.h"


#include "ivideo/graph3d.h"
#include "ivideo/graph2d.h"
#include "ivideo/natwin.h"
#include "ivideo/txtmgr.h"
#include "ivideo/texture.h"
#include "ivideo/material.h"
#include "ivideo/fontserv.h"

#include "igraphic/imageio.h"

#include "imap/loader.h"

#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "ivaria/conout.h"
#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "ivaria/collider.h"

#include "csgeom/quaterni.h"
#include "csgeom/transfrm.h"
#include "csgeom/math3d_d.h"
#include "csgeom/math3d.h"

#include "igeom/polymesh.h"

#include "imap/loader.h"


#include "iaws/aws.h"
#include "iaws/awscnvs.h"
#include "iaws/awsparm.h"


//
//My own include files.
#include "isense/iisensetracker.h"
#include "joystick/ikjoystick.h"
#include "korientation.h"
#include "kblock.h"
#include "kmap.h"
#include "kblockid.h"
#include "ksprite3d.h"
#include "ksprite3dlist.h"
#include "klandmark.h"
#include "klandmarklist.h"
#include "klightlist.h"
#include "kwireframe.h"
#include "kappstate.h"
#include "skybox.h"
#include "kcamera.h"
#include "kdata.h"
#include "kdatalist.h"
#include "kthing.h"
#include "kterrain.h"
#include "kobject3d.h"
#include "kmission.h"
#include "kutil.h"
#include "kpath.h"
#include "kplayer.h"
#include "kcommandprocessor.h"
#include "kkeystate.h"
#include "ksign.h"
#include "klight.h"
#include "kquaternion.h"
#include "ksaveddatamanager.h"
#include "kdragmanager.h"
#include "kmousemanager.h"
#include "kcursor3d.h"
#include "kmissiontype.h"
#include "kimagecardinaldirection.h"
#include "kmode.h"
//Include for this file.
#include "ske.h"
#include <iostream>
#include <sstream>
#include <string>

// This is a CS application.
CS_IMPLEMENT_APPLICATION

//
//Some global vars.
SKE *g_ske;// The global pointer to SKE
iObjectRegistry *g_objReg;//The global pointer to the object registry.

//
//Ctor.
SKE::SKE () :
  m_walkedPath (0),
  m_appState (KAppState::EDITING),
  m_useJoy (false),
  //?????Disabled until some1 will fix the terrain related code!  m_drawTerrain (false)
  m_putLightOntoHead (false),
  m_useDynaVis (false),
  mDebugMode (false),
  m_backgrounded (false),
  m_skyBox (0),
  m_kcam (0),
//?????Disabled until some1 will fix the terrain related code!  m_terrain = 0;
  m_sign (0),
  mMode (0),
  m_replaySpeed (0),
  m_blockIdSelected (KBlockId::I1),
  mPathTolerance (5.0f)
{
}

SKE::~SKE ()
{
  this->m_evHndlrMan->RemoveAllEventHandlers ();

  delete m_skyBox;
  delete m_kcam;
//?????Disabled until some1 will fix the terrain related code!  delete m_terrain;
  delete m_sign;
  delete mMode;
}


void SKE::Report (int severity, const char* msg, ...)
{
  va_list arg;
  va_start (arg, msg);
  csRef<iReporter> rep (CS_QUERY_REGISTRY (g_objReg, iReporter));
  if (rep)
  {
    rep->ReportV (severity, "crystalspace.application.SKE", msg, arg);
  }//if
  else
  {
    csPrintfV (msg, arg);
    csPrintf ("\n");
  }//else
  va_end (arg);
}


//?????
#define IS_KEY_DOWN(ev, key) \
  ((csKeyEventHelper::GetEventType (& ev) == csKeyEventTypeDown) &&\
     (csKeyEventHelper::GetCookedCode (& ev) == key))

bool SKE::HandleEvent (iEvent& p_ev)
{
  /*
  csKeyModifiers l_modifiers;
  csKeyEventHelper::GetModifiers (&p_ev, l_modifiers);


  if (l_modifiers.modifiers[csKeyModifierTypeShift])
  {
    if (IS_KEY_DOWN (p_ev, CSKEY_F3))
      m_player->m_topOffset.x += 0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F4))
      m_player->m_topOffset.y += 0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F5))
      m_player->m_topOffset.z+=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F6))
      m_player->m_bottomOffset.x += 0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F7))
      m_player->m_bottomOffset.y += 0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F8))
      m_player->m_bottomOffset.z+=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F9))
      m_player->m_headOffset.x+=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F10))
      m_player->m_headOffset.y+=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F11))
      m_player->m_headOffset.z+=0.01f;
  }//if
  else //if (!(l_modifiers.modifiers[csKeyModifierTypeShift]))
  {
    if (IS_KEY_DOWN (p_ev, CSKEY_F3))
      m_player->m_topOffset.x-=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F4))
      m_player->m_topOffset.y-=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F5))
      m_player->m_topOffset.z-=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F6))
      m_player->m_bottomOffset.x-=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F7))
      m_player->m_bottomOffset.y-=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F8))
      m_player->m_bottomOffset.z-=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F9))
      m_player->m_headOffset.x-=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F10))
      m_player->m_headOffset.y-=0.01f;
    else if (IS_KEY_DOWN (p_ev, CSKEY_F11))
      m_player->m_headOffset.z-=0.01f;
  }//else
*/

  if (p_ev.Type == csevBroadcast && 
    csCommandEventHelper::GetCode (&p_ev) == cscmdProcess)
  {
    if (!m_backgrounded)
      SetupFrame ();
    else
      csSleep (500);//If the application is backgrounded, let's sleep!
    
    return true;
  }//if
  else if (p_ev.Type == csevBroadcast && 
    csCommandEventHelper::GetCode (&p_ev) == cscmdFinalProcess)
  {
    if (!m_backgrounded)
      FinishFrame ();
    
    return true;
  }//else
  else
  {
    if (m_aws->HandleEvent (p_ev))
      return true;//let aws try to handle this event before my handlers.
    
    switch (p_ev.Type)
    {
    case csevBroadcast:
      {
        if (csCommandEventHelper::GetCode (&p_ev) == cscmdCanvasHidden)
        {
          KCommandProcessor::_Perform ("canvas_hidden");
          break;
        }//if
        else if (csCommandEventHelper::GetCode (&p_ev) == cscmdCanvasExposed)
        {
          KCommandProcessor::_Perform ("canvas_exposed");
          break;
        }//else if
        else if (csCommandEventHelper::GetCode (&p_ev) == cscmdContextResize)
        {
          iGraphics2D* lG2D = (iGraphics2D*)
            csCommandEventHelper::GetInfo (&p_ev);
          m_aws->SetupCanvas (0, lG2D, m_g3d);
        }//else
        
        break;//
      }//case
      
    case csevKeyboard:
      {
        EatKeyPress (&p_ev);
        break;
      }//case
      
    }//switch
  }//else
  return false;
}





typedef KEventHandlerHelper<SKE> KEventHandler2;

//SCF_IMPLEMENT_IBASE (KEventHandler2)
SCF_IMPLEMENT_IBASE_INCREF(KEventHandler2)
SCF_IMPLEMENT_IBASE_DECREF(KEventHandler2)
SCF_IMPLEMENT_IBASE_GETREFCOUNT(KEventHandler2)
  SCF_IMPLEMENT_IBASE_REFOWNER(KEventHandler2)
  //SCF_IMPLEMENT_IBASE_REMOVE_REF_OWNERS(Class)
template<class T> void KEventHandlerHelper<T>::scfRemoveRefOwners ()					\
{									\
  if (!scfWeakRefOwners) return;					\
  for (size_t i = 0 ; i < scfWeakRefOwners->Length () ; i++)		\
  {									\
    iBase** p = (*scfWeakRefOwners)[i];					\
    *p = 0;								\
  }									\
  delete scfWeakRefOwners;						\
  scfWeakRefOwners = 0;							\
}
  SCF_IMPLEMENT_IBASE_QUERY(KEventHandler2)
  SCF_IMPLEMENTS_INTERFACE (iEventHandler)
SCF_IMPLEMENT_IBASE_END

SCF_IMPLEMENT_IBASE (KEventPlug);
  SCF_IMPLEMENTS_INTERFACE (iEventPlug);
SCF_IMPLEMENT_IBASE_END;




/*
void kprintf (csVector3 p_v)
{
  printf ("x:%7.03f, y:%7.03f, z:%7.03f\n", p_v.x, p_v.y, p_v.z);
}
*/



bool SKE::Initialize ()
{

  //???kasm ();

  /*KQuaternion l_q;
  l_q.SetWithEuler (csVector3 (90,0,0));
  l_q.Normalize ();
  csVector3 l_Y (0,1,0);
  kprintf (l_q.Rotate (l_Y));}
  
    {KQuaternion l_q;
    l_q.SetWithEuler (csVector3 (0,90,0));
    l_q.Normalize ();
    csVector3 l_X (1,0,0);
    kprintf (l_q.Rotate (l_X));}
    
      {KQuaternion l_q;
      l_q.SetWithEuler (csVector3 (0,0,90));
      l_q.Normalize ();
      csVector3 l_X (1,0,0);
  kprintf (l_q.Rotate (l_X));}*/
  
  
  /*  csQuaternion l_q;
  csVector3 l_v;
  l_q.SetWithEuler (csVector3 (0.4f, 0.2f, 0.3f));  
  l_q.Normalize ();
  l_q.GetEulerAngles (l_v);
  l_q.SetWithEuler (csVector3 (1.45f, 2.4f, 1.97));
  l_q.Normalize ();
  l_q.GetEulerAngles (l_v);
  l_q.SetWithEuler (csVector3 (3.15f, 1.4f, 0.97));
  l_q.Normalize ();
  l_q.GetEulerAngles (l_v);*/
  
  /*l_q.SetWithEuler (csVector3 (0.4f, 0.0f, 0.0f));
  l_q.Normalize ();
  l_v = l_q.Rotate (csVector3 (0,1,0));
  l_q.SetWithEuler (csVector3 (0.0f, 0.4f, 0.0f));
  l_q.Normalize ();
  l_v = l_q.Rotate (csVector3 (0,1,0));
  l_q.SetWithEuler (csVector3 (0.0f, 0.0f, 0.4f));
  l_q.Normalize ();
  l_v = l_q.Rotate (csVector3 (0,1,0));
  
    l_q.SetWithEuler (csVector3 (0.4f, 0.0f, 0.4f));
    l_q.Normalize ();
    l_v = l_q.Rotate (csVector3 (0,1,0));
    
      l_q.SetWithEuler (csVector3 (0.4f, 0.4f, 0.0f));
      l_q.Normalize ();
      l_v = l_q.Rotate (csVector3 (0,1,0));
      
  */

  if (!csInitializer::SetupVFS (g_objReg))
  {
    Report (CS_REPORTER_SEVERITY_ERROR,
      "crystalspace.application.SKE", "Failed to setup the VFS plugin!");
    return false;
  }//if

  //
  // The Virtual File System.
  m_vfs = CS_QUERY_REGISTRY (g_objReg, iVFS);
  if (!m_vfs)
  {
    SKE::Report (CS_REPORTER_SEVERITY_ERROR, "Can't find the VFS!");
    return false;
  }//if

  //
  //Mount some useful directories.
  MountDirectory ("/SKE", "$.$/data$/SKE$/");
  MountDirectory ("/SKE/model", "$.$/data$/SKE$/model$/");
  MountDirectory ("/SKE/texture", "$.$/data$/SKE$/texture$/");
  MountDirectory ("/SKE/aws", "$.$/data$/SKE$/aws$/");
  MountDirectory ("/SKE/mission", "$.$/data$/SKE$/mission$/");
  MountDirectory ("/SKE/terrain", "$.$/data$/SKE$/terrain$/");
  MountDirectory ("/SKE/font", "$.$/data$/SKE$/font$/");

  if (!csInitializer::SetupConfigManager (g_objReg, "/SKE/SKE.cfg"))
  {
    Report (CS_REPORTER_SEVERITY_ERROR,
      "crystalspace.application.SKE", "Failed to initialize config!");
    return false;
  }//if
  
  if (!csInitializer::RequestPlugins(g_objReg,
    CS_REQUEST_VFS,
    CS_REQUEST_OPENGL3D,
    //??CS_REQUEST_SOFTWARE3D,
    CS_REQUEST_ENGINE,
    CS_REQUEST_IMAGELOADER,
    CS_REQUEST_LEVELLOADER,
    CS_REQUEST_REPORTER,
    CS_REQUEST_REPORTERLISTENER,    
    CS_REQUEST_PLUGIN ("crystalspace.console.input.standard", iConsoleInput),
    CS_REQUEST_PLUGIN ("crystalspace.window.alternatemanager", iAws),
    CS_REQUEST_PLUGIN ("crystalspace.collisiondetection", iCollideSystem),
    CS_REQUEST_PLUGIN ("ske.device.windows.joystick", iKJoystick),
    CS_REQUEST_PLUGIN ("ske.device.tracker.windows.isense.intertrax2", iIntertrax2),
    CS_REQUEST_PLUGIN ("crystalspace.font.server.freetype2", iFontServer),//???????
    CS_REQUEST_PLUGIN ("crystalspace.documentsystem.tinyxml", iDocumentSystem),//???????
    CS_REQUEST_END))
  {
    SKE::Report (CS_REPORTER_SEVERITY_ERROR, "Can't initialize plugins!");
    return false;
  }//if

  // Check for commandline help.
  if (csCommandLineHelper::CheckHelp (g_objReg))
  {
    csCommandLineHelper::Help (g_objReg);
    return false;
  }//if
  
  
  // The virtual clock.
  m_vc = CS_QUERY_REGISTRY (g_objReg, iVirtualClock);
  if (!m_vc)
  {
    SKE::Report (CS_REPORTER_SEVERITY_ERROR, 
      "Can't find the virtual clock!");
    return false;
  }//if
  
  // Find the pointer to m_engine plugin
  m_engine = CS_QUERY_REGISTRY (g_objReg, iEngine);
  if (!m_engine)
  {
    csReport (g_objReg, CS_REPORTER_SEVERITY_ERROR,
    		"crystalspace.application.SKE","No iEngine plugin!");
    return false;
  }//if
  
  m_loader = CS_QUERY_REGISTRY (g_objReg, iLoader);
  if(!m_loader)
  {
    SKE::Report (CS_REPORTER_SEVERITY_ERROR, "No iLoader plugin!");
    return false;
  }
  
  m_imageIO = CS_QUERY_REGISTRY (g_objReg, iImageIO);
  if(!m_imageIO)
  {
    SKE::Report (CS_REPORTER_SEVERITY_ERROR, "No iImageIO plugin!");
    return false;
  }
  
  m_g2d = CS_QUERY_REGISTRY (g_objReg, iGraphics2D);
  if(!m_g2d)
  {
    SKE::Report (CS_REPORTER_SEVERITY_ERROR, "No iGraphics2D plugin!");
    return false;
  }//if
  
  m_g3d = CS_QUERY_REGISTRY (g_objReg, iGraphics3D);
  if(!m_g3d)
  {
    SKE::Report (CS_REPORTER_SEVERITY_ERROR,
      "No iGraphics3D plugin!");
    return false;
  }//if
  
  m_kbd = CS_QUERY_REGISTRY (g_objReg, iKeyboardDriver);
  if (!m_kbd)
  {
    SKE::Report (CS_REPORTER_SEVERITY_ERROR,
      "No iKeyboardDriver plugin!");
    return false;
  }
   
  m_consoleInput = CS_QUERY_REGISTRY (g_objReg, iConsoleInput);
  if(!m_consoleInput)
  {
    SKE::Report (CS_REPORTER_SEVERITY_WARNING,
      "No iConsoleInput plugin!");
  }

  m_consoleOutput=CS_QUERY_REGISTRY(g_objReg,iConsoleOutput);
  if(!m_consoleOutput)
  {
    SKE::Report (CS_REPORTER_SEVERITY_WARNING,
      "No iConsoleOutput plugin!");
  }
  
  m_collisionDet=CS_QUERY_REGISTRY(g_objReg,iCollideSystem);
  if(!m_collisionDet)
  {
    SKE::Report (CS_REPORTER_SEVERITY_WARNING,
      "No iCollideSystem plugin!");
  }
  
  m_joyDriver = CS_QUERY_REGISTRY (g_objReg, iJoystickDriver);
  if (!m_joyDriver)
  {
    SKE::Report (CS_REPORTER_SEVERITY_WARNING, 
      "No iJostickDriver plugin!");
  }//if

  m_joy = CS_QUERY_REGISTRY (g_objReg, iKJoystick);
  if (!m_joy)
  {
    SKE::Report (CS_REPORTER_SEVERITY_WARNING, 
      "No iKJostick plugin!");
  }//if
  
  m_aws = CS_QUERY_REGISTRY (g_objReg, iAws);
  if(!m_aws)
  {
    SKE::Report (CS_REPORTER_SEVERITY_WARNING, "No iAws plugin!");
  }//if
  
  m_intertrax2 = CS_QUERY_REGISTRY (g_objReg, iIntertrax2);
  if (!m_intertrax2)
  {
    SKE::Report (CS_REPORTER_SEVERITY_WARNING, "No iIntertrax2 plugin!");
  }//if
  
  // Find the font we'll use.
  m_font = m_g2d->GetFontServer ()->LoadFont("Verdana", 8);
  
  //
  //Init the console output.
  m_consoleOutput->SetVisible (false);
  m_consoleOutput->AutoUpdate (true);
  m_consoleOutput->Clear ();
  m_consoleOutput->SetFont (m_font);
  
  //
  //Set the title of the window.
  iNativeWindow* l_nW = m_g2d->GetNativeWindow ();
  if(l_nW)
    l_nW->SetTitle ("S.K.E.");
  
  //
  // Open the main system. This will open all the previously loaded plug-ins.
  if (!csInitializer::OpenApplication (g_objReg))
  {
    SKE::Report (CS_REPORTER_SEVERITY_ERROR, "Error opening system!");
    return false;
  }//if

  //
  //Init the UI.
  m_aws->SetupCanvas (0, m_g2d, m_g3d); 
  m_aws->SetFlag (AWSF_AlwaysRedrawWindows);
  m_aws->GetPrefMgr ()->SetDefaultFont (m_font);
  //create the unique&global sink.
  iAwsSink* l_sink = m_aws->GetSinkMgr ()->CreateSink ((void*)this);
  
  //
  //page: Lighting tab.
  l_sink->RegisterTrigger ("GetLightListLB", &GetLightListLB);
  l_sink->RegisterTrigger ("GetPosXTB", &GetPosXTB);
  l_sink->RegisterTrigger ("GetPosYTB", &GetPosYTB);
  l_sink->RegisterTrigger ("GetPosZTB", &GetPosZTB);
  l_sink->RegisterTrigger ("GetRadiusTB", &GetRadiusTB);
  l_sink->RegisterTrigger ("GetRedTB", &GetRedTB);
  l_sink->RegisterTrigger ("GetGreenTB", &GetGreenTB);
  l_sink->RegisterTrigger ("GetBlueTB", &GetBlueTB);
  l_sink->RegisterTrigger ("GetStaticRB", &GetStaticRB);
  l_sink->RegisterTrigger ("GetPseudodynamicRB", &GetPseudodynamicRB);
  l_sink->RegisterTrigger ("GetDynamicRB", &GetDynamicRB);
  l_sink->RegisterTrigger ("GetNoneAttRB", &GetNoneAttRB);
  l_sink->RegisterTrigger ("GetLinearAttRB", &GetLinearAttRB);
  l_sink->RegisterTrigger ("GetInverseAttRB", &GetInverseAttRB);
  l_sink->RegisterTrigger ("GetRealisticAttRB", &GetRealisticAttRB);
  l_sink->RegisterTrigger ("GetCLQAttRB", &GetCLQAttRB);

  l_sink->RegisterTrigger ("LSelectionChanged", &LSelectionChanged);
  l_sink->RegisterTrigger ("Relight", &Relight);
  l_sink->RegisterTrigger ("CreateLight", &CreateLight);
  l_sink->RegisterTrigger ("DestroyLight", &DestroyLight);

  //
  //page: Mission tab.
  l_sink->RegisterTrigger ("GetTargetRB", &GetTargetRB);
  l_sink->RegisterTrigger ("PutTargetRB", &PutTargetRB);
  l_sink->RegisterTrigger ("GetFreeWalkingRB", &GetFreeWalkingRB);
  l_sink->RegisterTrigger ("PutFreeWalkingRB", &PutFreeWalkingRB);
  l_sink->RegisterTrigger ("GetNotFreeWalkingRB", &GetNotFreeWalkingRB);
  l_sink->RegisterTrigger ("PutNotFreeWalkingRB", &PutNotFreeWalkingRB);
  l_sink->RegisterTrigger ("GetPointingTargetRB", &GetPointingTargetRB);
  l_sink->RegisterTrigger ("PutPointingTargetRB", &PutPointingTargetRB);
  l_sink->RegisterTrigger ("GetMissionAllowedTimeTB", &GetMissionAllowedTimeTB);
  l_sink->RegisterTrigger ("StartMission", &StartMission);
  l_sink->RegisterTrigger ("EndMission", &EndMission);
  l_sink->RegisterTrigger ("StopSaveMission", &StopSaveMission);
  l_sink->RegisterTrigger ("MTargetSelectionChanged", &MTargetSelectionChanged);
  l_sink->RegisterTrigger ("GetTargetListLB", &GetTargetListLB);
  l_sink->RegisterTrigger ("GetSaveMissionTB", &GetSaveMissionTB);
  l_sink->RegisterTrigger ("DiscardDataCB", &DiscardDataCB);
  
  //
  //page: Player Configuration tab.
  l_sink->RegisterTrigger ("GetHeightPlayerTB", &GetHeightPlayerTB);
  l_sink->RegisterTrigger ("GetFrictionPlayerTB", &GetFrictionPlayerTB);
  l_sink->RegisterTrigger ("GetAccKPlayerTB", &GetAccKPlayerTB);
  l_sink->RegisterTrigger ("GetMaxVelPlayerTB", &GetMaxVelPlayerTB);
  l_sink->RegisterTrigger ("GetFOVAnglePlayerTB", &GetFOVAnglePlayerTB);
  l_sink->RegisterTrigger ("GetFOVWidthPlayerTB", &GetFOVWidthPlayerTB);
  l_sink->RegisterTrigger ("GetXPlayerTB", &GetXPlayerTB);
  l_sink->RegisterTrigger ("GetZPlayerTB", &GetZPlayerTB);
  l_sink->RegisterTrigger ("GetAnglePlayerTB", &GetAnglePlayerTB);  
  
  l_sink->RegisterTrigger ("InitPosSelectionChanged", &InitPosSelectionChanged);
  l_sink->RegisterTrigger ("GetInitPosListLB", &GetInitPosListLB);
  l_sink->RegisterTrigger ("GetInitPosNameTB", &GetInitPosNameTB );  
  l_sink->RegisterTrigger ("LoadInitPos", &LoadInitPos);
  l_sink->RegisterTrigger ("SaveInitPos", &SaveInitPos);
  l_sink->RegisterTrigger ("DeleteInitPos", &DeleteInitPos);
  
  //
  //page: K Configuration.
  l_sink->RegisterTrigger ("GetSkyBoxCB", &GetSkyBoxCB);
//?????Disabled until some1 will fix the terrain related code!  l_sink->RegisterTrigger ("GetTerrainCB", &GetTerrainCB);
  l_sink->RegisterTrigger ("GetDebugModeCB", &GetDebugModeCB);
  l_sink->RegisterTrigger ("GetLightOntoHeadCB", &GetLightOntoHeadCB);
  l_sink->RegisterTrigger ("GetUseJoystickCB", &GetUseJoystickCB);
  l_sink->RegisterTrigger ("GetSkyBoxHourTB", &GetSkyBoxHourTB);
  l_sink->RegisterTrigger ("GetLandscapeRB", &GetLandscapeRB);
  l_sink->RegisterTrigger ("GetSunRB", &GetSunRB);
  l_sink->RegisterTrigger ("PutLandscapeRB", &PutLandscapeRB);
  l_sink->RegisterTrigger ("PutSunRB", &PutSunRB);
  l_sink->RegisterTrigger ("GetUseDynaVisCB", &GetUseDynaVisCB);
  l_sink->RegisterTrigger ("GetShowCloudsCB", &GetShowCloudsCB);
  l_sink->RegisterTrigger ("Exit", &Exit);
  l_sink->RegisterTrigger ("GetAmbientRedTB", &GetAmbientRedTB);
  l_sink->RegisterTrigger ("GetAmbientGreenTB", &GetAmbientGreenTB);
  l_sink->RegisterTrigger ("GetAmbientBlueTB", &GetAmbientBlueTB);  
  l_sink->RegisterTrigger ("GetDynAmbientRedTB", &GetDynAmbientRedTB);
  l_sink->RegisterTrigger ("GetDynAmbientGreenTB", &GetDynAmbientGreenTB);
  l_sink->RegisterTrigger ("GetDynAmbientBlueTB", &GetDynAmbientBlueTB);  
  //
  //page: Landmark
  l_sink->RegisterTrigger ("LoadLM", &LoadLM);
  l_sink->RegisterTrigger ("SaveLM", &SaveLM);
  l_sink->RegisterTrigger ("DeleteLM", &DeleteLM);
  l_sink->RegisterTrigger ("GetLandmarksNameTB", &GetLandmarksNameTB);
  l_sink->RegisterTrigger ("GetLandmarksListLB", &GetLandmarksListLB);
  l_sink->RegisterTrigger ("LMSSelectionChanged", &LMSSelectionChanged);
  l_sink->RegisterTrigger ("CreateLM", &CreateLM);
  l_sink->RegisterTrigger ("DestroyLM", &DestroyLM);
  l_sink->RegisterTrigger ("LMSelectionChanged", &LMSelectionChanged);
  l_sink->RegisterTrigger ("LMCreatedSelectionChanged", &LMCreatedSelectionChanged);
  l_sink->RegisterTrigger ("GetLandmarkToCreateLB", &GetLandmarkToCreateLB);
  l_sink->RegisterTrigger ("GetCreatedLMListLB", &GetCreatedLMListLB);
  l_sink->RegisterTrigger ("GetPositionXLMTB", &GetPositionXLMTB);
  l_sink->RegisterTrigger ("GetPositionYLMTB", &GetPositionYLMTB);
  l_sink->RegisterTrigger ("GetPositionZLMTB", &GetPositionZLMTB);
  l_sink->RegisterTrigger ("GetSizeXLMTB", &GetSizeXLMTB);
  l_sink->RegisterTrigger ("GetSizeYLMTB", &GetSizeYLMTB);
  l_sink->RegisterTrigger ("GetSizeZLMTB", &GetSizeZLMTB);
  l_sink->RegisterTrigger ("GetMaterialLB", &GetMaterialLB);
  l_sink->RegisterTrigger ("MaterialSelectionChanged", &MaterialSelectionChanged);
  
  //
  //page: Editor
  l_sink->RegisterTrigger ("SaveE", &SaveE);
  l_sink->RegisterTrigger ("LoadE", &LoadE);
  l_sink->RegisterTrigger ("NewMap", &NewMap);
  l_sink->RegisterTrigger ("GetMapXTB", &GetMapXTB);
  l_sink->RegisterTrigger ("GetMapZTB", &GetMapZTB);
  l_sink->RegisterTrigger ("GetLevelNameTB", &GetLevelNameTB);
  l_sink->RegisterTrigger ("GetLevelsListLB", &GetLevelsListLB);
  l_sink->RegisterTrigger ("DestroyE", &DestroyE);
  l_sink->RegisterTrigger ("ESelectionChanged", &ESelectionChanged);
  l_sink->RegisterTrigger ("I1", &I1);
  l_sink->RegisterTrigger ("I2", &I2);
  l_sink->RegisterTrigger ("L1", &L1);
  l_sink->RegisterTrigger ("L2", &L2);
  l_sink->RegisterTrigger ("L3", &L3);
  l_sink->RegisterTrigger ("L4", &L4);
  l_sink->RegisterTrigger ("T1", &T1);
  l_sink->RegisterTrigger ("T2", &T2);
  l_sink->RegisterTrigger ("F", &F);
  l_sink->RegisterTrigger ("C", &C);
  l_sink->RegisterTrigger ("D1", &D1);
  l_sink->RegisterTrigger ("D2", &D2);
  
  //page: Path
  l_sink->RegisterTrigger ("PathApply", &PathApply);
  l_sink->RegisterTrigger ("LoadPath", &LoadPath);
  l_sink->RegisterTrigger ("SavePath", &SavePath);
  l_sink->RegisterTrigger ("DeletePath", &DeletePath);
  l_sink->RegisterTrigger ("GetPathNameTB", &GetPathNameTB);
  l_sink->RegisterTrigger ("GetPathPathLB", &GetPathPathLB);
  l_sink->RegisterTrigger ("PathSelectionChangedPath", &PathSelectionChangedPath);
  l_sink->RegisterTrigger ("StartCreatingPath", &StartCreatingPath);
  l_sink->RegisterTrigger ("StopPathCreation", &StopPathCreation);
  l_sink->RegisterTrigger ("DeleteCurrentPath", &DeleteCurrentPath);
  l_sink->RegisterTrigger ("GetPathToleranceTB", &GetPathToleranceTB);
  
  
  //dialog: Replay
  l_sink->RegisterTrigger ("GetTargetNameL", &GetTargetNameL);
  l_sink->RegisterTrigger ("GetTimeL", &GetTimeL);
  l_sink->RegisterTrigger ("GetPathNameL", &GetPathNameL);
  l_sink->RegisterTrigger ("GetLmListNameL", &GetLmListNameL);
  l_sink->RegisterTrigger ("GetMissionTypeL", &GetMissionTypeL);
  l_sink->RegisterTrigger ("GetMissionNameL", &GetMissionNameL);
  l_sink->RegisterTrigger ("GetInitPosNameL", &GetInitPosNameL);
  l_sink->RegisterTrigger ("GetLevelNameL", &GetLevelNameL);
  l_sink->RegisterTrigger ("MissionSelectionChangedLB", 
    &MissionSelectionChangedLB);
  l_sink->RegisterTrigger ("GetMissionLB", &GetMissionLB);
  l_sink->RegisterTrigger ("StartReplay", &StartReplay);
  l_sink->RegisterTrigger ("StopReplay", &StopReplay);
  
  //page: Task
  l_sink->RegisterTrigger ("TaskSelectionChangedLB", &TaskSelectionChangedLB);
  l_sink->RegisterTrigger ("GetTaskLB", &GetTaskLB);
  l_sink->RegisterTrigger ("GetSaveTaskTB", &GetSaveTaskTB);
  l_sink->RegisterTrigger ("DeleteTask", &DeleteTask);
  l_sink->RegisterTrigger ("SaveTask", &SaveTask);
  l_sink->RegisterTrigger ("LoadTask", &LoadTask);
  
  //
  //listeners for the Ok,Cancel,Apply buttons.
  l_sink->RegisterTrigger ("Apply", &Apply);      
  l_sink->RegisterTrigger ("Ok", &Ok);      
  l_sink->RegisterTrigger ("Cancel", &Cancel);      
  //
  //register the unique and global sink.
  m_aws->GetSinkMgr ()->RegisterSink ("KSink", l_sink);
  
  //
  // now load preferences
  if (!m_aws->GetPrefMgr()->Load ("/SKE/aws/windows_skin.def"))
    csReport(g_objReg,CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.SKE",
    "couldn't load definition file!");
  if (!m_aws->GetPrefMgr()->Load ("/SKE/aws/uiNEW.def"))//hacked????HACKED!!!!
    csReport(g_objReg,CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.SKE",
    "couldn't load definition file!");
  if (!m_aws->GetPrefMgr()->Load ("/SKE/aws/uiREPLAY.def"))
    csReport(g_objReg,CS_REPORTER_SEVERITY_ERROR, "crystalspace.application.SKE",
    "couldn't load definition file!");
  
  m_aws->GetPrefMgr()->SelectDefaultSkin ("Windows");//set the skin.
  m_plConfWnd = m_aws->CreateWindowFrom ("SKE");//create the window.
  m_replayWnd = m_aws->CreateWindowFrom ("REPLAY");//create the window.
  
  

  //
  //Setup the render priorities for the engine.
  m_engine->RegisterRenderPriority ("sky", 1);
  m_engine->RegisterRenderPriority ("skyclouds", 2);
  m_engine->RegisterRenderPriority ("wall", 3);
  m_engine->RegisterRenderPriority ("object", 4);
  m_engine->RegisterRenderPriority ("alpha", 5, 
    CS_RENDPRI_SORT_BACK2FRONT);//??<sort>BACK2FRONT</sort>
  
  //
  //Create the sectors.
  m_world = m_engine->CreateSector ("world");
  m_hiddenWorld = m_engine->CreateSector ("hiddenWorld");
  
  //
  //Setup the ambient color for the engine.
  m_engine->SetAmbientLight (csColor (.3f, .3f, .3f));
  m_world->SetDynamicAmbientLight (csColor (.3f, .3f, .3f));
  
  //
  // Setup the texture manager.
  iTextureManager* txtmgr = m_g3d->GetTextureManager ();

  //
  //Init what we need to init: joystick, collisiondet, intertrax2, mouse, 
  //player,  terrain, skybox, m_savedDataMan, m_blockIdSelected.
  //

  //joy:
  m_joyDriver->Reset ();
  if ((m_joy) && (m_joy->IsActive ()))
  {
    Report (CS_REPORTER_SEVERITY_NOTIFY, "Joystick is available!");
  }//if
  else
  {
    Report (CS_REPORTER_SEVERITY_WARNING, "Joystick is not available!");
  }//else

  //colldet:
  m_collisionDet->SetOneHitOnly (false);
  
  //it2
  if ((m_intertrax2) && (m_intertrax2->Open ()))//try using intertrax2.
  {
    Report (CS_REPORTER_SEVERITY_NOTIFY, "Intertrax2 is available!");
  }//if
  else
  {
    Report (CS_REPORTER_SEVERITY_WARNING, "Intertrax2 is not available!");
  }//else

  //
  //Create the player meshes.
  m_player.AttachNew (new KPlayer ());
  m_player->Initialize ();
  m_player->SetPosition (csVector3 (0, 0.0f, 0.0f));
  
  
  
  //
  //Create the skybox.
  m_skyBox = new SkyBox ();
  m_skyBox->Initialize (0);
  m_skyBox->SetSector (m_world);
  
  //
  //Create the saved data manager (like a DataBase).
  m_savedDataMan.AttachNew (new KSavedDataManager ());

  void FillTheLMList();//??
  FillTheLMList();//??


  //
  //Create the terrain.
//?????Disabled until some1 will fix the terrain related code!  m_terrain = new KTerrain ();
//?????Disabled until some1 will fix the terrain related code!  m_terrain->Initialize ();
//?????Disabled until some1 will fix the terrain related code!  m_terrain->SetInvisible (true);

  //
  //Create the signer..
  m_sign = new KSign ();
  m_sign->Initialize (); 

  //
  //Create the mode viewer..
  mMode = new KMode ();
  mMode->Initialize (); 

  //
  //Create the cursor.
  m_cursor.AttachNew (new KCursor3D ());
  m_cursor->Initialize ();
  


  
  //
  //Init the m_initPos object.
  m_initPos.SetPosition (csVector3 (0, 0.0f, 0.0f));
  m_initPos.SetName ("no-name");
  
  //
  //create the map.
  m_map.AttachNew (new KMap (m_world));
  
  //
  //Create the path.
  m_path.AttachNew (new KPath ());
  m_path->SetName ("no-name");

    //
  //Create the list of KLandmark
  m_listLM.AttachNew (new KLandmarkList ());
  m_listLM->SetName ("no-name");

  //
  //create the 2d view.
  m_kcam = new KCamera ();
  m_kcam->SetSector (m_world);
  m_kcam->SetPositionRotation (csVector3 (0,0,0), csMatrix3 ());
  m_kcam->SetState (EDITING);
  m_kcam->SetTracked (m_player);
   
  //
  // Initialize the command processor with the engine and camera.
  KCommandProcessor::Initialize (m_kcam->GetCamera (),
    m_consoleOutput);
  KCommandProcessor::s_extraHandler = &SKE::CommandHandlerBridge;


  //Update the Lighting page.//??????????? CRAP!
  Create5Lights ();//??????????? CRAP!
  








/*  
  // create a snow factory wrapper
  imeshfact_snow = m_engine->CreateMeshFactory("crystalspace.mesh.object.snow",
    "snow factory");
  
  if (!imeshfact_snow) 
    return false;

  snow  =m_engine->CreateMeshWrapper (imeshfact_snow, "custom snow", this->m_world,
    csVector3 (1, 1, 1));
  snow->SetZBufMode(CS_ZBUF_TEST);
  
  csBox3 bbox;
  //??m_world->CalculateSectorBBox (bbox, true);
  
  csVector3 maxi (csVector3 (1, 2, 1));//??= bbox.Max();
  csVector3 mini (csVector3 (-1, 0, -1));//??= bbox.Min();
  
  char count[1024];
  sprintf(count, "min.x = %f, min.y = %f, min.z = %f, max.x = %f, max.y = %f, max.z = %f", 
    mini.x, mini.y, mini.z, maxi.x, maxi.y, maxi.z);
  
  csRef<iParticleState> partstate (SCF_QUERY_INTERFACE (snow->GetMeshObject (), iParticleState));
  partstate->SetMaterialWrapper (this->m_engine->GetMaterialList ()->FindByName ("ball"));
  partstate->SetMixMode (CS_FX_ADD);
  partstate->SetColor (csColor (1.0,1.0,1.0));
  
  
  csRef<iSnowState> snowstate (SCF_QUERY_INTERFACE (snow->GetMeshObject (), iSnowState));
  snowstate->SetParticleCount (500);
  snowstate->SetDropSize (0.07f, 0.07f);
  snowstate->SetLighting (false);
  snowstate->SetBox (mini, maxi);//??bbox.Max(), bbox.Min());
  snowstate->SetFallSpeed (csVector3 (0, -20, 0));
  snowstate->SetSwirl (0.2f);
  */












  
  //Do not use lightmap cache at all!
  m_engine->SetLightingCacheMode (0);
  
  //
  // Prepare the engine. This will calculate all lighting and
  // prepare the lightmaps for the 3D rasterizer.
  csTextProgressMeter* l_meter = new csTextProgressMeter (m_consoleOutput);
  m_engine->Prepare (l_meter);
  delete l_meter;
  
    
  //
  // Start the 'autoexec.cfg' script and fully execute it.
  KCommandProcessor::StartScript ("/SKE/autoexec.cfg");
  char cmd_buf[512];
  while (KCommandProcessor::GetScriptLine (cmd_buf, 511))
    KCommandProcessor::_PerformLine (cmd_buf);
  
  //Toggle auto update.
  if (m_consoleOutput)
  {
    m_consoleOutput->SetVisible (false);
    m_consoleOutput->AutoUpdate (false);
    if (m_consoleInput)
    {
      m_consoleInput->Bind (m_consoleOutput);
      m_consoleInput->SetPrompt ("ske# ");
      csRef<KCommandProcessor::PerformCallback> lCb;
      lCb.AttachNew (new KCommandProcessor::PerformCallback ());
      m_consoleInput->SetExecuteCallback (lCb);
    }//if

    /*
    // Set console to center of screen, if supported
    int DeltaX = m_g2d->GetWidth () / 10;
    int DeltaY = m_g2d->GetHeight () / 10;
    SmallConsole = myConsole->PerformExtension ("SetPos", DeltaX, DeltaY,
    myG2D->GetWidth () - DeltaX * 2, myG2D->GetHeight () - DeltaY * 2);*/
  }
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  //
  //Create the default mission.
  m_mission.AttachNew (new KFreeWalkingMission ("default",
    &m_initPos,
    m_player,
    0, m_map, m_listLM, true));
  
  
  //Create the drag manager.
  m_dragManager.AttachNew (new KDragManager ());
  
  //Create the event handlers manager.
  m_evHndlrMan.AttachNew (new KEventHandlerManager ());
  
  
  //Create the mouse manager.
  m_mouseManager.AttachNew (new KMouseManager ());
  
  
  //
  //Setup a listener in the event queue.
  csRef<KEventHandlerHelper<SKE> > l_evH;
  l_evH.AttachNew (new KEventHandlerHelper<SKE> (this));
  
  m_evHndlrMan->AddEventHandler (l_evH,
    CSMASK_Nothing | CSMASK_Broadcast | CSMASK_MouseUp |
    CSMASK_MouseDown | CSMASK_MouseMove |
    CSMASK_Keyboard | CSMASK_MouseClick |
    CSMASK_MouseDoubleClick | CSMASK_JoystickMove |
    CSMASK_JoystickDown | CSMASK_JoystickUp,
    0);
  
  //
  //Create an event outlet to let us shooting events in the queue.
  csRef<KEventPlug> l_eventPlug;
  l_eventPlug.AttachNew (new KEventPlug ());
  csRef<iEventQueue> l_q (CS_QUERY_REGISTRY (g_objReg, iEventQueue));
  m_eventOutlet = l_q->CreateEventOutlet (l_eventPlug);

  //
  //Load the view-finder.
  mViewFinderMaterial = LoadTexture ("view_finder", "/SKE/texture/view_finder.bmp");
  mViewFinderMaterial->GetTextureHandle ()->SetKeyColor (255, 255, 255);
  mViewFinderMaterial->GetTextureHandle ()->SetKeyColor (true);
  //mViewFinderImage = CreateMaterial (lTW->GetTextureHandle (), "view_finder");
  //??mViewFinderImage = m_engine->GetMaterialList ()->FindByName ("view_finder");
  return true;
}

iTextureWrapper* SKE::LoadTexture (char const* pName, char const* pFileName)
{
  iTextureManager* lTxtMgr = m_g3d->GetTextureManager ();
  iTextureWrapper* lTxtW = m_loader->LoadTexture (pName, pFileName, CS_TEXTURE_3D,
    lTxtMgr, false, false);
  if (!lTxtW)
    SKE::Report (CS_REPORTER_SEVERITY_WARNING,
      "Error loading '%s' texture from file '%s'!", pName, pFileName);

  return lTxtW;
}

iMeshWrapper* SKE::HitMeshWrapper (const csVector3& l_fromW, 
  const csVector3& l_directionW, csVector3& p_hitPoint)
{
  csVector3 l_intersect;
  return (m_world->HitBeam (l_fromW, (l_directionW - l_fromW) *
    600.0f, p_hitPoint, 0));
}


bool SKE::CalculateIntersection (int p_x, int p_y, csPlane3 p_plane, 
  csVector3& pIntersection, float& pDistanceAlongSegment)
{
  //
  //Transform the point from (x, y) to (x',y',1)
  csVector3 l_v;
  csVector2 l_p (p_x, m_kcam->GetCamera ()->GetShiftY () * 2 - p_y - 1);
  
  m_kcam->GetCamera ()->InvPerspective (l_p, 1.0f, l_v);//z=1.0f is correct.
  csVector3 l_directionW = m_kcam->GetCamera ()->GetTransform ().This2Other (l_v);
  csVector3 l_eyeW = m_kcam->GetCamera ()->GetTransform ().GetO2TTranslation ();
  
  //
  //test for intersection between the segment and the plane.
  return csIntersect3::SegmentPlane 
    (l_eyeW, l_eyeW + (l_directionW - l_eyeW).Unit () * 600.0f, p_plane,
    pIntersection, pDistanceAlongSegment);
}   


void SKE::SetupFrame ()
{
  csVector3 l_intersection;//NOTE: this is useful also far below!!!
  static int s_lastTimestamp;//NOTE: this is useful also far below!!!

  // First get elapsed time from the virtual clock.
  csTicks elapsed_time = m_vc->GetElapsedTicks ();
  
  //
  //Adjust time.
  if (elapsed_time  == 0.0f)
    elapsed_time  = 10;
  if (elapsed_time  > 100)
    elapsed_time  = 100;
  
  float l_seconds = elapsed_time / 1000.0f;
  
  float speedRadians = (elapsed_time / 1000.0f) * (0.03f * 20);
  //convert 'speedRadians' from RADIANS to DEGREE.
  float speedDegree = RAD2DEG (speedRadians);
  

  //
  //KAppState::POINTINGBEFOREWALKING
  //
  if (m_appState == KAppState::POINTINGBEFOREWALKING)
  {
    
    //?? DISPLAY HERE AN IMAGE THAT IS SAYING: "LET LOOK TOWARDS and PRESS SPACEBAR TO START!"
    m_sign->SetDisplay (KSign::LOOK_TOWARDS);

    //
    //Reset the heading for the tracker.
    if ((m_intertrax2) && (m_intertrax2->IsOpen ()))
    {
      float a,b,c;
      m_intertrax2->GetData (a, b, c, true);
      m_intertrax2->ResetHeading(a, b, c);
    }//if
    
    //
    //The arrow must be always visible in this mode.
    m_player->ShowArrow (true);
    
    //
    //Look forward along the Z axis!
    KQuaternion l_q;
    l_q.SetWithEuler (csVector3 (0.f, 0.f, 0.f));
    m_player->SetHeadAngles (l_q);
    
    
    //
    //Set the camera state.
    m_kcam->SetState (POINTINGBEFOREWALKING);
    m_kcam->UpdatePosition (elapsed_time);


    //
    //Let's draw the sign (do this after setting the position of the camera!).
    m_sign->SetupFrame (m_kcam, elapsed_time);  
  }











  //
  //KAppState::EDITING
  //
  else if (m_appState == KAppState::EDITING) 
  {
    
    
    //??CRAP!
    //Make visible the target (useful only for LM_target, but it does not hurt
    //for any other target).
    if (0 != m_listLM->FindByName ("LM_target"))
      m_listLM->FindByName ("LM_target")->SetVisible (true);    
    
    
    //
    //Update the camera state and camera position.
    if (m_useJoy)
    {
      m_kcam->MoveForward (false);//??UGLY!
      m_kcam->MoveBack (false);//??UGLY!
      m_kcam->MoveLeft (false);//??UGLY!
      m_kcam->MoveRight (false);//??UGLY!
      
      if (m_joyDriver->GetLastY (0) > 0)
        m_kcam->MoveForward (true);
      else if (m_joyDriver->GetLastY (0) < 0)
        m_kcam->MoveBack (true);
      if (m_joyDriver->GetLastX (0) > 0)
        m_kcam->MoveRight (true);
      else if (m_joyDriver->GetLastX (0) < 0)
        m_kcam->MoveLeft (true);
    }//if
    
    
    
    
    //
    //The arrow and the head must be always visible in this mode.
    m_player->ShowArrow (true);
    m_player->ShowHead (true);


    //
    //Set the position m_initPos to the player object.
    m_player->SetPosition (m_initPos.GetPosition ());
    m_player->SetBodyAngle (m_initPos.GetBodyAngle ());

    m_kcam->SetState (EDITING);
    m_kcam->UpdatePosition (elapsed_time);
  }//if
  
  
  
  
  
  




  //
  //KAppState::REPLAY
  //
  else if (m_appState == KAppState::REPLAY)
  {
    //
    //update the camera state and camera position.
    if (m_useJoy)
    {
      m_kcam->MoveForward (false);//??UGLY!
      m_kcam->MoveBack (false);//??UGLY!
      m_kcam->MoveLeft (false);//??UGLY!
      m_kcam->MoveRight (false);//??UGLY!
      
      if (m_joyDriver->GetLastY (0) > 0)
        m_kcam->MoveForward (true);
      else if (m_joyDriver->GetLastY (0) < 0)
        m_kcam->MoveBack (true);
      if (m_joyDriver->GetLastX (0) > 0)
        m_kcam->MoveRight (true);
      else if (m_joyDriver->GetLastX (0) < 0)
        m_kcam->MoveLeft (true);
    }//if
    
    int l_camState = m_kcam->GetState ();
    m_player->ShowArrow (!(l_camState == THIRD));
    m_player->ShowHead (!(l_camState == FIRST));
    
    
    //
    //Check for boundaries regarding the current replay time.
    KDataList* l_dL = m_mission->GetDataList ();
    s_lastTimestamp = l_dL->GetLastSampleTimestamp ();
    
    m_replayMsecs += elapsed_time * m_replaySpeed;
    if (m_replayMsecs < 0)
      m_replayMsecs = 0;
    else if (m_replayMsecs > s_lastTimestamp)
      m_replayMsecs = s_lastTimestamp;
    
    //
    //Get the position, orientation of the player.
    csVector3 l_pos;
    KQuaternion l_hQ;
    KQuaternion l_bQ;
    csVector3 l_vel;
    
    l_dL->GetAtTime (m_replayMsecs, l_pos, l_hQ, l_bQ, l_vel);
    m_player->SetPosition (l_pos);
    m_player->SetHeadAngles (l_hQ);
    m_player->SetBodyAngle (l_bQ);
    
    m_kcam->UpdatePosition (elapsed_time);
  }//REPLAY
  
  
  
  
  
  
  
  
  //
  //KAppState::WALKING
  //
  else if (m_appState == KAppState::WALKING)
  {
    
    //
    //Handling of the head movements.
    this->HandlePlayerHeadMovement (speedRadians);
    
    //
    //Handling of the mission.
    
    //Get the mission type.
    KMissionType const& l_missionType = m_mission->GetMissionType ();
    
    if (l_missionType == KMissionType::FREEWALKING)
    {
      m_player->CalculatePlayerAcceleration (true, true, speedRadians);
        
      csRef<iKFreeWalkingMission> l_mission = SCF_QUERY_INTERFACE 
        (this->m_mission, iKFreeWalkingMission);
        
        //
        //Check if the max allowed time is passed.
        float l_minutes = l_mission->GetAllowedMinutes ();
        if (l_minutes > 0 && (l_minutes <= (m_timePassed / 1000.0f) / 60.0f))
        {
          //
          //DISPLAY AN IMAGE SAYING: "tempo scaduto"
          m_sign->SetDisplay (KSign::TIME_EXPIRED);
          m_appState = KAppState::STANDING;
          
          SKE::Report (CS_REPORTER_SEVERITY_NOTIFY, 
            "Time expired (%7.03f minutes)!", l_minutes);
        }//if
    }//if
    else if (l_missionType == KMissionType::NOTFREEWALKING)
      {
        static bool l_stop = false;
        
        if (l_stop)
        {
          l_stop = false;
          
          //DISPLAY AN IMAGE SAYING: "percorso completato"
          m_sign->SetDisplay (KSign::PATH_COMPLETED);
          m_appState = KAppState::STANDING;
          
          SKE::Report (CS_REPORTER_SEVERITY_NOTIFY, "Path Completed!");          
        }//if
        else
        {
        csRef<iKNotFreeWalkingMission> l_mission = SCF_QUERY_INTERFACE 
          (this->m_mission, iKNotFreeWalkingMission);
        
        float l_totalTime = l_mission->GetPath ()->GetDurationTime (g_ske->
          m_player->m_mov3d.GetMaxVelocity () / 2.0f);
        
        if (l_totalTime <= m_timePassed / 1000.0f)
        {
          m_timePassed = l_totalTime * 1000.0f;
          l_stop = true;
        }//if
        
        csVector3 l_pos;
        csVector3 l_for;
        csVector3 l_up;
        
        l_mission->GetPath ()->GetPositionAtTime (&l_pos, &l_for, &l_up, 
          m_timePassed / (l_totalTime * 1000.f));
        
        float l_angle = Vector2Angle (l_for, csVector3 (0, 0, 1));
        
        m_player->SetPosition (l_pos);//????
        KQuaternion l_q;
        l_q.SetWithEuler (csVector3 (-l_angle, 0, 0));//?????WHY THE MINUS!?!?!?!
        l_q.Normalize ();
        m_player->SetBodyAngle (l_q);
        m_player->SetWalking (true);
        }//else
      }//else if
    else if (l_missionType == KMissionType::POINTINGTARGET)
      {
        m_player->CalculatePlayerAcceleration (false, true, speedRadians);
        
      }//else if
    else if (l_missionType == KMissionType::TARGETING)
      {
        m_player->CalculatePlayerAcceleration (true, true, speedRadians);
        
        csRef<iKTargetingMission> l_mission = SCF_QUERY_INTERFACE
          (this->m_mission, iKTargetingMission);
        
        //Get the path follower.
        KPathFollower* l_pF = l_mission->GetPathFollower ();
        
        //
        //Check for time expiring.
        float l_minutes = l_mission->GetAllowedMinutes ();
        if ((l_minutes > 0) &&//if there is a time limit
          (l_minutes < m_timePassed / 1000.0f /60.f))
        {
          m_sign->SetDisplay (KSign::TIME_EXPIRED);
          m_appState = KAppState::STANDING;
        }//if
        
        
        //
        //Get the next position of the player.
        csVector3 l_position = m_player->GetPosition ();
        csVector3 l_mov = m_player->GetNextWalkingStep (l_seconds);
        l_position += l_mov;
        
        //
        //Check for collision with the target.
        //Check only if we reached the last segment along the path.
        if ((0 != l_pF) && (l_pF->IsLastSegmentBeingTouched ())
          || (0 == l_pF) )
        {
          //
          //Get the colliders.
          csRefArray<iCollider>* l_colls;
          l_colls = l_mission->GetColliders ();
          
          //
          //Get the transformations
          csArray<csReversibleTransform> l_rTS;
          l_mission->GetTarget ()->GetReversibleTransform (l_rTS);
          csMatrix3 m;
          csReversibleTransform l_rT2 (m, l_position);
          
          size_t i;
          for (i = 0; i < l_colls->Length (); i++)
          {
            m_collisionDet->ResetCollisionPairs ();
            if (this->m_collisionDet->Collide (l_colls->Get (i), &l_rTS.Get (i), 
              m_player->GetBodyColliderWrapper ()->GetCollider (), &l_rT2))
            {
              //???? TODO:add the correct test
              //Check if we look towards the target, if not, although we are touching it,
              //we *have* not reached it yet. We must look at max 45 degree away
              //related to one of the ksprite3d center point.
              csVector3 l_targetPos = l_mission->GetTarget()->GetPosition ();
              csVector3 l_towardsTargetVector (l_targetPos - l_position);
              
              SKE::Report (CS_REPORTER_SEVERITY_NOTIFY, 
                "Target found (%s)!", l_mission->GetTarget ()->GetName ());
              
              //DISPLAY AN IMAGE SAYING: "obiettivo raggiunto"
              m_sign->SetDisplay (KSign::TARGET_REACHED);
              m_appState = KAppState::STANDING;
            }//if
          }//for
        }//if
        
        //
        //Check for the path, if any.
        KPath* l_path = l_mission->GetPath ();
        if (0 != l_path)
        {
          csVector3 l_intersection;
          
          CS_ASSERT (0 != l_pF);
          l_pF->AddPosition (l_position, l_intersection, l_seconds);
          
          if (l_pF->IsPathLeft ())
          {
            //
            //DISPLAY AN IMAGE SAYING: "Wrong way!".
            m_sign->SetDisplay (KSign::WRONG_WAY);
            m_appState = KAppState::STANDING;
            
            SKE::Report (CS_REPORTER_SEVERITY_NOTIFY, "Wrong way!");
          }//if
        }//if
        
      }//else if
    
    //
    //Collect the time passed, and let the scheduler know.
    m_mission->Record (elapsed_time);
    
    //
    //Collect the current time of the mission.
    m_timePassed += elapsed_time;
    
    //?? UGLY CODE BEGINS
    if (l_missionType != KMissionType::NOTFREEWALKING)
    {
      //
      //Handle phisics of the walking.
      m_player->Walk (l_seconds);//??      
    }//?? UGLY CODE ENDS
    
    
    //
    //The arrow and the head must be always visible?
    int l_camState = m_kcam->GetState ();
    m_player->ShowArrow (!(l_camState == THIRD));
    m_player->ShowHead (!(l_camState == FIRST));
    
    //
    //Update the camera position.
    m_kcam->UpdatePosition (elapsed_time);
    

    
  }//else if WALKING
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  else if (m_appState == KAppState::STANDING)
  {
    //
    this->HandlePlayerHeadMovement (speedRadians);
    
    //
    m_player->SetWalking (false);
    
    
    
    //
    //Stay in this state for max 10 seconds (you can
    //exit beforeward hitting the SPACEBAR key)
    static float l_secondsPassed;
    
    l_secondsPassed += elapsed_time / 1000.0f;
    if (l_secondsPassed > 10.0f)
    {
      l_secondsPassed = 0.0f;
      KCommandProcessor::_PerformLine ("stopsave_mission");
    }//if
    
    //
    //The arrow and the head must be always visible?
    int l_camState = m_kcam->GetState ();
    m_player->ShowArrow (!(l_camState == THIRD));
    m_player->ShowHead (!(l_camState == FIRST));
    
    
    //
    //Update the camera position.
    m_kcam->UpdatePosition (elapsed_time);
    
    //
    //Let's draw the sign (do this after setting the position of the camera!).
    m_sign->SetupFrame (m_kcam, elapsed_time);
    

  }//else if STANDING
  
  
  
  
  
  
  
  
  
  
  
  //
  //Show/Hide the path as needed.
  if (m_appState == KAppState::EDITING)
  { 
    if (m_path) 
      m_path->SetInvisible (false); 
    if (m_walkedPath) 
      m_walkedPath->SetInvisible (false); 
  }
  else if (m_appState == KAppState::REPLAY)
  {
    if (m_path)
      m_path->SetInvisible (false);
    if (m_walkedPath)
    {
      m_walkedPath->SetInvisible (false);
      m_walkedPath->SetBallInvisible (true);
    }
  }
  else if (mDebugMode)
  {
    if (m_path)
      m_path->SetInvisible (false);
    if (m_walkedPath)
      m_walkedPath->SetInvisible (false);
  }//else if
  else
  {
    if (m_path)
      m_path->SetInvisible (true);
    if (m_walkedPath)
      m_walkedPath->SetInvisible (true);
  }//else if
    
  //
  //Update the skydome.
  m_skyBox->SetupFrame (elapsed_time);

  //
  //Update the skydome.
  /*m_terrain->SetInvisible(!m_drawTerrain);
  m_terrain->SetupFrame ();//????????????*/

  //
  //Let's mode the mode (do this after setting the position of the camera!).
  mMode->SetupFrame (m_kcam, elapsed_time);

  //
  //Update the player.
  m_player->SetupFrame ();

  //
  //If the skybox is not drawn, then clear the zbuffer yourself.
  static int  l_myFlags;
  l_myFlags = (!m_skyBox->IsInvisible () ? CSDRAW_CLEARSCREEN | CSDRAW_CLEARZBUFFER : 0);
  
  // Tell 3D driver we're going to display 3D things.
  if(!m_g3d->BeginDraw(m_engine->GetBeginDrawFlags() | CSDRAW_3DGRAPHICS | l_myFlags ) )
    return;
  
  // Tell the camera to render into the frame buffer.
  m_kcam->Draw();
  
  // Tell 2D driver we're going to display 2D things.
  if(!m_g3d->BeginDraw (CSDRAW_2DGRAPHICS))
    return;
  
  
  //draw the console output.
  m_consoleOutput->SetTransparency (true);
  m_consoleOutput->Draw2D (NULL);
  
  //
  //G.U.I. thingy.
  m_aws->Redraw ();
  m_aws->Print (m_g3d, 65);
  
  /*//???csVector3 l_bA;
  m_player->GetBodyAngle ().GetEulerAngles (l_bA);
  csVector3 l_hA;
  m_player->GetHeadAngles ().GetEulerAngles (l_hA);
  g_ske->Gfx2DWrite (20, 20, g_ske->m_g2d->FindRGB (255,255,255), 
  -1, " HEAD (%7.3f %7.3f %7.3f)   BODY (%7.3f %7.3f %7.3f)",
  l_hA.x,l_hA.y,l_hA.z, l_bA.x,l_bA.y,l_bA.z);*/
  
  
  if (m_appState == KAppState::REPLAY)
  {
    int l_maxHeigth,  l_maxWidth;
    m_font->GetMaxSize (l_maxWidth, l_maxHeigth);

    int l_y = m_g2d->GetHeight () - l_maxHeigth * 4;
    iTextureManager* txtmgr = m_g3d->GetTextureManager ();
    int l_white = m_g2d->FindRGB (255, 255, 255);
    int l_black = m_g2d->FindRGB (0, 0, 0);
    
    Gfx2DWrite (m_font, 10, l_y, l_white, -1, "MISSION NAME: %s",
      m_mission->GetName ());
    
    l_y += l_maxHeigth + 2;

    Gfx2DWrite (m_font, 10, l_y, l_white, -1, "MISSION TYPE: %s",
      m_mission->GetMissionType ().GetName ());
    
    l_y += l_maxHeigth + 2;
    float l_currT = m_replayMsecs / 1000.0f;
    float l_maxT = s_lastTimestamp / 1000.0f;
    Gfx2DWrite (m_font, 10, l_y, l_white, -1, "REPLAY TIME: %7.3f      %7.3f      %7.3f",
      0.0f, l_currT, l_maxT);
  }//if


  //
  //??????????????????????????????
  if (m_appState == KAppState::WALKING && 
    m_mission->GetMissionType () == KMissionType::POINTINGTARGET)
  {
    iTextureHandle* lTH = mViewFinderMaterial->GetTextureHandle ();
    int lH, lW;
    lTH->GetOriginalDimensions (lW, lH);
    m_g3d->DrawPixmap (lTH,
      m_g2d->GetWidth () / 2.f -  lW / 2,m_g2d->GetHeight () / 2.f - lH / 2,
      lW, lH, 
      0, 0,
      lW, lH);
  }//if
}




void SKE::HandlePlayerHeadMovement (float p_speedRadians)
{
  if (m_intertrax2 && (m_intertrax2->IsOpen()))
  {
    //use the intertrax2 WOW!
    float l_x, l_y, l_z;
    m_intertrax2->GetData (l_y, l_x, l_z);//yaw,pitch,roll.
    KQuaternion l_q;
    l_q.SetWithEuler (csVector3 (l_y, -l_x, -l_z));
    m_player->SetHeadAngles (l_q);
  }//if
  else
  {
    //
    //use the keyboard for the m_headYAngle and m_headXAngle.
    csVector3 l_a;
    KQuaternion l_q = m_player->GetHeadAngles ();
    l_q.GetEulerAngles (l_a);
    
    //
    //head left and right rotation.
    if (Key_LookLeft)
    {
      l_a.x -= p_speedRadians;
    }//if
    else if (Key_LookRight)
    {
      l_a.x += p_speedRadians;
    }//if
    //head up and down.
    if (Key_LookUp)
    {
      l_a.y += p_speedRadians;
      /*if (l_a.x > K_2PI)
        l_a.x = l_a.x - K_2PI;*/
    }//if
    else if (Key_LookDown)
    {
      l_a.y -= p_speedRadians;
      /*if (l_a.x < 0)
        l_a.x = K_2PI + l_a.x;*/
    }//if
    
    //head bending left/right
    if (Key_BendLeft)
    {
      l_a.z += p_speedRadians;
      if (l_a.z > K_2PI)
        l_a.z = l_a.z - K_2PI;
    }//if
    else if (Key_BendRight)
    {
      l_a.z -= p_speedRadians;
      if (l_a.z < 0)
        l_a.z = K_2PI + l_a.z;
    }//if
    
    l_q.SetWithEuler (csVector3 (l_a.x, l_a.y, l_a.z));
    m_player->SetHeadAngles (l_q);
  }//else
}



int SKE::FindRGBColor (csColor const& pColor)
{
  return m_g2d->FindRGB (int (pColor.red * 255.f), 
    int (pColor.green * 255.f), int (pColor.blue * 255.f));
}

/**
 *
 * Load a texture and register in the graphic render.
 */
csPtr<iTextureHandle> SKE::MyLoadImage (char* file, bool p_keyColor, 
  csRGBcolor const& p_color)
{
  iTextureManager* txtmgr = m_g3d->GetTextureManager();
  csRef<iDataBuffer> buf = m_vfs->ReadFile (file);
  
  //The image is loaded into memory
  csRef<iImage> ifile = m_imageIO->Load (buf, txtmgr->GetTextureFormat ());
  csRef<iTextureHandle> txt = txtmgr->RegisterTexture (ifile, CS_TEXTURE_2D);	
  
  if (p_keyColor)
  {
    txt->SetKeyColor (true);
    txt->SetKeyColor (p_color.red, p_color.green, p_color.blue);
  }//if
    
  return csPtr<iTextureHandle> (txt);
}

iMaterialWrapper* SKE::CreateMaterial (char* p_name, float p_r, float p_g, float p_b)
{
  csRef<iEngine> l_engine = CS_QUERY_REGISTRY(g_objReg, iEngine);
  csRef<iGraphics3D> l_g3d = CS_QUERY_REGISTRY(g_objReg, iGraphics3D);
  
  iMaterialWrapper* l_mw;
  // Create a new material.
  csRef<iMaterial> l_mat (l_engine->CreateBaseMaterial (0));
  l_mat->SetFlatColor (csRGBcolor (int (p_r*255), int (p_g*255), int (p_b*255)));
  l_mw = l_engine->GetMaterialList ()->NewMaterial (l_mat, p_name);
  //??????????l_mw->QueryObject ()->SetName (p_name);REQUIRED???
  //??l_mw->Register (l_g3d->GetTextureManager ());
  return l_mw;
}

iMaterialWrapper* SKE::CreateMaterial (iTextureHandle* p_tH, char* p_name)
{
  csRef<iTextureWrapper> l_tW = m_engine->GetTextureList ()->NewTexture
    (p_tH);
  if (p_name != NULL)
    l_tW->QueryObject ()->SetName (p_name);
  
  iMaterialWrapper* l_mW = NULL;
  csRef<iMaterial> l_material (m_engine->CreateBaseMaterial (l_tW));
  CS_ASSERT (p_name != NULL);//???????????????
  l_mW = m_engine->GetMaterialList ()->NewMaterial (l_material, p_name);
  l_mW->QueryObject ()->SetName (p_name);//???????????
  
  l_tW->Register (m_g3d->GetTextureManager ());
  
  /*//??l_mW->Register (m_g3d->GetTextureManager ());*/
  return l_mW;
}

void SKE::FinishFrame ()
{
  m_g3d->FinishDraw ();
  m_g3d->Print (NULL);
}

void SKE::Start ()
{
  csDefaultRunLoop (g_objReg);
}

/*---------------*
* Main function
*---------------*/
int main (int p_argc, char* p_argv[])
{
  g_objReg = csInitializer::CreateEnvironment (p_argc, p_argv);
  if (!g_objReg) 
    return -1;
  
  g_ske = new SKE ();
  
  if (g_ske->Initialize ())
    g_ske->Start ();
  
  //
  //Destroy and set to 0 the global pointer of the application.
  delete g_ske;
  g_ske = 0;
  
  csInitializer::DestroyApplication (g_objReg);
  return 0;
}


//
//UTILITY ROUTINES
//



void SKE::Gfx2DWrite (iFont* p_font, int x, int y, int fg, int bg, char *str, ...)
{
  va_list arg;
  char buf[256];
  
  va_start (arg, str);
  vsprintf (buf, str, arg);
  va_end (arg);
  
  m_g2d->Write (p_font, x, y, fg, bg, buf);
}

bool SKE::MountDirectory (const char* p_vpath,  const char* p_path)
{
  if (0 == (m_vfs->Mount (p_vpath, p_path)))
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "Could not mount %s on the real path %s !", p_vpath, p_path);
    return false;
  }//if
  
  return true;
}









//
// TRIGGERS for UI
//


/*******************

  PLAYER CONFIGURATION SETTINGS
  
********************/

static iAwsComponent* s_heightTB; 
static iAwsComponent* s_frictionTB;
static iAwsComponent* s_accKTB;
static iAwsComponent* s_maxVelTB;
static iAwsComponent* s_FOVAngleTB;
static iAwsComponent* s_FOVWidthTB;
static iAwsComponent* s_xTB;
static iAwsComponent* s_zTB;
static iAwsComponent* s_angleTB;

static iAwsComponent* s_initPosNameTB;
static iAwsComponent* s_initPosListLB;
static iString* s_selectedInitPosSaved = new scfString ("");

void GetInitPosNameTB (void* p_void, iAwsSource * p_awsSource)
{
  s_initPosNameTB = p_awsSource->GetComponent ();
}
void GetInitPosListLB (void* p_void, iAwsSource * p_awsSource)
{
  s_initPosListLB = p_awsSource->GetComponent ();
}
//those functions below get the handle to the TextBox component.
void GetHeightPlayerTB (void* p_void, iAwsSource * p_awsSource)
{
  s_heightTB= p_awsSource->GetComponent ();  
}
void GetFrictionPlayerTB (void* p_void, iAwsSource * p_awsSource)
{
  s_frictionTB= p_awsSource->GetComponent ();  
}
void GetAccKPlayerTB (void* p_void, iAwsSource * p_awsSource)
{
  s_accKTB= p_awsSource->GetComponent ();  
}
void GetMaxVelPlayerTB (void* p_void, iAwsSource * p_awsSource)
{
  s_maxVelTB= p_awsSource->GetComponent ();  
}
void GetFOVAnglePlayerTB (void* p_void, iAwsSource * p_awsSource)
{
  s_FOVAngleTB= p_awsSource->GetComponent ();  
}
void GetFOVWidthPlayerTB (void* p_void, iAwsSource * p_awsSource)
{
  s_FOVWidthTB= p_awsSource->GetComponent ();  
}
void GetXPlayerTB (void* p_void, iAwsSource * p_awsSource)
{
  s_xTB= p_awsSource->GetComponent ();  
}
void GetZPlayerTB (void* p_void, iAwsSource * p_awsSource)
{
  s_zTB= p_awsSource->GetComponent ();  
}
void GetAnglePlayerTB (void* p_void, iAwsSource * p_awsSource)
{
  s_angleTB= p_awsSource->GetComponent ();  
}


/*
<init_positions>
<init_position name="" x="" z="" angle="">
<init_position name="" x="" z="" angle="">
...
</init_positions>
*/

//This function below put the actual data in the PlConf.
void PlConfUpdate()
{  
  s_heightTB->SetProperty ("Text",Double2String 
    (g_ske->m_player->GetHeight ()));
  s_frictionTB->SetProperty ("Text",Double2String 
    (g_ske->m_player->m_friction ) );
  s_accKTB->SetProperty ("Text",Double2String 
    (g_ske->m_player->m_accK ) );
  s_maxVelTB->SetProperty ("Text",Double2String (
    g_ske->m_player->m_mov3d.GetMaxVelocity ()));
  s_FOVAngleTB->SetProperty ("Text", Double2String 
    (g_ske->m_player->m_FOVAngle));
  s_FOVWidthTB->SetProperty ("Text",Double2String 
    (g_ske->m_player->m_FOVWidth));
  
  csVector3 l_position = g_ske->m_initPos.GetPosition ();
  KQuaternion l_q = g_ske->m_initPos.GetBodyAngle ();
  csVector3 l_a;
  l_q.GetEulerAngles (l_a);
  float l_bodyAngle = l_a.x;//??????? X, instead of Y??? what the heck!!!!!
  
  s_xTB->SetProperty ("Text",Double2String ( l_position.x ) );
  s_zTB->SetProperty ("Text",Double2String ( l_position.z ) );
  s_angleTB->SetProperty ("Text",Double2String (RAD2DEG (l_bodyAngle)));
  
  //
  //Fill the list box with the initial positions contained in the xml init position 
  //file.
  
  //clear all the listbox entries.
  s_initPosListLB->Execute ("ClearList", NULL);

  csStringArray l_sA;
  scfString l_err;

  g_ske->m_savedDataMan->RetrieveInitPossList (l_sA, &l_err);

  size_t i; 
  for (i = 0; i < l_sA.Length (); i++)
  {
    csString l_s (l_sA.Get (i));

    csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
    l_param->AddString ("text0", l_s.GetData ());
    s_initPosListLB->Execute ("InsertItem", l_param);
  }//for
}


void PlConfApply (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;

  //
  //Removed any guard based upon the state of the application.
  //This properties are always modifieable.

  iString* l_string;
  //get&store the height.
  s_heightTB-> GetProperty ("Text", (void**)&l_string);
  l_simple->m_player->SetHeight (String2Double (l_string));
  
  s_frictionTB-> GetProperty ("Text", (void**)&l_string);
  l_simple->m_player->m_friction = String2Double (l_string);
  
  s_accKTB-> GetProperty ("Text", (void**)&l_string);
  l_simple->m_player->m_accK = String2Double (l_string);
  
  s_maxVelTB-> GetProperty ("Text", (void**)&l_string);
  l_simple->m_player->m_mov3d.SetMaxVelocity (String2Double (l_string));
  
  s_FOVAngleTB-> GetProperty ("Text", (void**)&l_string);
  l_simple->m_player->m_FOVAngle = String2Double (l_string);
  
  s_FOVWidthTB-> GetProperty ("Text", (void**)&l_string);
  l_simple->m_player->m_FOVWidth = String2Double (l_string);
  
  //
  //
  s_xTB-> GetProperty ("Text", (void**)&l_string);
  float l_x = String2Double( l_string );
  s_zTB-> GetProperty ("Text", (void**)&l_string);
  float l_z = String2Double( l_string );
  s_angleTB-> GetProperty ("Text", (void**)&l_string);
  l_simple->m_initPos.SetPosition (csVector3 (l_x, 0, l_z));

  float l_yAngle = DEG2RAD (String2Double( l_string));
  KQuaternion l_q;
  l_q.SetWithEuler (csVector3 (l_yAngle, 0, 0));
  l_simple->m_initPos.SetBodyAngle (l_q);
}

void InitPosSelectionChanged (void* p_void, iAwsSource * p_awsSource)
{
  csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
  l_param->AddString ( "text0", "" );
  s_initPosListLB->Execute ("GetSelectedItem", l_param);
  l_param->GetString ( "text0", &s_selectedInitPosSaved );
}

void DeleteInitPos (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  char* l_initPosToDestroy = (s_selectedInitPosSaved ? 
    s_selectedInitPosSaved->GetData (): 0);
  if ((l_initPosToDestroy == 0) || (!strcmp (l_initPosToDestroy, "")))
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY, "No initial position is selected!");
    return;
  }//if
  
  KCommandProcessor::_PerformFormat ("delete_initpos %s", l_initPosToDestroy);
}

void LoadInitPos (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*)p_void;
  
  char* l_initPosName = (s_selectedInitPosSaved ? s_selectedInitPosSaved->
    GetData () : 0);
  if (!l_initPosName || !strcmp (l_initPosName, ""))
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "None \"init position\" is selected !");
    return;
  }//if  
  
  KCommandProcessor::_PerformFormat ("load_initpos %s", l_initPosName);
}

void SaveInitPos (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  iString* l_initPosNameS;
  s_initPosNameTB->GetProperty ("Text", (void**)&l_initPosNameS);
  char* l_initPosNameToSave = l_initPosNameS->GetData ();
  if ((l_initPosNameToSave == 0) || (!strcmp (l_initPosNameToSave, "")))
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "Error: No name was typed in the textbox!");
    return;
  }//if
  
  //
  //Get the init position.//???
  l_simple->m_initPos.SetName (l_initPosNameToSave);
  l_simple->m_initPos.SetPosition (l_simple->m_player->GetPosition ());
  l_simple->m_initPos.SetBodyAngle (l_simple->m_player->GetBodyAngle ());

  KCommandProcessor::_PerformFormat ("save_initpos %s", l_initPosNameToSave);
}

















/*******************

  K SETTINGS
  
********************/

static iAwsComponent* s_skyBoxCB;
static iAwsComponent* s_terrainCB;
static iAwsComponent* s_debugModeCB;
static iAwsComponent* s_lightOntoHeadCB;
static iAwsComponent* s_hourTB;
static iAwsComponent* s_landscapeRB;
static iAwsComponent* s_sunRB;
static iAwsComponent* s_useJoystickCB;
static iAwsComponent* s_useDynaVisCB;
static iAwsComponent* s_showCloudsCB;
static iAwsComponent* s_ambientRedTB;
static iAwsComponent* s_ambientGreenTB;
static iAwsComponent* s_ambientBlueTB;
static iAwsComponent* s_dynAmbientRedTB;
static iAwsComponent* s_dynAmbientGreenTB;
static iAwsComponent* s_dynAmbientBlueTB;



//those functions below get the handle to the TextBox component.
void GetSkyBoxCB (void* p_void, iAwsSource * p_awsSource)
{
  s_skyBoxCB = p_awsSource->GetComponent ();
}
//?????Disabled until some1 will fix the terrain related code!void GetTerrainCB (void* p_void, iAwsSource * p_awsSource)
//?????Disabled until some1 will fix the terrain related code!{
  //?????Disabled until some1 will fix the terrain related code!s_terrainCB = p_awsSource->GetComponent ();
//?????Disabled until some1 will fix the terrain related code!}
void GetDebugModeCB (void* p_void, iAwsSource * p_awsSource)
{
  s_debugModeCB = p_awsSource->GetComponent ();
}
void GetUseJoystickCB (void* p_void, iAwsSource * p_awsSource)
{
  s_useJoystickCB = p_awsSource->GetComponent ();
}
void GetUseDynaVisCB (void* p_void, iAwsSource * p_awsSource)
{
  s_useDynaVisCB = p_awsSource->GetComponent ();
}
void GetShowCloudsCB (void* p_void, iAwsSource * p_awsSource)
{
  s_showCloudsCB = p_awsSource->GetComponent ();
}
void GetLightOntoHeadCB (void* p_void, iAwsSource * p_awsSource)
{
  s_lightOntoHeadCB = p_awsSource->GetComponent ();
}
void GetSkyBoxHourTB (void* p_void, iAwsSource * p_awsSource)
{
  s_hourTB = p_awsSource->GetComponent ();
}
void GetAmbientRedTB (void* p_void, iAwsSource * p_awsSource)
{
  s_ambientRedTB = p_awsSource->GetComponent ();
}
void GetAmbientGreenTB (void* p_void, iAwsSource * p_awsSource)
{
  s_ambientGreenTB = p_awsSource->GetComponent ();
}
void GetAmbientBlueTB (void* p_void, iAwsSource * p_awsSource)
{
  s_ambientBlueTB = p_awsSource->GetComponent ();
}
void GetDynAmbientRedTB (void* p_void, iAwsSource * p_awsSource)
{
  s_dynAmbientRedTB = p_awsSource->GetComponent ();
}
void GetDynAmbientGreenTB (void* p_void, iAwsSource * p_awsSource)
{
  s_dynAmbientGreenTB = p_awsSource->GetComponent ();
}
void GetDynAmbientBlueTB (void* p_void, iAwsSource * p_awsSource)
{
  s_dynAmbientBlueTB = p_awsSource->GetComponent ();
}
void GetLandscapeRB (void* p_void, iAwsSource * p_awsSource)
{
  s_landscapeRB = p_awsSource->GetComponent ();
}
void GetSunRB (void* p_void, iAwsSource * p_awsSource)
{
  s_sunRB = p_awsSource->GetComponent ();
}
void PutSunRB (void* p_void, iAwsSource * p_awsSource)
{
  bool l_true=true;
  bool l_false=false;
  /*s_sunRB->GetProperty ("State", (void**)&l_bool);  
  if(*l_bool)
  {
  bool l_bool = false;*/
  s_sunRB->SetProperty("State", (void*)&l_true);
  s_landscapeRB->SetProperty("State", (void*)&l_false);
  //}//if
}
void PutLandscapeRB (void* p_void, iAwsSource * p_awsSource)
{
  bool l_true=true;
  bool l_false=false;
  /*bool* l_bool;
  s_landscapeRB->GetProperty ("State", (void**)&l_bool);  
  if(*l_bool)
  {
  bool l_bool = false;*/
  s_sunRB->SetProperty("State", (void*)&l_false);
  s_landscapeRB->SetProperty("State", (void*)&l_true);
  //}//if
}
void KApply (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  bool* l_bool;
  
  s_debugModeCB->GetProperty ("State", (void**)&l_bool);
  l_simple->mDebugMode = *l_bool;
  
  s_landscapeRB->GetProperty ("State", (void**)&l_bool);
  if(*l_bool)
    l_simple->m_skyBox->SetMode(SkyBox::NEWSKY);

  s_sunRB->GetProperty ("State", (void**)&l_bool);
  if(*l_bool)
    l_simple->m_skyBox->SetMode(SkyBox::WIENGAARD);
  
  s_skyBoxCB->GetProperty ("State", (void**)&l_bool);  
  g_ske->m_skyBox->SetInvisible (!(*l_bool));
  
  s_showCloudsCB->GetProperty ("State", (void**)&l_bool);
  l_simple->m_skyBox->SetCloudVisible (*l_bool);
  
//?????Disabled until some1 will fix the terrain related code!  s_terrainCB->GetProperty ("State", (void**)&l_bool);  
//?????Disabled until some1 will fix the terrain related code!  g_ske->m_drawTerrain = *l_bool;
  
  s_useJoystickCB->GetProperty ("State", (void**)&l_bool);  
  g_ske->m_useJoy = *l_bool;
  
  s_useDynaVisCB->GetProperty ("State", (void**)&l_bool);  
  g_ske->m_useDynaVis = *l_bool;
  
  static bool s_dyna = false;
  static bool s_frus = true;
  if (g_ske->m_useDynaVis && !s_dyna)
  {
    s_dyna = true;
    s_frus = false;
    //in order to speed up use the dynavis culler.
    g_ske->m_world->SetVisibilityCullerPlugin ("crystalspace.culling.dynavis");
    csReport (g_objReg, CS_REPORTER_SEVERITY_NOTIFY,
      "crystalspace.application.SKE", "Using DynaVis culler.");
  }//if
  else if (!g_ske->m_useDynaVis && !s_frus)
  {
    s_frus = true;
    s_dyna = false;
    g_ske->m_world->SetVisibilityCullerPlugin ("crystalspace.culling.frustvis");
    csReport(g_objReg,CS_REPORTER_SEVERITY_NOTIFY,
      "crystalspace.application.SKE","Using FrustVis culler.");
  }//else
  
  s_lightOntoHeadCB->GetProperty ("State", (void**)&l_bool);  
  l_simple->m_putLightOntoHead = *l_bool;
  
  iString* l_string;
  s_hourTB-> GetProperty ("Text", (void**)&l_string);
  l_simple->m_skyBox->SetTime24( String2Double( l_string ) );
  l_simple->m_skyBox->SetupFrame (0);//redraw the sky.//?? 0 as parameter???
  
  //
  //Set the static ambient light.
  csColor l_ambientColor;
  s_ambientRedTB-> GetProperty ("Text", (void**)&l_string);
  l_ambientColor.red = String2Double (l_string);
  s_ambientGreenTB-> GetProperty ("Text", (void**)&l_string);
  l_ambientColor.green = String2Double (l_string);
  s_ambientBlueTB-> GetProperty ("Text", (void**)&l_string);
  l_ambientColor.blue = String2Double (l_string);
  l_ambientColor.Clamp (1, 1, 1);
  l_simple->m_engine->SetAmbientLight (l_ambientColor);
  
  //
  //Set the dynamic ambient light.
/*  s_dynAmbientRedTB-> GetProperty ("Text", (void**)&l_string);
  l_ambientColor.red = String2Double (l_string);
  s_dynAmbientGreenTB-> GetProperty ("Text", (void**)&l_string);
  l_ambientColor.green = String2Double (l_string);
  s_dynAmbientBlueTB-> GetProperty ("Text", (void**)&l_string);
  l_ambientColor.blue = String2Double (l_string);
  l_ambientColor.Clamp (1, 1, 1);
  l_simple->m_world->SetDynamicAmbientLight (l_ambientColor);*/
}

void KUpdate ()
{
  SKE* l_simple = g_ske;//?? HACK!!
  
  bool l_true=true;
  bool l_false=false;
  
  if(l_simple->mDebugMode)
    s_debugModeCB->SetProperty("State", (void*)&l_true);
  else
    s_debugModeCB->SetProperty("State", (void*)&l_false);
  
  if(l_simple->m_skyBox->GetMode() == SkyBox::WIENGAARD)
  {
    s_landscapeRB->SetProperty ("State", (void*)&l_false);
    s_sunRB->SetProperty ("State", (void*)&l_true);
  }//if
  else if(l_simple->m_skyBox->GetMode() == SkyBox::NEWSKY)
  {
    s_landscapeRB->SetProperty ("State", (void*)&l_true);
    s_sunRB->SetProperty ("State", (void*)&l_false);
  }//else
  
  if(l_simple->m_skyBox->IsCloudVisible ())
    s_showCloudsCB->SetProperty ("State", (void*)&l_true);
  else 
    s_showCloudsCB->SetProperty ("State", (void*)&l_false);
  
  if (g_ske->m_useJoy)
    s_useJoystickCB->SetProperty ("State", (void*)&l_true);
  else
    s_useJoystickCB->SetProperty ("State", (void*)&l_false);
  
  if (g_ske->m_useDynaVis)
    s_useDynaVisCB->SetProperty ("State", (void*)&l_true);
  else
    s_useDynaVisCB->SetProperty ("State", (void*)&l_false);
  
  s_hourTB->SetProperty ("Text",Double2String ( g_ske->m_skyBox->GetTime24() ) );
  
  //
  //Get the ambient light.
  csColor l_ambientColor;
  l_simple->m_engine->GetAmbientLight (l_ambientColor);
  s_ambientRedTB->SetProperty ("Text", 
    Double2String (l_ambientColor.red));
  s_ambientGreenTB->SetProperty ("Text", 
    Double2String (l_ambientColor.green));
  s_ambientBlueTB->SetProperty ("Text", 
    Double2String (l_ambientColor.blue));
  
  //
  //Get the dynamic ambient light.
  l_ambientColor = l_simple->m_world->GetDynamicAmbientLight ();
  s_dynAmbientRedTB->SetProperty ("Text", 
    Double2String (l_ambientColor.red));
  s_dynAmbientGreenTB->SetProperty ("Text", 
    Double2String (l_ambientColor.green));
  s_dynAmbientBlueTB->SetProperty ("Text", 
    Double2String (l_ambientColor.blue));
  
  if (l_simple->m_skyBox->IsInvisible ())
    s_skyBoxCB->SetProperty("State", (void*)&l_false);
  else
    s_skyBoxCB->SetProperty("State", (void*)&l_true);
  
//?????Disabled until some1 will fix the terrain related code!  if(l_simple->m_drawTerrain)
//?????Disabled until some1 will fix the terrain related code!    s_terrainCB->SetProperty("State", (void*)&l_true);
//?????Disabled until some1 will fix the terrain related code!  else
//?????Disabled until some1 will fix the terrain related code!    s_terrainCB->SetProperty("State", (void*)&l_false);
  
  if(l_simple->m_putLightOntoHead)
    s_lightOntoHeadCB->SetProperty("State", (void*)&l_true);
  else
    s_lightOntoHeadCB->SetProperty("State", (void*)&l_false);
}

void Exit (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_ske = (SKE*) p_void;
  
  if (l_ske->m_appState == KAppState::EDITING)
    KCommandProcessor::_Perform ("quit");
  else
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "You cannot exit if you are not in EDITING mode!");
}

/*******************

  LANDMARK
  
********************/

/*
<landmarks>
<landmarks_list name="">
<landmark name="" x="" z="" ...>
<sprite3d name="" x="" z="" ...>
</landmark>
</landmarks_list>
<landmarks_list name="">
...
</landmarks_list>
...
</landmarks>
*/

static unsigned long s_landmarkId = 0;
static iAwsComponent* s_landmarkToCreateLB;//listbox of the name of the LM to be created.
static iAwsComponent* s_createdLMListLB;//list of the created landmark.
static iAwsComponent* s_landmarksListLB;//list of the saved landmarks.
static iAwsComponent* s_landmarksNameTB;//textbox of the name of the lms to save.
static iAwsComponent* s_sizeXLMTB;//X size of LM
static iAwsComponent* s_sizeYLMTB;//Y size of LM
static iAwsComponent* s_sizeZLMTB;//Z size of LM
static iAwsComponent* s_positionXLMTB;//X position of LM
static iAwsComponent* s_positionYLMTB;//Y position of LM
static iAwsComponent* s_positionZLMTB;//Z position of LM
static iAwsComponent* s_materialLB;//materials list.

static iString* s_selectedLM = new scfString ();
static iString* s_selectedLMCreated = new scfString ();
static iString* s_selectedLMSSaved = new scfString ();
static iString* s_selectedMaterial = new scfString ();

/**
fill the list of lms!
*/
void FillTheLMList ()
{
  csStringArray l_sA;
  scfString l_err;
  g_ske->m_savedDataMan->RetrieveDefaultLandmarksList (l_sA, &l_err);
//?????????????????

  size_t i; 
  for (i = 0; i < l_sA.Length (); i++)
  {
    csString l_s (l_sA.Get (i));

    csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
    l_param->AddString ("text0", l_s.GetData ());
    s_landmarkToCreateLB->Execute ("InsertItem", l_param);
  }//for
}

iMaterialWrapper* SKE::LoadMaterial (char const* p_matName, char const* p_path)
{
  if (!g_ske->m_loader->LoadTexture (p_matName, p_path))
  {
    SKE::Report (CS_REPORTER_SEVERITY_ERROR,
      "Error loading %s texture!", p_path);
    return 0;
  }//if
  return g_ske->m_engine->GetMaterialList ()->FindByName 
    (p_matName);
}


static void LoadMaterialsForLandmarks ()
{
  SKE::CreateMaterial ("red", 1.f, 0.f, 0.f);
  SKE::CreateMaterial ("light_red", 0.7f, 0.f, 0.f);
  SKE::CreateMaterial ("morelight_red", 0.4f, 0.f, 0.f);
  SKE::CreateMaterial ("blue", 0.f, 0.f, 1.f);
  SKE::CreateMaterial ("dark_blue", 0.f, 0.f, 0.7f);
  SKE::CreateMaterial ("light_blue", .3f, .3f, 1.f);
  SKE::CreateMaterial ("grey", .5f, .5f, 0.5f);
  SKE::CreateMaterial ("light_grey", .7f, .75f, 0.7f);
  SKE::CreateMaterial ("green", .0f, .9f, 0.1f);
  SKE::CreateMaterial ("yellow", 1.f, 1.f, 0.f);
  SKE::CreateMaterial ("brown", 198.0f/256.0f, 90.0f/256.0f, 42.0f/256.0f);
  SKE::CreateMaterial ("pink", 0xFF/255.0f, 0xC0/255.0f, 0xCB/255.0f);
  SKE::CreateMaterial ("orange", 1, 0.65f, 0.0);
  SKE::CreateMaterial ("black", 1.f, 1.f, 1.0f);
  
  //
  //Load all the images found in the /SKE/texture directory.
  //Each texture will have the same name of the files, but the
  //extension is stripped off.
  csRef<iStringArray> l_sA = g_ske->m_vfs->FindFiles ("/SKE/texture/");
  size_t i;
  for (i = 0; i < l_sA->Length (); i++)
  {
    //Strip off the extension of the file.
    csString l_s (l_sA->Get (i));
    int l_lastSlash = l_s.FindLast ('/');
    
    //
    //If the name ends with a '/' then it is a directory.
    if (l_lastSlash == l_s.Length () - 1)
      continue;//Skip the directories.

    csString l_matName;
    if (l_lastSlash != -1)
       l_matName = l_s.Slice (l_lastSlash + 1, l_s.Length ());
    int l_lastDot = l_matName.FindLast ('.');
    if (l_lastDot != -1)
      l_matName.Truncate (l_lastDot);
    
    char const* lMatNameChar = l_matName.GetData ();
    if (SKE::LoadMaterial (lMatNameChar, l_sA->Get (i)))
    {
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "Successfully loaded the %s material.", lMatNameChar);
    }//if
    else
    {
      SKE::Report (CS_REPORTER_SEVERITY_WARNING,
        "Failed to load the %s material!", lMatNameChar);
    }//else
  }//for
}

static void FillTheMaterialList ()
{
  LoadMaterialsForLandmarks ();

  csRef<iMaterialList> l_materials = g_ske->m_engine->GetMaterialList ();
  int i;
  for (i = 0; i < l_materials->GetCount (); i++)
  {
    csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
    l_param->AddString ( "text0", l_materials->Get (i)->QueryObject ()
      ->GetName () );
    s_materialLB->Execute ("InsertItem", l_param);
  }//for
}

//get the textbox for giving name when saving.
void GetLandmarksNameTB (void* p_void, iAwsSource * p_awsSource)
{
  s_landmarksNameTB = p_awsSource->GetComponent ();
}
//get the listbox of the saved landmarks.
void GetLandmarksListLB (void* p_void, iAwsSource * p_awsSource)
{
  s_landmarksListLB = p_awsSource->GetComponent ();
}
//get the combobox of the landmark to be created.
void GetLandmarkToCreateLB (void* p_void, iAwsSource * p_awsSource)
{
  s_landmarkToCreateLB = p_awsSource->GetComponent ();
}
//get the list of the LM created.
void GetCreatedLMListLB (void* p_void, iAwsSource * p_awsSource)
{
  s_createdLMListLB = p_awsSource->GetComponent ();
}

/**
  Get the list of the materials.
*/
void GetMaterialLB (void* p_void, iAwsSource * p_awsSource)
{
  s_materialLB = p_awsSource->GetComponent ();
  FillTheMaterialList ();//??
}
//get the sizeX textbox.
void GetSizeXLMTB (void* p_void, iAwsSource * p_awsSource)
{
  s_sizeXLMTB = p_awsSource->GetComponent ();
}
//get the sizeY textbox.
void GetSizeYLMTB (void* p_void, iAwsSource * p_awsSource)
{
  s_sizeYLMTB = p_awsSource->GetComponent ();
}
//get the sizeZ textbox.
void GetSizeZLMTB (void* p_void, iAwsSource * p_awsSource)
{
  s_sizeZLMTB = p_awsSource->GetComponent ();
}
//get the positionX textbox.
void GetPositionXLMTB (void* p_void, iAwsSource * p_awsSource)
{
  s_positionXLMTB = p_awsSource->GetComponent ();
}
//get the positionY textbox.
void GetPositionYLMTB (void* p_void, iAwsSource * p_awsSource)
{
  s_positionYLMTB = p_awsSource->GetComponent ();
}
//get the positionZ textbox.
void GetPositionZLMTB (void* p_void, iAwsSource * p_awsSource)
{
  s_positionZLMTB = p_awsSource->GetComponent ();
}

//???
static void UpdatePosSizTB (SKE* l_simple)
{
  if (0 == s_selectedLMCreated)
  {
    csRef<scfString> l_empty;
    l_empty.AttachNew (new scfString (""));
    s_positionXLMTB->SetProperty ("Text", l_empty);
    s_positionYLMTB->SetProperty ("Text", l_empty);
    s_positionZLMTB->SetProperty ("Text", l_empty);
    s_sizeXLMTB->SetProperty ("Text", l_empty);
    s_sizeYLMTB->SetProperty ("Text", l_empty);
    s_sizeZLMTB->SetProperty ("Text", l_empty);
    return;
  }//if
  
  //
  //Update the dialog's fields: position X Y Z and size X Y Z.
  KLandmark* l_lm = l_simple->m_listLM->FindByName 
    (s_selectedLMCreated->GetData ());
  if (l_lm == NULL)
  {
    s_selectedLMCreated->Truncate (0);
    csRef<scfString> l_empty;
    l_empty.AttachNew (new scfString (""));
    s_positionXLMTB->SetProperty ("Text", l_empty);
    s_positionYLMTB->SetProperty ("Text", l_empty);
    s_positionZLMTB->SetProperty ("Text", l_empty);
    s_sizeXLMTB->SetProperty ("Text", l_empty);
    s_sizeYLMTB->SetProperty ("Text", l_empty);
    s_sizeZLMTB->SetProperty ("Text", l_empty);
    return;
  }
  
  csVector3 l_pos = l_lm->GetPosition ();
  csRef<iString> l_pX = Double2String (l_pos.x);
  s_positionXLMTB->SetProperty ("Text", l_pX);
  csRef<iString> l_pY = Double2String (l_pos.y);
  s_positionYLMTB->SetProperty ("Text", l_pY);
  csRef<iString> l_pZ = Double2String (l_pos.z);
  s_positionZLMTB->SetProperty ("Text", l_pZ);
  
  csVector3 l_size = GetBoxSize (l_lm->GetBoundingBox ());
  csRef<iString> l_sX = Double2String (l_size.x);
  s_sizeXLMTB->SetProperty ("Text", l_sX);
  csRef<iString> l_sY = Double2String (l_size.y);
  s_sizeYLMTB->SetProperty ("Text", l_sY);
  csRef<iString> l_sZ = Double2String (l_size.z);
  s_sizeZLMTB->SetProperty ("Text", l_sZ);
}


/**
 * Create a landmark in the world.
 */
void CreateLM (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  if (l_simple->m_appState != KAppState::EDITING)
    return;
  
  //
  //Update the s_landmarkId, i.e. the next id to be use
  s_landmarkId = 0;//Reset it.
  
  //
  //Find the max into the list.
  int l_maxId = -1;
  size_t i;
  for (i = 0; i < l_simple->m_listLM->GetCount (); i++)
  {
    csString l_id;
    KLandmark* l_lm = l_simple->m_listLM->Get (i);
    char const* l_name = l_lm->GetName ();

    unsigned int l_temp = (int)RetrievePostfixedNumber (csString (l_name));
    s_landmarkId = s_landmarkId > l_temp ? s_landmarkId : l_temp;
  }//for
  s_landmarkId++;//Increment it.
  
  const char* l_selectedLMChar = s_selectedLM ? s_selectedLM->GetData () : 0;
  if ((l_selectedLMChar == 0) || (!strcmp (l_selectedLMChar, "")))
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY, "No landmark is selected!");
    return;
  }//if

  csRef<KLandmark> l_lm;
  csRef<iString> l_s;
  l_s.AttachNew (new scfString (s_selectedLM->GetData ()));
  scfString l_LM("LM_");

  l_s->Insert(0, &l_LM);
  l_s->Append( Integer2String (s_landmarkId++));
  
  l_lm = csPtr<KLandmark> (new KLandmark ());
  scfString l_error;
  if (!g_ske->m_savedDataMan->RetrieveLandmark (l_selectedLMChar, l_lm, &l_error))
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "Error creating the landmark (%s) !", l_error.GetData ());
  }//if

  l_lm->SetName (l_s->GetData ());
  l_lm->SetSector (g_ske->m_world);  
  
  if (l_lm == 0)
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY, "Error: landmark not created !");
    return;
  }//if
  
  //Add the landmark to the landmarklist.
  g_ske->m_listLM->Add (l_lm);
  
  //
  //Update the list of landmarks in both the target list (mission tab) 
  //and in landmarks created (landmarks tab).
  MUpdate ();
  LMUpdate ();
}


//
//destroy a single landmark already created in the world.
void DestroyLM (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  //
  //Guard.
  if (l_simple->m_appState != KAppState::EDITING)
    return;
  
  if (s_selectedLMCreated == 0)
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "No landmark is selected!");
    return;
  }//if
  
  KLandmark* l_lm = l_simple->m_listLM->FindByName 
    (s_selectedLMCreated->GetData ());
  if (l_lm == 0)
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "Landmark to delete not found!");
    return;
  }//if
  
  //
  //Removing the landmark from the list causes also its destruction, since the list
  //is keepeing just the unique reference to that landmark.
  g_ske->m_listLM->Remove (l_lm);
  
  //
  //Update the list of landmarks in both the target list ('mission' tab) 
  //and in landmarks created ('landmarks' tab).
  MUpdate();
  LMUpdate();
}


void LMUpdate ()
{
  //
  //update the list box listing the landmarks created.
  s_createdLMListLB->Execute ("ClearList", NULL);
  size_t i;
  for (i = 0; i < g_ske->m_listLM->GetCount (); i++)
  {
    KLandmark* l_lm = g_ske->m_listLM->Get (i);
    csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
    l_param->AddString ( "text0", l_lm->GetName ());
    s_createdLMListLB->Execute ("InsertItem", l_param);
  }//for
  
  
  //
  //update the list box with the landmarks contained in the xml landmarks file.
  
  //clear all the listbox entries.
  s_landmarksListLB->Execute ("ClearList", NULL);
  
  csStringArray l_list;
  g_ske->m_savedDataMan->RetrieveLandmarksListList (l_list);
  
  for (i = 0; i < l_list.Length (); i++)
  {
    const char* l_levelName = l_list.Get (i);
    //add the name to the listbox.
    csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
    l_param->AddString ( "text0", l_levelName );
    s_landmarksListLB->Execute ("InsertItem", l_param);
  }//for
  
  //Update the textboxes of the dialog.
  UpdatePosSizTB (g_ske);
}

void LMApply (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  //
  //Apply the material, the size, the position to the landmark selected!
  if ((s_selectedLMCreated == 0) || (s_selectedLMCreated->IsEmpty ()))
    return;
  
  KLandmark* l_lm = l_simple->m_listLM->FindByName (s_selectedLMCreated->GetData ());
  
  scfString* l_s;
  
  //
  //Get&Apply the dimension.
  csVector3 l_size (0, 0, 0);
  s_sizeXLMTB->GetProperty ("Text", (void**)&l_s);
  l_size.x = String2Double (l_s);
  s_sizeYLMTB->GetProperty ("Text", (void**)&l_s);
  l_size.y = String2Double (l_s);
  s_sizeZLMTB->GetProperty ("Text", (void**)&l_s);
  l_size.z = String2Double (l_s);
  l_lm->SetSize (l_size);
  
  //
  //Get&Apply the position.
  csVector3 l_pos (0, 0, 0);
  s_positionXLMTB->GetProperty ("Text", (void**)&l_s);
  l_pos.x = String2Double (l_s);
  s_positionYLMTB->GetProperty ("Text", (void**)&l_s);
  l_pos.y = String2Double (l_s);
  s_positionZLMTB->GetProperty ("Text", (void**)&l_s);
  l_pos.z = String2Double (l_s);
  l_lm->SetPosition (l_pos);
  
  //
  //Get&Apply the material.
  if ((s_selectedMaterial == NULL) || (s_selectedMaterial->IsEmpty ()))
    return;
  
  l_lm->SetMaterial (s_selectedMaterial->GetData ());
}

//
//Delete a saved landmarks list.
void DeleteLM (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  if (l_simple->m_appState != KAppState::EDITING)
    return;
  
  char* l_lmsListToDestroy = (s_selectedLMSSaved ? s_selectedLMSSaved->GetData (): NULL);
  if ((l_lmsListToDestroy == NULL) || (!strcmp (l_lmsListToDestroy, "")))
  {
    csReport(g_objReg,CS_REPORTER_SEVERITY_NOTIFY,
      "crystalspace.application.SKE","No list of landmarks is selected!");
    return;
  }//if
  
  scfString l_error;
  if (!l_simple->m_savedDataMan->RemoveLandmarksList (l_lmsListToDestroy, &l_error))
  {
    csReport(g_objReg,CS_REPORTER_SEVERITY_NOTIFY,
      "crystalspace.application.SKE", "Error removing landmarks list %s (%s) !",
      l_lmsListToDestroy, l_error.GetData ());
    return;
  }//if
  
  
  csReport(g_objReg,CS_REPORTER_SEVERITY_NOTIFY,
    "crystalspace.application.SKE","Successfully deleted the landmark list called '%s' !",
    l_lmsListToDestroy);
  
  //
  //Set to empty string the selection in the listbox, 
  //since the actual selection was removed.
  s_selectedLMSSaved->Clear ();
  
  //
  //Call the updating of the dialog.
  LMUpdate();
}

void LoadLM (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_ske = (SKE*) p_void;
  
  if (l_ske->m_appState != KAppState::EDITING)
    return;
  
  char* l_lmsListName = (s_selectedLMSSaved ? s_selectedLMSSaved->GetData () : 0);
  if (!l_lmsListName || !strcmp(l_lmsListName, ""))
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "None landmarks list is selected !");
    return;
  }//if
  
  KCommandProcessor::_Perform ("load_landmarks", l_lmsListName);
}

void SaveLM (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  iString* l_lmsListNameS;
  s_landmarksNameTB->GetProperty ("Text", (void**)&l_lmsListNameS);
  char* l_lmsListNameToSave = l_lmsListNameS->GetData ();
  if ((l_lmsListNameToSave == 0) || (!strcmp(l_lmsListNameToSave, "")))
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "No landmarks list name was typed in the textbox!");
    return;
  }//if
  
  KCommandProcessor::_Perform ("save_landmarks", l_lmsListNameToSave);
}




void LMSelectionChanged(void* p_void, iAwsSource * p_awsSource)
{
  csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
  l_param->AddString ("text0", "" );
  s_landmarkToCreateLB->Execute ("GetSelectedItem", l_param);
  l_param->GetString ("text0", &s_selectedLM);
}

void LMCreatedSelectionChanged (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  //
  //Get the name of the item selected.
  csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
  l_param->AddString ("text0", "");
  s_createdLMListLB->Execute ("GetSelectedItem", l_param);
  l_param->GetString ("text0", &s_selectedLMCreated);
  
  //Update the textboxes of the dialog.
  UpdatePosSizTB (l_simple);
}


void LMSSelectionChanged(void* p_void, iAwsSource * p_awsSource)
{
  csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
  l_param->AddString ( "text0", "" );
  s_landmarksListLB->Execute ("GetSelectedItem", l_param);
  l_param->GetString ( "text0", &s_selectedLMSSaved );
}

void MaterialSelectionChanged (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  //
  //Get the name of the item selected.
  csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
  l_param->AddString ("text0", "");
  s_materialLB->Execute ("GetSelectedItem", l_param);
  l_param->GetString ("text0", &s_selectedMaterial);
}










/*******************

  EDITOR
  
********************/
static iAwsComponent* s_sizeZMapTB;
static iAwsComponent* s_sizeXMapTB;
static iAwsComponent* s_levelNameTB;
static iAwsComponent* s_loadLevelBT;
static iAwsComponent* s_saveLevelBT;
static iAwsComponent* s_destroyLevelBT;
static iAwsComponent* s_levelsListLB;

static iString* s_selectedLevel = new scfString ();

void GetLevelNameTB (void* p_void, iAwsSource * p_awsSource)
{
  s_levelNameTB = p_awsSource->GetComponent ();
}
void GetLoadLevelBT (void* p_void, iAwsSource * p_awsSource)
{
  s_loadLevelBT = p_awsSource->GetComponent ();
}
void GetSaveLevelBT (void* p_void, iAwsSource * p_awsSource)
{
  s_saveLevelBT = p_awsSource->GetComponent ();
}
void GetDestroyLevelBT (void* p_void, iAwsSource * p_awsSource)
{
  s_destroyLevelBT = p_awsSource->GetComponent ();
}
void GetLevelsListLB (void* p_void, iAwsSource * p_awsSource)
{
  s_levelsListLB = p_awsSource->GetComponent ();
}
void GetMapXTB (void* p_void, iAwsSource * p_awsSource)
{
  s_sizeXMapTB = p_awsSource->GetComponent ();
}
void GetMapZTB (void* p_void, iAwsSource * p_awsSource)
{
  s_sizeZMapTB = p_awsSource->GetComponent ();
}
#define SETBLOCKID( x ) \
  void x (void* p_void, iAwsSource * p_awsSource)\
{\
  g_ske->m_blockIdSelected = KBlockId::##x;\
}
SETBLOCKID(F);
SETBLOCKID(I1);
SETBLOCKID(I2);
SETBLOCKID(L1);
SETBLOCKID(L2);
SETBLOCKID(L3);
SETBLOCKID(L4);
SETBLOCKID(T1);
SETBLOCKID(T2);
SETBLOCKID(C);
SETBLOCKID(D1);
SETBLOCKID(D2);

const KBlockId SKE::GetSelectedBlockId()
{
  return m_blockIdSelected;
}

void ESelectionChanged (void* p_void, iAwsSource * p_awsSource)
{
  csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
  l_param->AddString ( "text0", "" );
  s_levelsListLB->Execute ("GetSelectedItem", l_param);
  l_param->GetString ( "text0", &s_selectedLevel );
}

void EditorUpdate ()
{
  int l_sizeX, l_sizeZ;
  csVector2 l_box = g_ske->m_map->GetSize ();
  l_sizeX = l_box.x;
  l_sizeZ = l_box.y;
  
  s_sizeXMapTB->SetProperty ("Text", 
    new scfString (Integer2String ( l_sizeX ).GetData ()) );
  s_sizeZMapTB->SetProperty ("Text", 
    new scfString (Integer2String ( l_sizeZ ).GetData ()) );
  
  //
  //update the list box with the levels contained in the xml levels file.
  
  //clear all the listbox entries.
  s_levelsListLB->Execute ("ClearList", NULL);
  
  csStringArray l_list;
  g_ske->m_savedDataMan->RetrieveLevelsList (l_list);
  
  size_t i = 0;
  for (;i < l_list.Length (); i++)
  {
    const char* l_levelName = l_list.Get (i);
    //add the name to the listbox.
    csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
    l_param->AddString ( "text0", l_levelName );
    s_levelsListLB->Execute ("InsertItem", l_param);
  }//for
}

void EditorApply (void* p_void, iAwsSource * p_awsSource)
{
  //nothing to store here!
}

void DestroyE (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  char* l_levelToDestroy = (s_selectedLevel ? s_selectedLevel->GetData (): NULL);
  if ((l_levelToDestroy == NULL) || (!strcmp (l_levelToDestroy, "")))
  {
    csReport(g_objReg,CS_REPORTER_SEVERITY_NOTIFY,
      "crystalspace.application.SKE","No level is selected!");
    return;
  }//if
  
  scfString l_error;
  if (!l_simple->m_savedDataMan->RemoveLevel (l_levelToDestroy, &l_error))
  {
    csReport(g_objReg,CS_REPORTER_SEVERITY_NOTIFY,
      "crystalspace.application.SKE", "Error removing level %s (%s) !",
      l_levelToDestroy, l_error.GetData ());
    return;
  }//if    
  
  //
  //Set to empty string the selection in the listbox, 
  //since the actual selection was removed.
  s_selectedLevel->Clear ();
  
  //Call the updating of the dialog.
  EditorUpdate();
}




void SaveE (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_simple = (SKE*) p_void;
  
  iString* l_levelNameS;
  s_levelNameTB->GetProperty ("Text", (void**)&l_levelNameS);
  char* l_levelName = l_levelNameS->GetData ();
  if ((l_levelName == 0) || (!strcmp(l_levelName, "")))
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "No level name was typed in the textbox!");
    return;
  }//if
  
  KCommandProcessor::_Perform ("save_level", l_levelName);
}

void LoadE (void* p_void, iAwsSource * p_awsSource)
{
  char* l_levelName = (s_selectedLevel ? s_selectedLevel->GetData () : 0);
  if (!l_levelName)
  {
    SKE::Report (CS_REPORTER_SEVERITY_WARNING, "None level is selected !");
    return;
  }//if
  
  KCommandProcessor::_Perform ("load_level", l_levelName);
}

void NewMap (void* p_void, iAwsSource * p_awsSource)
{
  iString* l_string;
  s_sizeXMapTB-> GetProperty ("Text", (void**)&l_string);
  int lSizeX = (int) String2Double (l_string);
  
  s_sizeZMapTB-> GetProperty ("Text", (void**)&l_string);
  int lSizeZ = (int) String2Double( l_string );
  
  KCommandProcessor::_PerformFormat ("resize_level %d %d", lSizeX, lSizeZ);
}
























/*******************

  MISSION
  
********************/
static iAwsComponent* s_targetRB;
static iAwsComponent* s_freeWalkingRB;
static iAwsComponent* s_notFreeWalkingRB;
static iAwsComponent* s_pointingTargetRB;
static iAwsComponent* s_durationTimeTB;
static iAwsComponent* s_targetLB;
static iAwsComponent* s_saveMissionTB;
static iAwsComponent* s_discardDataCB;

static iString* s_selectedTarget = new scfString ();
static iString* s_selectedPath = new scfString ();

static iString* s_dateHour = new scfString ();


void DiscardDataCB (void* p_void, iAwsSource * p_awsSource)
{
  s_discardDataCB = p_awsSource->GetComponent ();
}
void GetSaveMissionTB (void* p_void, iAwsSource * p_awsSource)
{
  s_saveMissionTB = p_awsSource->GetComponent ();
}
void GetTargetRB (void* p_void, iAwsSource * p_awsSource)
{
  s_targetRB = p_awsSource->GetComponent ();
}
void GetPointingTargetRB (void* p_void, iAwsSource * p_awsSource)
{
  s_pointingTargetRB = p_awsSource->GetComponent ();
}
void GetFreeWalkingRB (void* p_void, iAwsSource * p_awsSource)
{
  s_freeWalkingRB = p_awsSource->GetComponent ();
}
void GetNotFreeWalkingRB (void* p_void, iAwsSource * p_awsSource)
{
  s_notFreeWalkingRB = p_awsSource->GetComponent ();
}

void PutTargetRB (void* p_void, iAwsSource * p_awsSource)
{
  bool l_true = true;
  bool l_false = false;
  s_targetRB->SetProperty("State", (void*)&l_true);
  s_freeWalkingRB->SetProperty("State", (void*)&l_false);
  s_notFreeWalkingRB->SetProperty("State", (void*)&l_false);
  s_pointingTargetRB->SetProperty("State", (void*)&l_false);
}
void PutFreeWalkingRB (void* p_void, iAwsSource * p_awsSource)
{
  bool l_true = true;
  bool l_false = false;
  s_targetRB->SetProperty("State", (void*)&l_false);
  s_freeWalkingRB->SetProperty("State", (void*)&l_true);
  s_notFreeWalkingRB->SetProperty("State", (void*)&l_false);
  s_pointingTargetRB->SetProperty("State", (void*)&l_false);
}
void PutNotFreeWalkingRB (void* p_void, iAwsSource * p_awsSource)
{
  bool l_true = true;
  bool l_false = false;
  s_targetRB->SetProperty("State", (void*)&l_false);
  s_freeWalkingRB->SetProperty("State", (void*)&l_false);
  s_notFreeWalkingRB->SetProperty("State", (void*)&l_true);
  s_pointingTargetRB->SetProperty("State", (void*)&l_false);
}
void PutPointingTargetRB (void* p_void, iAwsSource * p_awsSource)
{
  bool l_true = true;
  bool l_false = false;
  s_targetRB->SetProperty("State", (void*)&l_false);
  s_freeWalkingRB->SetProperty("State", (void*)&l_false);
  s_notFreeWalkingRB->SetProperty("State", (void*)&l_false);
  s_pointingTargetRB->SetProperty("State", (void*)&l_true);
}
void MTargetSelectionChanged(void* p_void, iAwsSource * p_awsSource)
{
  csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
  l_param->AddString ( "text0", "" );
  s_targetLB->Execute ("GetSelectedItem", l_param);
  l_param->GetString ("text0", &s_selectedTarget);
}
void GetTargetListLB (void* p_void, iAwsSource * p_awsSource)
{
  s_targetLB = p_awsSource->GetComponent ();
}
void GetMissionAllowedTimeTB (void* p_void, iAwsSource * p_awsSource)
{
  s_durationTimeTB = p_awsSource->GetComponent ();
}

void MUpdate ()
{
  //
  //Update the list box listing the landmarks created.
  s_targetLB->Execute ("ClearList", 0);//Clear the list.
  size_t i;
  for (i = 0; i < g_ske->m_listLM->GetCount (); i++)
  {
    KLandmark* l_lm = g_ske->m_listLM->Get (i);
    csRef<iAwsParmList> l_param = g_ske->m_aws->CreateParmList ();
    l_param->AddString ( "text0", l_lm->GetName ());
    s_targetLB->Execute ("InsertItem", l_param);
  }//for
  
  //
  //If there is a mission, read the data, and put them into the GUI.
  if (g_ske->m_mission != 0)
  {
    iKMission* l_km = g_ske->m_mission;
    csRef<iKFreeWalkingMission> l_fWM;
    csRef<iKTargetingMission> l_tM;
    csRef<iKPointingTargetMission> l_pTM;
    csRef<iKNotFreeWalkingMission> l_nFWM;
    //
    //Set the type (set the RBs status)
    bool l_true = true;
    bool l_false = false;
    s_targetRB->SetProperty ("State", (void*)&l_false);
    s_freeWalkingRB->SetProperty ("State", (void*)&l_false);
    s_notFreeWalkingRB->SetProperty ("State", (void*)&l_false);
    s_pointingTargetRB->SetProperty ("State", (void*)&l_false);
    KMissionType const& l_missionType = l_km->GetMissionType ();
    if (l_missionType == KMissionType::FREEWALKING)
    {
      s_freeWalkingRB->SetProperty ("State", (void*)&l_true);
      l_fWM = SCF_QUERY_INTERFACE (l_km, iKFreeWalkingMission);
    }//if
    else if (l_missionType == KMissionType::NOTFREEWALKING)
    {
      s_notFreeWalkingRB->SetProperty ("State", (void*)&l_true);
      l_nFWM = SCF_QUERY_INTERFACE (l_km, iKNotFreeWalkingMission);
    }//else if
    else if (l_missionType == KMissionType::TARGETING)
    {
      s_targetRB->SetProperty ("State", (void*)&l_true);
      l_tM = SCF_QUERY_INTERFACE (l_km, iKTargetingMission);
    }//else if
    else if (l_missionType == KMissionType::POINTINGTARGET)
    {
      s_pointingTargetRB->SetProperty("State", (void*)&l_true);
      l_pTM = SCF_QUERY_INTERFACE (l_km, iKPointingTargetMission);
    }//else if
    
    //
    //Set the target (set the selected item in listbox)
    //?? TO DO: add the functionality SetSelectedItem to AWS (to ListBoxes)
    
    //
    //Set minutes
    float l_time = -1;
    if (l_missionType == KMissionType::TARGETING)
      l_time = l_tM->GetAllowedMinutes ();
    else if (l_missionType == KMissionType::FREEWALKING)
      l_time = l_fWM->GetAllowedMinutes ();
    
    csRef<iString> l_s = Double2String (l_time);
    l_s->IncRef ();//?? Why this is needed?
    s_durationTimeTB->SetProperty ("Text", l_s);
    
    //
    //Set file name to save
    const char* l_name = l_km->GetName ();
    csRef<iString> l_s2;
    l_s2.AttachNew (new scfString (l_name));
    s_saveMissionTB->SetProperty ("Text", l_s2);
  }
}


void StartMission (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_ske = (SKE*) p_void;

  //
  //Store the date/hour of the mission.
  s_dateHour->Clear ();
  ::AddDateHour (s_dateHour);

  if (l_ske->m_appState != KAppState::EDITING)
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "Error: to start a mission you should be in the EDITING mode.");
    return;
  }//if
  
  //
  //Let's see if we want to collect datas.
  bool* l_discardData;
  s_discardDataCB->GetProperty ("State", (void**)&l_discardData);  
  
  //
  //Get the filename to save if needed.
  iString* l_dataFileName;
  s_saveMissionTB->GetProperty ("Text", (void**)&l_dataFileName);
  if ( !(*l_discardData) && (l_dataFileName == NULL || l_dataFileName->IsEmpty () ))
  {//If no filename is specified and we want to collect datas, report error.
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "Error: Please type in the proper textbox a name for saving datas!");
    return;
  }//if
  
  bool* l_targeting;
  s_targetRB->GetProperty ("State", (void**)&l_targeting);
  bool* l_freeWalking;
  s_freeWalkingRB->GetProperty ("State", (void**)&l_freeWalking);
  bool* l_notFreeWalking;
  s_notFreeWalkingRB->GetProperty ("State", (void**)&l_notFreeWalking);
  bool* l_pointingTarget;
  s_pointingTargetRB->GetProperty ("State", (void**)&l_pointingTarget);
  
  //
  //The radio buttons are automatically mutual exclusive, so just check
  //if at least one is set.
  if (!*l_freeWalking && !*l_targeting && !*l_notFreeWalking && !*l_pointingTarget)
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "Error: Please select the type of the mission to execute!");
    return;
  }//if
  
  if (*l_targeting)//if targeting
  {//TARGETING.
    
    //
    //Get the path, the map, the landmarks.
    KPath* l_path = l_ske->m_path;
    KMap* l_wM = l_ske->m_map;
    KLandmarkList* l_lML = l_ske->m_listLM;
    KPlayer* l_player = l_ske->m_player;
    
    //
    //If there is a path, put the player at the path's start.
    if (!l_path->IsEmpty ())
    {
      csDirtyAccessArray<csVector3> l_points;
      l_path->GetPoints (l_points);
      
      l_ske->m_initPos.SetPosition (l_points.Get (0));
      l_ske->m_player->SetPosition (l_points.Get (0));      
    }//if
    else
      l_path = 0;//Let l_path be 0
    
    //Get the initial position of the player.
    KPosition* l_initialPosition = &l_ske->m_initPos;
    
    //
    //Get the time.
    double l_minutes;
    iString* l_s;
    s_durationTimeTB->GetProperty ("Text", (void**)&l_s);
    l_minutes = String2Double (l_s);
    if (l_minutes <= 0)
      l_minutes = -1;
    
    //
    //Get target.
    csRef<KLandmark> l_lmTarget;
    char* l_seledTarget = s_selectedTarget ? 
      s_selectedTarget->GetData () : 0;
    if ((0 == l_seledTarget) || (!strcmp (l_seledTarget, "")))
    {
      //
      //If no target is being selected put the 'target' landmark to the end of the path
      //(if the path is not present, error!)
      if (0 == l_path || l_path->IsEmpty ())
      {
        SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
          "Error: you must select a path or provide a path!");
        return;
      }//if
      
      //
      // Dont allow the creation of the target more than one time.
      if ((0 == (l_lmTarget = l_lML->FindByName ("LM_target"))))
      {
        //Create the target (a KLandmark).
        l_lmTarget.AttachNew (new KLandmark ());
        csRef<scfString> l_s = csPtr<scfString> (new scfString ());
        l_lmTarget->SetName ("LM_target");
        
        csRef<KSprite3D> l_ks3d;
        l_ks3d.AttachNew (new KSprite3D ());
        l_ks3d->Create ("LM_target", "/SKE/model/SPRtarget", "target_mat", 
          1, 1, 1);
        
        l_lmTarget->AddKSprite3D (l_ks3d);
        
        //Add the landmark to the engine.
        l_lML->Add (l_lmTarget);
      }//if
      
      l_lmTarget->SetSector (l_ske->m_world);//??
      l_lmTarget->SetVisible (false);
      
      //
      //Set the position of the landmark at the end of the path.      
      csDirtyAccessArray<csVector3> l_points;
      l_path->GetPoints (l_points);
      csVector3 l_pos (l_points.Top ());
      l_pos.y = 0.6f;//????????
      l_lmTarget->SetPosition (l_pos);
    }//if
    else
    {
      l_lmTarget = l_lML->FindByName (l_seledTarget);
      if (0 == l_lmTarget)
      {
        SKE::Report (CS_REPORTER_SEVERITY_WARNING,
          "Error: no target is selected!");
        return;
      }//if
    }//else
    
    //Optional is the [time] and the [path].
    l_ske->m_mission.AttachNew (new KTargetingMission (
      l_dataFileName->GetData (), l_initialPosition, l_player,
      l_lmTarget->GetName (), l_path, l_minutes, l_wM,
      l_lML, !*l_discardData));
    
    //
    //?? output some useful debug information about the mission!
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "TARGETING MISSION ====== INFORMATIONS' START");
    char const* l_targetName = l_lmTarget->GetName () ? l_lmTarget->
      GetName ():"<noname>";
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "target name : %s", l_targetName);
    
    if (!l_path || l_path->IsEmpty ())
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "path : no path provided.");
    else
    {
      const char* l_pathName = l_path->GetName () ? l_path->
        GetName () : "<noname>";
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "path : %s", l_pathName);
    }//else
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "allowed minutes : %7.03f", l_minutes);
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "TARGETING MISSION ====== INFORMATIONS' END");
    }//if
    
    
    
    
    
    
    
    
    
    else if (*l_freeWalking)
    {//FREEWALKING.
      
      //
      //Get the KMap, the landmarks and the player.
      KMap* l_wM = l_ske->m_map;
      KLandmarkList* l_lML = l_ske->m_listLM;
      KPlayer* l_player = l_ske->m_player;
      
      
      //
      //Get the time.
      double l_minutes;
      
      iString* l_s;
      s_durationTimeTB->GetProperty ("Text", (void**)&l_s);
      if ((l_s == NULL) || (l_s->IsEmpty ()))
        l_minutes = -1;
      else
        l_minutes = String2Double (l_s);
      if (l_minutes <=0)
        l_minutes = -1;
      
      //Get the initial position of the player.
      KPosition* l_initialPosition = &l_ske->m_initPos;
      
      
      l_ske->m_mission.AttachNew
        (new KFreeWalkingMission (l_dataFileName->GetData (),
        l_initialPosition,
        l_player,
        l_minutes, l_wM, l_lML, !*l_discardData));
      
      //?? output some useful debug information about the mission!
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "FREEWALKING MISSION ====== INFORMATIONS' START");
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "allowed minutes : %7.03f", l_minutes);
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "FREEWALKING MISSION ====== INFORMATIONS' END");
    }//if
    
    
    
    else if (*l_notFreeWalking)
    {//NOTFREEWALKING.
      
      //
      //get the path, the KMap, the landmarks.
      KPath* l_path = l_ske->m_path;
      KMap* l_wM = l_ske->m_map;
      KLandmarkList* l_lML = l_ske->m_listLM;
      KPlayer* l_player = l_ske->m_player;
      
      if (l_path->IsEmpty ())
      {
        SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
          "Error: you must create a path!");
        return;
      }//if
      else
      {
        csDirtyAccessArray<csVector3> l_points;
        l_path->GetPoints (l_points);
        csVector3 l_v = l_points.Get(1) - l_points.Get(0);
        float l_initAngle = Vector2Angle (l_v, csVector3 (0,0,1));
        
        //
        //Set the right initial position and
        //put the player at the start of the path.//???UGLY CODE
        KQuaternion l_q;
        l_q.SetWithEuler (csVector3 (-l_initAngle, 0, 0));
        l_ske->m_initPos.SetBodyAngle (l_q);
        l_ske->m_initPos.SetPosition (l_points.Get (0));
        
        l_ske->m_player->SetBodyAngle (l_q);
        l_ske->m_player->SetPosition (l_points.Get (0));
      }//else
      
      //
      //Init the path
      l_path->Init (l_ske->m_player->m_mov3d.GetMaxVelocity ());
      
      //Get the initial position of the player.
      KPosition* l_initialPosition = &l_ske->m_initPos;
      
      l_ske->m_mission.AttachNew (new KNotFreeWalkingMission 
        (l_dataFileName->GetData (), l_initialPosition, l_player,
        l_path, l_wM, l_lML, !*l_discardData));
      
      //?? output some useful debug information about the mission!
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "NOTFREEWALKING MISSION ====== INFORMATIONS' START");
      const char* l_pathName = l_path->GetName () ? l_path->
        GetName () : "<noname>";
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "path : %s", l_pathName);
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "NOTFREEWALKING MISSION ====== INFORMATIONS' END");
      
    }//elseif
    else if (*l_pointingTarget)
    {//POINTINGTARGET.
      
      //
      //Get the path, the KMap, the landmarks.
      KMap* l_wM = l_ske->m_map;
      KLandmarkList* l_lML = l_ske->m_listLM;
      KPlayer* l_player = l_ske->m_player;
      
      //
      //Get target.
      if (0 == s_selectedTarget)
      {
        SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
          "Error: Please select a landmark as the target!");
        return;
      }//if
      
      //Get the initial position of the player.
      KPosition* l_initialPosition = &l_ske->m_initPos;
      
      KLandmark* l_lmTarget = l_lML->FindByName 
        (s_selectedTarget->GetData ());
      if (0 == l_lmTarget)
      {
        SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
          "Error: Please select a landmark as the target!");
        return;
      }//if
      
      l_ske->m_mission.AttachNew (new KPointingTargetMission 
        (l_dataFileName->GetData (), l_initialPosition, l_player,
        l_lmTarget->GetName (), l_wM, l_lML, !*l_discardData));
      
      //?? output some useful debug information about the mission!
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "POINTINGTARGET MISSION ====== INFORMATIONS' START");
      char const * l_targetName = l_lmTarget->GetName () ? l_lmTarget->
        GetName () : "<noname>";
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "target name : %s", l_targetName);
      SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
        "POINTINGTARGET MISSION ====== INFORMATIONS' END");
    }//elseif
    
    
    //?????? DONOT REMOVE ANY POLYGON, it is better...
    //
    //remove all polygon that are not visible. 
    /*csReport (g_objReg,CS_REPORTER_SEVERITY_NOTIFY,
    "crystalspace.application.SKE", "WALKING: removing not visible polygons.");
    l_ske->m_map->RemoveNotVisiblePolygons ();*/
    
    //
    //create colliders for all the walls in the KMap.
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "WALKING: colliders creation for walls.");
    l_ske->m_map->AttachColliders ();//create the colliders for walls.
    
    //
    //create colliders for all the landmarks.
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "WALKING: colliders creation for landmarks.");
    l_ske->m_listLM->AttachColliders (l_ske->m_collisionDet);
    
    
    //
    //Compute here the new shadow if needed (ie if not already done).
    //
    //??Dont use automatic relighting.
    //if (l_ske->m_map->GetFlags ().Check (KMap::KMAP_NEED_RELIGHTING))
    //  Relight (l_ske, 0);
    
    
    //????????????????????????????
    //switch to POINTINGBEFOREWALKING state.
    l_ske->m_appState = KAppState::POINTINGBEFOREWALKING;
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "Mode switched to POINTING_BEFORE_WALKING.");
    
    
    //
    //Hide the LM_target if it is there.
    KLandmark* l_target;
    if ((l_target = l_ske->m_listLM->FindByName ("LM_target")) != NULL)
      l_target->SetVisible (false);
    l_ske->m_plConfWnd->Hide ();//hide the window.

    //
    //Hide the mouse!
    l_ske->m_mouseManager->SetMode (HIDING_MODE);


    l_ske->m_map->HideLights (true);
}

void EndMission (void* p_void, iAwsSource * p_awsSource)
{    
  KCommandProcessor::_Perform ("end_mission");
}

void StopSaveMission (void* p_void, iAwsSource * p_awsSource)
{
  SKE* l_ske = (SKE*) p_void;
  
  if (l_ske->m_appState != KAppState::STANDING)
  {
    SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
      "Error: You are not in STANDING mode!");
    return;
  }//if
  
  //
  //Detach colliders for all the walls in the KMap.
  SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
    "WALKING: colliders destruction for walls.");
  l_ske->m_map->DetachColliders ();//Detach the colliders for walls.
  
  //
  //Detach colliders for all the landmarks.
  SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
    "WALKING: colliders destruction for landmarks.");
  l_ske->m_listLM->DetachColliders (l_ske->m_collisionDet);//Detach the colliders for all the landmarks.
  
  //
  //Show the cursor.
  l_ske->m_cursor->Untrack ();
  
  //
  //Switch application state.
  l_ske->m_appState = KAppState::EDITING;
  SKE::Report (CS_REPORTER_SEVERITY_NOTIFY,
    "Mode switched to EDITING.");
  

  //
  //Show the mouse!
  l_ske->m_mouseManager->SetMode (PUTTING_BLOCK_MODE);

  l_ske->m_map->HideLights (false);

  //
  //Test for saving or not saving the datas of the mission.
  if (!l_ske->m_mission->GetCollectingData ())
    return;//return if datas were not collected.
  
  //
  //Saving of the mission happen here.
  
  csRef<iDocumentSystem> l_xml (CS_QUERY_REGISTRY (g_objReg, iDocumentSystem));
  if (!l_xml) 
    l_xml = csPtr<iDocumentSystem> (new csTinyDocumentSystem ());
  csRef<iDocument> l_doc = l_xml->CreateDocument ();
  csRef<iDocumentNode> l_parent = l_doc->CreateRoot ();  
  l_parent->SetValue ("mission");
  
  l_ske->m_mission->SaveMissionInfo (l_parent);
  
  //
  //Write additional data regarding the mission.
  csRef<iKFreeWalkingMission> l_fWMission = SCF_QUERY_INTERFACE 
    (l_ske->m_mission, iKFreeWalkingMission);
  if (l_fWMission)
    l_fWMission->WriteAdditionalInfo (l_parent);
  
  csRef<iKTargetingMission> l_tMission = SCF_QUERY_INTERFACE 
    (l_ske->m_mission, iKTargetingMission);