module("m_Rest")
module("m_Attack")
module("m_DangerSound")
module("m_NotDangerSound")
module("m_Hit")

class "m_Monster"
function m_Monster:__init( mnstr, script_name )
    self.npc_name       = mnstr
    self.scr_name   	= script_name
    self.on_line        = false
    self.memory         = { npc = nil, enemy = nil; sound = nil ; hit = nil }

    self.Rest       	= m_rest.stateRest     		  		  ( self.scr_name, self.memory )
    self.Attack     	= m_attack.stateAttack 		  		  ( self.scr_name, self.memory )
    self.Hit			= m_hit.stateHit              		  ( self.scr_name, self.memory )
    self.DangerSound    = m_dangersound.stateDangerSound      ( self.scr_name, self.memory )
    self.NotDangerSound = m_notdangersound.stateNotDangerSound( self.scr_name, self.memory )

    self.curState   	= nil

--hit - who, ammount, time
end

--------------------------------------------------------------------------------

function m_Monster:is_on_line()
	if( level.object( self.npc_name ) ) then
    	if( self.on_line == false ) then
        	self.memory.npc = level.object( self.npc_name )
            printf( "On_line - %s", self.npc_name )
            if( self.curState ) then self.curState:update() end
            self.on_line = true
            printf( "_____________In line ______________" )
        end
    else
        if( self.on_line ) then printf( "________________Off line ______________" ) end
        self.on_line = false
    end
end

--------------------------------------------------------------------------------

function m_Monster:execute()

    self:is_on_line()
    if( self.on_line == false ) then return true end

    --Проверяем, живой ли монстр
    if( self.memory.npc:alive() == false ) then
--    	if( self.npc:get_script() ) then
--    		self.npc:script( false, self.scr_name )
--        end
        return false
    end

    self:update_world()

--	printf( "Sound time %d. Danger %d", self.memory.sound.time, self.memory.sound.danger )
   	self:select_state()

    self.curState:execute()
    return true
end

--------------------------------------------------------------------------------

function m_Monster:select_state()

	if( self.memory.enemy ) then

       	self:set_state							( self.Attack )

    elseif( self.memory.hit.time ~= 0 ) then

    	self:set_state							( self.Hit )

    elseif( self.memory.sound.time ~= 0 ) then

    	if( self.memory.sound.danger ~= 0 ) then
        	self:set_state						( self.DangerSound )
        else
        	self:set_state						( self.NotDangerSound )
        end

    else
    	self:set_state							( self.Rest )
    end

end

--------------------------------------------------------------------------------

function m_Monster:set_state( new_state )
    if( self.curState ) then
	    if( new_state:id() == self.curState:id() ) then return end
	    self.curState:finalize()
    end

    printf( "Set new state. His id %f", new_state:id() )

    self.curState = new_state
    self.curState:initialize()
end

--------------------------------------------------------------------------------

function m_Monster:check_completed()
	if( self.on_line == false ) then return false end  --Будем считать что в офлайне мы еще не умерли
   return ( self.memory.npc:alive() == false )
end

--------------------------------------------------------------------------------

function m_Monster:initialize()
end

--------------------------------------------------------------------------------

function m_Monster:finalize()
	if( self.curState ) then self.curState:finalize() end
	printf("bobik finalize")
	if(self.memory.npc and self.memory.npc:alive()) then
		printf("Bobik alive")
	else
		printf("Bobik dead")
	end
end

--------------------------------------------------------------------------------

function m_Monster:update_world()
    self.memory.sound     = self.memory.npc:get_sound_info()
    self.memory.hit		  = self.memory.npc:get_monster_hit_info()
    self.memory.enemy     = self.memory.npc:get_enemy()


    if( self.memory.enemy and self.memory.enemy:alive() == false ) then
    	self.memory.enemy  = nil
    end
end

function m_Monster:id()
	return 0
end

function m_Monster:__finalize()
    self.memory.sound     = nil
    self.memory.hit		  = nil
    self.memory.enemy     = nil
	self.memory			  = nil
end
--  id классов
--  0 - m_Monster
--  1 - stateAttack
--  2 - stateRest
--	3 - stateWalk
--  4 - stateEat
--  5 - stateSound
--  6 - stateDangerSound
--  7 - stateNotDangerSound
--  8 - stateWalkPoint
--  9 - stateGarbageWalk
--  10 - stateHit

