--[[-----------------------------------------------------------------------------------------------

	GoalManager

-------------------------------------------------------------------------------------------------]]

global_goal_id = 0

class 'GoalManager'

function GoalManager:__init()

	EETS_ID = -1 
	
	self.goals = {}

end

function GoalManager:AddGoal( goal )

	table.insert( self.goals, goal )
	global_goal_id = global_goal_id + 1

end

function GoalManager:RemoveGoal( goal )

	for i in self.goals do

		if self.goals[i].guid == goal.guid then
			table.remove( self.goals, i )
		end
	
	end

end

function GoalManager:GetObject( id )

	if id == EETS_ID then
		return World_GetEets()
	else
		return World_GetObjectByID( id )
	end

end

function GoalManager:Validate()

	for i in self.goals do
		local goal = self.goals[i]
				--goal.success = goal:Validate()
                --FIXME! uncomment this and fix it properly later
				if goal:Validate() == true then
                        goal:Trigger()
                end
	end

	--now check if they were all successful. done afterward in case validating caused new goals to be created
	for i in self.goals do
		if self.goals[i].required and not self.goals[i].success then
			--too bad
			return
		end
	end
		
end

function GoalManager:DebugDisplay()

	--print the debug text of all the current goals
	local str = "Currently running goals:\n-----------------------\n"
	for i in self.goals do
		str = str..(self.goals[i]:GetDebugText()).."\n"
		self.goals[i]:DebugDisplay()
	end
	
	Debug_DrawText( str, Vector2( 600, 20 ) )

end

--[[-----------------------------------------------------------------------------------------------

	Goal abstract base class

-------------------------------------------------------------------------------------------------]]

class 'Goal'

function Goal:__init()
	
	self.guid = global_goal_id
	self.success = false
	self.required = true
	self.name = "No name"
	goal_manager:AddGoal( self )
	
end

function Goal:GetDebugText()

	return self.name.." ("..tostring(self.success)..") "..self.guid

end

function Goal:Validate()

	return false

end

--happens when this goal is valid
function Goal:Trigger()

	self.success = true

end

function Goal:DebugDisplay()
	--do nothing
end


-- Do not override.  Sets whether a goal is required for the win condition.
function Goal:SetRequired( required )

        self.required = required

end

--[[-----------------------------------------------------------------------------------------------

	Positional Goal

-------------------------------------------------------------------------------------------------]]

class 'PositionalGoal' (Goal)

function PositionalGoal:__init( id, top_left, bottom_right ) super()

	self.name = "Positional Goal: "..id
	self.id = id
	self.top_left = top_left
	self.bottom_right = bottom_right

	self.top_right = Vector2( self.bottom_right.x, self.top_left.y )
	self.bottom_left = Vector2( self.top_left.x, self.bottom_right.y )
	
end

function PositionalGoal:Validate()

	local object = goal_manager:GetObject( self.id )
	if object == nil then
		return false
	end
	
	local pos = object:GetPosition()
	
	--check we're in bounds
	if 	pos.x > self.top_left.x and
		pos.x < self.top_right.x and
		pos.y < self.bottom_right.y and
		pos.y > self.top_right.y then
		
		return true
	end

end

function PositionalGoal:DebugDisplay()

	Debug_DrawLine( self.top_left, self.top_right )
	Debug_DrawLine( self.top_right, self.bottom_right )
	Debug_DrawLine( self.bottom_right, self.bottom_left )
	Debug_DrawLine( self.bottom_left, self.top_left )

end

--[[-----------------------------------------------------------------------------------------------

	EmotionGoal

-------------------------------------------------------------------------------------------------]]

class 'EmotionGoal' (Goal)

function EmotionGoal:__init( emotion ) super()

	self.name = "Emotion: "..emotion
	self.emotion = World_HashString(emotion)
	
end

function EmotionGoal:Validate()

	local eets = goal_manager:GetObject( EETS_ID )
	if eets:GetBlueprintHash() == self.emotion then
		return true
	end
		
end

--[[-----------------------------------------------------------------------------------------------

	OutGoal

-------------------------------------------------------------------------------------------------]]

class 'OutGoal' (Goal)

function OutGoal:__init( id ) super()

	self.name = "Out goal: "..id
	self.id = id
	
end

