;; ----------------------------------------------------------------------------
;; Irrlicht Wrapper For Imperative Languages - Purebasic Examples
;; IrrlichtWrapper and FreeBasic-Example by Frank Dodd (2006)
;; Improved IrrlichtWrapper and PureBasic-Example by Michael Taupitz (2006)
;; ----------------------------------------------------------------------------
;; Advanced Example 01 : A Birds Eye
;; This Example shows a Terrain von top, with a RTS-Style Camera
;; ----------------------------------------------------------------------------

;; ////////////////////////////////////////////////////////////////////////////
;; Includes For extension libraries
;XIncludeFile "..\..\IrrlichtWrapper.pbi"
XIncludeFile #PB_Compiler_Home + "Includes\IrrlichtWrapper_Include.pbi"
;EnableExplicit

;; ////////////////////////////////////////////////////////////////////////////
;; Global variables

Global g_GameQuit.l

Global g_ScreenSize_X.l,g_ScreenSize_Y.l

Global *RiverCamera.l


Define framesPerSecond.s    ; to show the Frame-Rate
Define *staticText.l        ; to show a small Text....

;; ////////////////////////////////////////////////////////////////////////////
;; Load The Ini-File and Create the Device/Driver
Procedure.l _Game_Init()
  Define m_DeviceString.s  
  Define m_DEVICE.l
  Define m_BPP.l
  Define m_WX.l
  Define m_WY.l
  Define m_FULLSCREEN.l
  Define m_STENCILBUFFER.l
  Define m_VSYNC.l
  
  
