;==================================================================
;Project Title: CRYSTALIUM
;Author:        Vladislav Borzunov aka ObelardO
;Email:         Obelardos@gmail.com 
;Version:       0.9 Alpha
;Date:          04.03.13
;Notes:         Player control code-file
;==================================================================

Const PLAYER_COLLISION = 1

Global PLAYER_CAMERA_X#
Global PLAYER_CAMERA_Y#
Global PLAYER_CAMERA_Z#
Global PLAYER_CAMERA_ZOOM# = 20.0
Global PLAYER_CAMERA_SHAKE# = 1.0
Global PLAYER_CAMERA_ZOOMING = 1

Global PLAYER_ACTIVE_X#
Global PLAYER_ACTIVE_Y#
Global PLAYER_ACTIVE_Z#

Global PLAYER_SHADER
Global PLAYER_TEXTURE
Global PLAYER_TEXTURE_2
Global PLAYER_ENTITY
Global PLAYER_POWER
Global PLAYER_LIGHTINING# = 22.0
Global PLAYER_SCORE
Global PLAYER_CRYSTALS

Global DELTATIME = 1

Global LIGHT_POWER = 1

; main player type
Type TYPE_PLAYER
	Field Entity
	Field Camera
     ;Field CameraBase
      Field Light
	Field Controllable%
	Field Plasm[5]
	Field Lightining[1]
	Field Status$
	Field SoundPoint
End Type

; creating a new player
Function CreatePlayer()
	PLAYER.TYPE_PLAYER = New TYPE_PLAYER
	PLAYER\Controllable = True
	
	PLAYER\Entity = xCreateSphere(12)
	xPositionEntity PLAYER\Entity, 0, 0, 0
      xEntityAlpha    PLAYER\Entity, 0
	xEntityRadius   PLAYER\Entity, 0.99
	xEntityType     PLAYER\Entity, PLAYER_COLLISION

	PLAYER\SoundPoint = xCreateCube()
	xEntityAlpha    PLAYER\SoundPoint, 0
	xEmitSound	    sOUND_PLAYER_LOOP, PLAYER\SoundPoint

	PLAYER\Camera = xCreateCamera();(PLAYER\Entity)
	xPositionEntity PLAYER\Camera, 0, 0, -8
      xCameraRange    PLAYER\Camera, 0.1, 500
     ;xLightColor     PLAYER\Camera, 255, 200, 150
      xCameraProjMode PLAYER\Camera, 2
      xCameraZoom     PLAYER\Camera, 5
      xScaleEntity    PLAYER\Camera, 0.2,0.2,0.2
	xCreateListener PLAYER\Camera

	PLAYER\Light =  xCreateLight(2)
	xLightRange     PLAYER\Light, 20
	xPositionEntity PLAYER\Light, 0, 0, -4
	xEntityParent   PLAYER\Light, PLAYER\Entity

	; Animation
	For i = 0 To 5
		PLAYER\Plasm[i] = CreateSurface2(1.5 - (i * 0.1))
		xEntityParent     PLAYER\Plasm[i], PLAYER\Entity
		xPositionEntity   PLAYER\Plasm[i], 0, 0, -i * 0.01
		xEntityTexture    PLAYER\Plasm[i], PLAYER_TEXTURE, 0, 0
		xTurnEntity       PLAYER\Plasm[i], 0, 180 *(i Mod 2), i * (i Mod 2) * 20
		xEntityFX         PLAYER\Plasm[i], 1 + 16
		xEntityColor      PLAYER\Plasm[i], 230, 255 - (6 - i) * 30, 255 - (6-i) * 6
	Next

	For i = 0 To 1
		PLAYER\Lightining[i] = CreateSurface2(2-(i*0.1))
		xEntityParent  	     PLAYER\Lightining[i], PLAYER\Entity
		xEntityTexture 	     PLAYER\Lightining[i], TEXTURE_LIGHT, 0, 0
		xEntityFX              PLAYER\Lightining[i], 1 + 16
		xTurnEntity            PLAYER\Lightining[i], 0, 180 *(i Mod 2), 0
		xPositionEntity        PLAYER\Lightining[i], 0, 0, -i * 0.01
	Next
End Function