function OutGoal:Validate()

	local object = goal_manager:GetObject( self.id )
	if object == nil then
		return false
	end
	
	local pos = object:GetPosition()
	
	--check we're in bounds
	if 	pos.x > 1024 or
		pos.x < 0 or
		pos.y < 0 or
		pos.y > 768 then
		
		return true
	end

end

--[[-----------------------------------------------------------------------------------------------

	EatenGoal

-------------------------------------------------------------------------------------------------]]

class 'EatenGoal' (Goal)

function EatenGoal:__init( id ) super()

	self.name = "Eaten goal: "..id
	self.id = id
	
end

function EatenGoal:Validate()

	local object = goal_manager:GetObject( self.id )
	if object == nil then
		return false
	end

	local edible = object:GetEdibleExtension()
	if edible == nil then
		--Print( self.id.." is not edible!" )
		return false
	end
	
	return edible:GetEaten()

end

--[[-----------------------------------------------------------------------------------------------

	MessageBoxGoal

        -When validated, this goal displays a goal box with a message
        -Will be validated at most once.
        
        Params:
                dialog: table defining the message box, see below for fields
                goal: the actual goal object used to determine when this message box is displayed
        -------------------------------------------------------------------------------------------------]]

class 'MessageBoxGoal' (Goal)

function MessageBoxGoal:__init( dialog, goal ) super()

	-- default widgets for the goal box
	-- widgets defined in Simulator_Screen.lua
	if dialog.dialog_widget == nil then
		dialog.dialog_widget = "ContextSensitiveHelpSmallDialog"
	end       
	if dialog.text_widget == nil then
		dialog.text_widget = "ContextSensitiveHelpSmallDialogText"
	end
	if dialog.text == nil then
		dialog.text = "Goal complete! (helptext not defined)"
	end
	if dialog.position == nil then
		dialog.position = Vector2(0,0)
	end
	
	self.goal = goal
	self.dialog = dialog
	self.name = goal.name

	goal_manager:RemoveGoal( goal )
	
	self.required = false

end

function MessageBoxGoal:Validate()

	-- we validate *only the first time* (so we don't get repeated messageboxes)
	if self.success == true then
		return false
	else
		return self.goal:Validate()
	end

end


function MessageBoxGoal:Trigger()

    Goal.Trigger( self )

	if self.dialog.object_id ~= nil then
		local obj = goal_manager:GetObject( self.dialog.object_id )
		World_ShowGoalBox( self.dialog.dialog_widget, obj:GetPosition() + self.dialog.position, self.dialog.text, self.dialog.text_widget, self.dialog.dialog_widget )
		
		if self.dialog.effect then
			World_ShowGoalBoxFX( self.dialog.effect, obj:GetPosition() + self.dialog.effect_pos )
		end
	else
		World_ShowGoalBox( self.dialog.dialog_widget, self.dialog.position, self.dialog.text, self.dialog.text_widget, self.dialog.dialog_widget )
		
		if self.dialog.effect then
			World_ShowGoalBoxFX( self.dialog.effect, self.dialog.effect_pos )
		end
	end

end


function MessageBoxGoal:GetDebugText()

	return self.goal:GetDebugText() .. " (MessageBox goal) "..self.guid

end

function MessageBoxGoal:DebugDisplay()

	self.goal:DebugDisplay()
	
end

--[[-----------------------------------------------------------------------------------------------

	Setup

-------------------------------------------------------------------------------------------------]]

goal_manager = GoalManager()
eets = EETS_ID

function Update()

	goal_manager:Validate()

end

function Draw()

	goal_manager:DebugDisplay()

end

BOX_TYPE_NORMAL 	= { [[WarrenTheWiseDialog]], [[WarrenTheWiseDialogText]] }
BOX_TYPE_LARGE 	= { [[WarrenTheWiseDialogLarge]], [[WarrenTheWiseDialogLargeText]] }
BOX_TYPE_NORMAL2 	= { [[WarrenTheWise2Dialog]], [[WarrenTheWise2DialogText]] }
BOX_TYPE_LARGE2 	= { [[WarrenTheWise2DialogLarge]], [[WarrenTheWise2DialogLargeText]] }

function CreateMessageBox( text, pos, box_type, object_id, effect, effect_pos )

	local box =
	{
		text = text,
		position = pos,
		dialog_widget = box_type[1],
		text_widget = box_type[2],
		object_id = object_id,
		effect = effect,
		effect_pos = effect_pos
	}
	
	return box
	
end