--==============================================================================
--==========Монстр который живет возле некоторой точки==========================
class "m_MonsterPoint" ( m_Monster )
function m_MonsterPoint:__init( mnstr, script_name, point_o, radius_o ) super( mnstr, script_name )
    self.Rest           = m_rest.stateRestPoint       			   ( self.scr_name, self.memory, point_o, radius_o )
end

--==============================================================================
--===Бобик. На врагов гавкает, на опасный звук смотрит, живет возле некоторой точки=====================
class "m_MonsterBobik" ( m_Monster )
function m_MonsterBobik:__init( mnstr, script_name, point_o, radius_o ) super( mnstr, script_name )
    self.Rest           = m_rest.stateRestPoint                    ( self.scr_name, self.memory, point_o, radius_o )
    self.DangerSound    = m_dangersound.stateDangerSoundLookAround ( self.scr_name, self.memory )
    self.NotDangerSound = m_dangersound.stateDangerSoundLookAround ( self.scr_name, self.memory )
    self.Attack         = m_attack.stateAttackThreaten			   ( self.scr_name, self.memory )
--    self.Hit			= m_hit.stateHitRunToHit				   ( self.scr_name, self.memory )
end
--==============================================================================
--===Собаки возле БТР, при виде врага бегут к некоторой точки и там его ждут====
class "m_MonsterArtful" ( m_Monster )
function m_MonsterArtful:__init( mnstr, script_name, way_o, point_o, radius_o ) super( mnstr, script_name )
    self.Rest           = m_rest.stateRestPoint                 	( self.scr_name, self.memory, point_o, radius_o )
	self.Attack  		= m_attack.stateAttackArtful				( self.scr_name, self.memory, way_o )
    self.DangerSound    = m_dangersound.stateDangerSoundLookAround  ( self.scr_name, self.memory )
	self.attacked       = false
end
--------------------------------------------------------------------------------
function m_MonsterArtful:execute()

    self:is_on_line()
    if( self.on_line == false ) then return true end

    --Проверяем, живой ли монстр
    if( self.memory.npc:alive() == false ) then
        return false
    end

    self:update_world()
    --Если появляется враг, то состояние атаки работает до тех пор, пока оно не закончится, а не до тех пор, пока пропадет враг
	if(self.memory.enemy and self.attacked == false) then
		--Запоминаем, что появился враг и выбираем состояние атаки
    	self.attacked = true
        self:select_state()
    end

    if(self.attacked == false) then
   		--Не атакуем, значит выбираем состояние
    	self:select_state()
    end

    self.curState:execute()

    if(self.attacked and self.curState:id() == 1)then
    	if(self.curState:check_complited())then
        	self.attacked = false
        end
    end

    return true
end
--==============================================================================
--=========== Черный пес - патрулирует маршрут, на опасный звук бежит ==========
class "garbage_black_dog" ( m_Monster )
function garbage_black_dog:__init( mnstr, script_name, way_o, dir ) super( mnstr, script_name )
    self.Rest           = m_rest.stateGarbageRest     				( self.scr_name, self.memory, way_o, dir )
    self.DangerSound    = m_dangersound.stateDangerSoundRun			( self.scr_name, self.memory )
end

--==============================================================================
--=========== Черный кабан - патрулирует маршрут, на опасный звук бежит ==========
class "garbage_boar" ( m_Monster )
function garbage_boar:__init( mnstr, script_name, way_o, dir ) super( mnstr, script_name )
    self.Rest           = m_rest.stateGarbageBoarRest               ( self.scr_name, self.memory, way_o, dir )
    self.DangerSound    = m_dangersound.stateDangerSoundRun         ( self.scr_name, self.memory )
end


--==============================================================================
--=========== Видит врага - убегает ============================================
class "m_Coward" ( m_Monster )
function m_Coward:__init( mnstr, script_name) super ( mnstr, script_name )
    self.Attack         = m_attack.stateCowardAttack( self.scr_name, self.memory )
end

--==============================================================================
--=========== Бегут на выстрелы ================================================
class "m_Hunter" ( m_Monster )
function m_Hunter:__init( mnstr, script_name, radius ) super( mnstr, script_name )
    self.DangerSound    = m_dangersound.stateDangerSoundRun ( self.scr_name, self.memory )
    self.Rest           = m_rest.stateRestPoint             ( self.scr_name, self.memory, radius )
end