; Update all players
Function UpdatePlayers()

	For PLAYER.TYPE_PLAYER = Each TYPE_PLAYER
		If PLAYER\Controllable

			Speed#=1.5 * DELTATIME;+xDeltaTime()*0.1
			PLAYER_ENTITY = PLAYER\Entity

			; Animation
			For i = 0 To 5
				xTurnEntity  PLAYER\Plasm[i], 0, 0, (i+1)*0.5
			Next
			For i = 0 To 1
				xTurnEntity  PLAYER\Lightining[i], 0, 0, (i+1)*0.4
				xScaleEntity PLAYER\Lightining[i], Sin(MilliSecs()*0.2)*0.1+1, Sin(MilliSecs()*0.2)*0.1+1, Sin(MilliSecs()*0.2)*0.1+1
			Next

			; Sound point position
			xPositionEntity PLAYER\SoundPoint, PLAYER_ACTIVE_X, PLAYER_ACTIVE_Y , -(8-((PLAYER_CAMERA_ZOOM - 5)+1 * 0.5))

			; Player moving
			If xKeyDown(32) Or xKeyDown(KEY_RIGHT) xMoveEntity PLAYER\Entity, 0.1*Speed, 0, 0
			If xKeyDown(30) Or xKeyDown(KEY_LEFT)  xMoveEntity PLAYER\Entity,-0.1*Speed, 0, 0
			If xKeyDown(17) Or xKeyDown(KEY_UP)    xMoveEntity PLAYER\Entity, 0, 0.1*Speed, 0
			If xKeyDown(31) Or xKeyDown(KEY_DOWN)  xMoveEntity PLAYER\Entity, 0,-0.1*Speed, 0

			; Camera and lightining
			xLightRange  PLAYER\Light,  PLAYER_CAMERA_ZOOM * LIGHT_POWER
			
			If PLAYER_CAMERA_ZOOM < PLAYER_LIGHTINING PLAYER_CAMERA_ZOOM = PLAYER_CAMERA_ZOOM + (PLAYER_LIGHTINING - PLAYER_CAMERA_ZOOM) * 0.025 * DELTATIME
			If PLAYER_CAMERA_ZOOM > PLAYER_LIGHTINING PLAYER_CAMERA_ZOOM = PLAYER_CAMERA_ZOOM - (PLAYER_CAMERA_ZOOM - PLAYER_LIGHTINING) * 0.025 * DELTATIME
			If PLAYER_CAMERA_ZOOM > 20 PLAYER_CAMERA_ZOOM = 20
			PLAYER_LIGHTINING = PLAYER_LIGHTINING - 0.002 * DELTATIME
			If PLAYER_LIGHTINING <  5 createmenu("gameover");PLAYER_LIGHTINING =  5
		      If PLAYER_LIGHTINING > 25 PLAYER_LIGHTINING = 25
			xCameraZoom  PLAYER\Camera, 25 - PLAYER_CAMERA_ZOOM

			If Not PLAYER_CAMERA_ZOOMING xCameraZoom  PLAYER\Camera, 5

			; Globals
			PLAYER_ACTIVE_X = xEntityX(PLAYER\Entity)
			PLAYER_ACTIVE_Y = xEntityY(PLAYER\Entity)
			PLAYER_ACTIVE_Z = -8.0 ; -8.0 for shaders vector's 

			PLAYER_CAMERA_X = xEntityX(PLAYER\Camera)
			PLAYER_CAMERA_Y = xEntityY(PLAYER\Camera)
			PLAYER_CAMERA_Z = xEntityZ(PLAYER\Camera); (-8.0)

			; Camera smooth moving
			If PLAYER_CAMERA_X < PLAYER_ACTIVE_X xMoveEntity PLAYER\Camera, (PLAYER_ACTIVE_X - PLAYER_CAMERA_X) * 0.05 * DELTATIME, 0, 0
			If PLAYER_CAMERA_X > PLAYER_ACTIVE_X xMoveEntity PLAYER\Camera, (PLAYER_ACTIVE_X - PLAYER_CAMERA_X) * 0.05 * DELTATIME, 0, 0
			If PLAYER_CAMERA_Y < PLAYER_ACTIVE_Y xMoveEntity PLAYER\Camera, 0, (PLAYER_ACTIVE_Y - PLAYER_CAMERA_Y) * 0.05 * DELTATIME, 0
			If PLAYER_CAMERA_Y > PLAYER_ACTIVE_Y xMoveEntity PLAYER\Camera, 0, (PLAYER_ACTIVE_Y - PLAYER_CAMERA_Y) * 0.05 * DELTATIME, 0

			; GUI
			If CRYSTAL_COUNT
				xDrawImage IMAGE_GENERAL, 20, 20, 12
				TextDraw(98, 40, PLAYER_CRYSTALS+ "\" +CRYSTAL_COUNT, 30)
				If PLAYER_CRYSTALS >= CRYSTAL_COUNT
					xDrawImage IMAGE_GENERAL, 20, 100, 13
					TextDraw(98, 120, "opened", 30)
				End If
			End If

			If MAP_TIME
				TextDraw(250 + Len(PLAYER_SCORE)*18, WINDOW_HEIGHT - 52, "time: "+MAP_TIME, 20)
				If MilliSecs() > MAP_FRAMEPAUSE + 1000 - 1000 / xGetFPS()
					MAP_TIME = MAP_TIME - 1
					If MAP_TIME = 0 createmenu("timeover")
					MAP_FRAMEPAUSE=MilliSecs()
				End If
			End If

			TextDraw(20, WINDOW_HEIGHT - 52, "score: "+PLAYER_SCORE, 20)
			
			; Block removing
			BLOCK = xEntityCollided(PLAYER\Entity, MAP_COLLISION)
			If BLOCK
				Name$ =  xEntityName(BLOCK)
				If Name$ = "04" Or Name$ = "03" Or Name$ = "06" 
					If (xKeyDown(32) Or xKeyDown(KEY_RIGHT)) And Abs(PLAYER_ACTIVE_Y-xEntityY(BLOCK)) < 0.8 BlockDestroy = True
					If (xKeyDown(30) Or xKeyDown(KEY_LEFT))  And Abs(PLAYER_ACTIVE_Y-xEntityY(BLOCK)) < 0.8 BlockDestroy = True
					If (xKeyDown(17) Or xKeyDown(KEY_UP))    And Abs(PLAYER_ACTIVE_X-xEntityX(BLOCK)) < 0.8 BlockDestroy = True
					If (xKeyDown(31) Or xKeyDown(KEY_DOWN))  And Abs(PLAYER_ACTIVE_X-xEntityX(BLOCK)) < 0.8 BlockDestroy = True
					If BlockDestroy
						DeleteBlock(BLOCK)
						Sound = Rand(1, 4)
						Select Sound
							Case 1: xPlaySound SOUND_BLOCK_REMOVE_A
							Case 2: xPlaySound SOUND_BLOCK_REMOVE_B
							Case 3: xPlaySound SOUND_BLOCK_REMOVE_C
							Case 4: xPlaySound SOUND_BLOCK_REMOVE_D
						End Select
						PLAYER_SCORE = PLAYER_SCORE + 1
					End If
				End If
			End If

			If xEntityZ(PLAYER\Entity) <> 0 xPositionEntity PLAYER\Entity, PLAYER_ACTIVE_X, PLAYER_ACTIVE_Y, 0
		End If
	Next

	If DEBUG_MODE
		; map
		If MAP_DEBUG
			xRect 10, 100, MAP_WIDTH * 18 + 20, 18 * MAP_HEIGHT, 0: xColor 20,   20, 255,  64
			xRect 10, 100, MAP_WIDTH * 18 + 20, 18 * MAP_HEIGHT, 1: xColor 255, 255, 255, 255
			For LocalW = 0 To MAP_WIDTH
				For LocalH = 0 To MAP_HEIGHT
					If Not MAP_MATRIX(Localw, Localh) = "" xText 10 + 18 * Localw, 100 + 18 * Localh, MAP_MATRIX(Localw, Localh)
				Next
			Next
		End If
		; 
		xRect 10, 10, 200, 85, 0: xColor 20,   20, 255,  64
		xRect 10, 10, 200, 85, 1: xColor 255, 255, 255, 255
		xText 10,10, "CRYSTALIUM: "   + VERSION
		xText 10,25, "Fps: "		+ xGetFPS()
		xText 10,40, "Tris: "		+ xTrisRendered()
		xText 10,55, "DIP calls: " 	+ xDIPCounter()
		xText 10,70, "Deltatime: "    + xDeltaTime()
		; player stat
		xRect WINDOW_WIDTH - 210, 10, 200, 130, 0: xColor 20,   20, 255,  64
		xRect WINDOW_WIDTH - 210, 10, 200, 130, 1: xColor 255, 255, 255, 255
		xText WINDOW_WIDTH - 205, 15, "PLAYER:"
		xText WINDOW_WIDTH - 205, 30, "CAMERA X " + PLAYER_CAMERA_X
		xText WINDOW_WIDTH - 205, 45, "CAMERA Y " + PLAYER_CAMERA_Y
		xText WINDOW_WIDTH - 205, 60, "CAMERA Z " + PLAYER_CAMERA_Z
		xText WINDOW_WIDTH - 205, 75, "CAMERA A " + (25-PLAYER_CAMERA_ZOOM)
		xText WINDOW_WIDTH - 205, 90, "CAMERA 2 " + PLAYER_CAMERA_ZOOM
		xText WINDOW_WIDTH - 205, 105,"PLAYER L " + PLAYER_LIGHTINING
		xText WINDOW_WIDTH - 205, 120,"PLAYER S "  ;xEntityZ(PLAYER\SoundPoint)
	End If
End Function

; Move player to new position
Function PositionPlayer(x = 0, y = 0)
	For PLAYER.TYPE_PLAYER = Each TYPE_PLAYER
		If PLAYER\Controllable
			xEntityType     PLAYER\Entity, 0
			xPositionEntity PLAYER\Entity, x, y, 0
			xEntityType     PLAYER\Entity, PLAYER_COLLISION
		End If
	Next
End Function 

; Create the disk mesh [NOT USED]
Function CreateDisk(sectors%, parent% = 0)
	Local mesh = xCreateMesh(parent%)
	Local surf = xCreateSurface(mesh)
	Local i%

	; may be you need in this function :P
	xAddVertex(surf, 0.0, 0.0, 0.0, 0.0, 1.0)
	xVertexNormal(surf, 0, 0.0, 0.0, -1.0)
	xAddVertex(surf, 0.0, 1.0, 0.0, 0.0, 0.0)
	xVertexNormal(surf, 1, 0.0, 1.0, -1.0)
	For i% = 1 To sectors
		xAddVertex(surf, 0.0, 0.0, 0.0, Float(i) / sectors, 1.0)
		xVertexNormal(surf, 2*i, Sin(360.0 / sectors * i), Cos(360.0 / sectors * i), -1.0)
		xAddVertex(surf, Sin(360.0 / sectors * i), Cos(360.0 / sectors * i), 0.0, Float(i) / sectors, 0.0)
		xVertexNormal(surf, 2*i+1, Sin(360.0 / sectors * i), Cos(360.0 / sectors * i), -1.0)
		xAddTriangle(surf, 2*i-2, 2*i-1, 2*i+1)
	Next
	xAddTriangle(surf, 2*sectors, 2*sectors+1, 2*sectors+1)
	
	Return mesh
End Function

; Create the surface
Function CreateSurface2(size# = 1)
	mesh		 = xCreateMesh()
	Surface      = xCreateSurface(mesh)
	vertex0      = xAddVertex(Surface, -size, -size, 0, 0, 1)
	vertex1      = xAddVertex(Surface, -size,  size, 0, 0, 0)
	vertex2      = xAddVertex(Surface,  size,  size, 0, 1, 0)
	vertex3      = xAddVertex(Surface,  size, -size, 0, 1, 1)
	Trinagle1    = xAddTriangle(Surface, vertex0, vertex1, vertex2)
	Trinagle2    = xAddTriangle(Surface, vertex3, vertex0, vertex2)

	xUpdateNormals mesh
	Return mesh
End Function

; Rotation texture in center of entity 
Function RotateTexture2(Texture, Angle#)
	xRotateTexture(Texture, Angle)
	Local Dx# = Cos(Angle)*0.5
	Local Dy# = Sin(Angle)*0.5
	xPositionTexture(Texture, (Dx-0.5) - Dy, (Dy-0.5) + Dx)
End Function