; Load Preferences    
  If OpenPreferences("config.ini")
    If PreferenceGroup("DEVICE")
      m_DeviceString = ReadPreferenceString("EDT","SOFTWARE")
      m_BPP          = ReadPreferenceLong("BPP",16)
      m_WX           = ReadPreferenceLong("WX",800)
      m_WY           = ReadPreferenceLong("WY",600)
      m_FULLSCREEN   = ReadPreferenceLong("FULLSCREEN",#False)
      m_STENCILBUFFER= ReadPreferenceLong("STENCILBUFFER",#False)
      m_VSYNC        = ReadPreferenceLong("VSYNC",#False)
    Else
      MessageRequester("Fehler","Ini-Datei Fehlerhaft")
      ProcedureReturn #False
    EndIf
  Else
    MessageRequester("Fehler","Ini-Datei Fehlt")
    ProcedureReturn #False
  EndIf
  
 ;Find the correct Driver
  Select m_DeviceString
    Case "DIRECT3D9":
      Debug("#IRR_EDT_DIRECT3D9")
      m_DEVICE=#IRR_EDT_DIRECT3D9
    Case "DIRECT3D8":
      Debug("#IRR_EDT_DIRECT3D8")
      m_DEVICE=#IRR_EDT_DIRECT3D8
    Case "OPENGL":
      Debug("#IRR_EDT_OPENGL")
      m_DEVICE=#IRR_EDT_OPENGL
    Case "SOFTWARE":
      Debug("#IRR_EDT_SOFTWARE")
      m_DEVICE=#IRR_EDT_SOFTWARE
    Case "SOFTWARE2":
      Debug("#IRR_EDT_SOFTWARE2")
      m_DEVICE=#IRR_EDT_SOFTWARE2
    Default:
      Debug("#IRR_EDT_SOFTWARE")
    
      m_DEVICE=#IRR_EDT_SOFTWARE
  EndSelect    

  ;Pull the Screen-Size to the Globals
  g_ScreenSize_X = m_WX
  g_ScreenSize_Y = m_WY
  
  ProcedureReturn IrrStart( m_DEVICE, m_WX, m_WY, m_FULLSCREEN, m_STENCILBUFFER, #IRR_CAPTURE_EVENTS )
  
EndProcedure

;; ////////////////////////////////////////////////////////////////////////////
;; Load the Meshes, and create the Scene Nodes and Camera
Procedure.l _Game_LoadScene()
  Shared *RiverMesh.l
  Shared *RiverSceneNode.l
  Shared *RiverCamera.l
  Shared *RiverTexture.l
  
  ;make a simple Hill-Mesh
  *RiverSceneNode = IrrAddHillPlaneSceneNode( "Riverworld", 10, 10, 10, 10, 1, 1, 43, 122 )

; load texture resources for texturing the scene nodes
  *RiverTexture = IrrGetTexture( "..\..\..\media\terrain-texture.jpg" )

; apply a material to the node to give its surface color
  IrrSetNodeMaterialTexture( *RiverSceneNode, *RiverTexture, 0 )
  
  IrrSetNodeScale(*RiverSceneNode,20.0,0.8,20.0);
  IrrSetNodeMaterialFlag( *RiverSceneNode, #IRR_EMF_NORMALIZE_NORMALS, #True )
  IrrSetNodeMaterialFlag( *RiverSceneNode, #IRR_EMF_LIGHTING, #False )
  IrrSetNodeMaterialShininess(*RiverSceneNode,0,10.0)
  *RiverCamera = IrrAddCamera( 0,500,-250, 0,0,0 )
    
  ProcedureReturn #True
EndProcedure


;; ////////////////////////////////////////////////////////////////////////////
;; Check the Events
Procedure.l _Game_Events()
  Shared *RiverCamera.l
  Define *KeyEvent.IRR_KEY_EVENT
  Define *MouseEvent.IRR_MOUSE_EVENT
  Define newFOV.f, FOV.f
  ; while there are key events waiting to be processed
  While IrrKeyEventAvailable()

    ; read the key event out. the key event has three parameters the key
    ; scan code, the direction of the key and flags that indicate whether
    ; the control key or the shift keys were also pressed
    *KeyEvent = IrrReadKeyEvent()

     If *KeyEvent\direction = #IRR_KEY_DOWN 
        ; arbitrate based on the key that was pressed
        Select *KeyEvent\key
          Case #IRR_KEY_ESCAPE  ;Escape Quits
             g_GameQuit = #True
        EndSelect
     EndIf
  Wend       

  ; while there are mouse events waiting to be processed
  While IrrMouseEventAvailable()
    *MouseEvent = IrrReadMouseEvent()
      If *MouseEvent\action = #IRR_EMIE_MOUSE_WHEEL
		  ; zoom cam
        IrrGetCameraFOV(*RiverCamera,@FOV)
        newFOV = FOV + (*MouseEvent\Wheel/20)
    		If newFOV > 2
			    ProcedureReturn #False;
		    ElseIf (newFOV < 1)
           ProcedureReturn #False;
        Else
           IrrSetCameraFOV(*RiverCamera,newFOV)
		    EndIf
			EndIf
		ProcedureReturn #True;
	Wend  
  ProcedureReturn #True  
EndProcedure


;; ////////////////////////////////////////////////////////////////////////////
;; Update the Camera
Procedure.l _Game_UpdateCamera()
  Shared *RiverCamera.l
  Define mouse_pos.IRR_POS2D
  Define cpos_x.f,cpos_y.f,cpos_z.f
  Define fps.l 
  
; 	; make the camera loop To a fixed Point (45 degrees down)
; 	; in front of it, so it wont stay locked on the old target.
	IrrGetNodePosition(*RiverCamera,@cpos_x,@cpos_y,@cpos_z)
  cpos_z = cpos_z+2.0
  cpos_y = cpos_y-2.0
	IrrSetCameraTarget(*RiverCamera,cpos_x,cpos_y,cpos_z)

	; get the cursor positions
  IrrGetCursorPosition(@mouse_pos)
	; make distance the same For different FPS rates
	fps.l = IrrGetFPS();
	Define dist.f
	If (fps > 5)
        dist = 400.0 / fps;
	Else
		dist = 2.0;
  EndIf

	If mouse_pos\x > (g_ScreenSize_X - 50)
  	IrrGetNodePosition(*RiverCamera.l,@cpos_x.f,@cpos_y.f,@cpos_z.f)
		cpos_x = cpos_x + dist;
	  IrrSetNodePosition(*RiverCamera.l,cpos_x.f,cpos_y.f,cpos_z.f)
	ElseIf mouse_pos\x < 50
  	IrrGetNodePosition(*RiverCamera.l,@cpos_x.f,@cpos_y.f,@cpos_z.f)
		cpos_x = cpos_x - dist;
	  IrrSetNodePosition(*RiverCamera.l,cpos_x.f,cpos_y.f,cpos_z.f)
  EndIf
;   
	If mouse_pos\y < 50
  	IrrGetNodePosition(*RiverCamera.l,@cpos_x.f,@cpos_y.f,@cpos_z.f)
		cpos_z = cpos_z + dist;
	  IrrSetNodePosition(*RiverCamera.l,cpos_x.f,cpos_y.f,cpos_z.f)
	ElseIf mouse_pos\y > (g_ScreenSize_Y - 50)
  	IrrGetNodePosition(*RiverCamera.l,@cpos_x.f,@cpos_y.f,@cpos_z.f)
		cpos_z = cpos_z - dist;
	  IrrSetNodePosition(*RiverCamera.l,cpos_x.f,cpos_y.f,cpos_z.f)
  EndIf

 ProcedureReturn #True  
EndProcedure


;--- START
;; ////////////////////////////////////////////////////////////////////////////
;; Init the DLL
;InitIrrlichtWrapperDll()

;; Initialize the Game 
If _Game_Init()
  g_GameQuit = #False   ; Start the Game
  
    ;; Load the Meshes, and make the Scene
  _Game_LoadScene()

  ;;pu a Text on the Screen
   *staticText  = IrrGuiAddStaticText( "A Example for a RTS-Style-Camera. Use your Mouse and Mouse-Wheel", 4,0,300,36, #IRR_GUI_NO_BORDER, #IRR_GUI_NO_WRAP )
  IrrGuiStaticSetOverrideColor(*staticText,255,255,240) 
  
  ; -----------------------------------------------------------------------------
  ; while the irrlicht environment is still running
  While IrrRunning() And g_GameQuit = #False

      ; check available Events
      _Game_Events()
  
      ; update the Camera
      _Game_UpdateCamera()

      ; begin the scene, erasing the canvas with sky-blue before rendering
      IrrBeginScene( 0,0,0 )
        
      ; draw the scene
      IrrDrawScene()

    ; draw the Graphical User Interface
      IrrDrawGUI()
      
      ; end drawing the scene and render it
      IrrEndScene()
      
      framesPerSecond.s = "FPS:" + Str(IrrGetFPS())
    ; set the window caption
      IrrSetWindowCaption( framesPerSecond)
      
      Delay(2)
  Wend
  
EndIf

; -----------------------------------------------------------------------------
; Stop the irrlicht engine and release resources
IrrStop()

;; ////////////////////////////////////////////////////////////////////////////
;; Free the DLL
;FreeIrrlichtWrapperDll()

; IDE Options = PureBasic 4.10 Beta 3 (Windows - x86)
; ExecutableFormat = Console
; CursorPosition = 113
; Folding = -
; EnableXP
; Executable = BirdsEye.exe
; CPU = 1