-- LegacyWorlds Beta 6
-- PostgreSQL database scripts
--
-- Game updates - fleet movements
--
-- Copyright(C) 2004-2010, DeepClone Development
-- --------------------------------------------------------


CREATE OR REPLACE FUNCTION sys.process_planet_fleet_movements_updates( c_tick BIGINT )
		RETURNS VOID
		STRICT VOLATILE
		SECURITY INVOKER
	AS $$
DECLARE
	rec		RECORD;
	rpid	INT;
BEGIN
	-- Lock all records
	PERFORM f.id FROM sys.updates su
			INNER JOIN verse.updates vu ON vu.update_id = su.id
			INNER JOIN verse.planets p ON p.name_id = vu.planet_id
			INNER JOIN fleets.fleets f ON f.location_id = p.name_id
			INNER JOIN fleets.movements fm ON fm.fleet_id = f.id
			INNER JOIN emp.empires e ON e.name_id = f.owner_id
		WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
			AND su.gu_type = 'PLANET_FLEET_MOVEMENTS'
			AND f.status = 'AVAILABLE'
		FOR UPDATE;

	-- Handle state transitions
	FOR rec IN SELECT f.id  AS id , max( fsd.flight_time ) AS flight_time ,
					s.x AS x , s.y AS y , s.id AS sys_id ,
					isms.ref_point_id AS is_ref_point , isms.outwards AS is_outwards ,
					isms.past_ref_point AS is_past_ref_point ,
					rp.system_id AS is_ref_point_system , rp.orbit AS is_ref_point_orbit ,
					rps.x AS is_ref_point_x , rps.y AS is_ref_point_y
				FROM sys.updates su
					INNER JOIN verse.updates vu ON vu.update_id = su.id
					INNER JOIN verse.planets p ON p.name_id = vu.planet_id
					INNER JOIN verse.systems s ON s.id = p.system_id
					INNER JOIN fleets.fleets f ON f.location_id = p.name_id
					INNER JOIN fleets.ships fs ON fs.fleet_id = f.id
					INNER JOIN tech.ships fsd ON fsd.buildable_id = fs.ship_id 
					INNER JOIN fleets.movements m ON m.fleet_id = f.id
					LEFT OUTER JOIN fleets.ms_system isms ON isms.movement_id = f.id
					LEFT OUTER JOIN verse.planets rp ON isms.ref_point_id = rp.name_id
					LEFT OUTER JOIN verse.systems rps ON rps.id = rp.system_id
				WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
					AND su.gu_type = 'PLANET_FLEET_MOVEMENTS'
					AND f.status = 'AVAILABLE' AND m.state_time_left = 1
				GROUP BY f.id , s.x , s.y , s.id , isms.ref_point_id , isms.outwards ,
					isms.past_ref_point , rp.system_id , rp.orbit , rps.x , rps.y
	LOOP
		IF rec.is_ref_point_orbit IS NOT NULL THEN
			IF rec.is_ref_point_orbit = 5 AND rec.is_outwards AND rec.is_past_ref_point THEN
				-- Fleet exiting system
				INSERT INTO fleets.ms_space ( movement_id , start_x , start_y )
					VALUES ( rec.id , rec.is_ref_point_x , rec.is_ref_point_y );
				DELETE FROM fleets.ms_system WHERE movement_id = rec.id;
				UPDATE fleets.movements
					SET state_time_left = 1 + fleets.compute_outerspace_duration(
							rec.flight_time , rec.is_ref_point_x , rec.is_ref_point_y , rec.x , rec.y )
					WHERE fleet_id = rec.id;
			ELSE
				-- In-system state change
				IF rec.is_past_ref_point THEN
					SELECT INTO rpid p.name_id FROM verse.planets p
						WHERE p.system_id = rec.is_ref_point_system
							AND p.orbit = rec.is_ref_point_orbit + ( CASE WHEN rec.is_outwards THEN 1 ELSE -1 END );
					UPDATE fleets.ms_system
						SET past_ref_point = FALSE , ref_point_id = rpid
						WHERE movement_id = rec.id;
				ELSE
					UPDATE fleets.ms_system SET past_ref_point = TRUE
						WHERE movement_id = rec.id;
				END IF;
				UPDATE fleets.movements
					SET state_time_left = rec.flight_time + 1
					WHERE fleet_id = rec.id;
			END IF;
		ELSE
			-- Fleet entering system
			SELECT INTO rpid p.name_id FROM verse.planets p
				WHERE p.system_id = rec.sys_id AND p.orbit = 5;
			INSERT INTO fleets.ms_system ( movement_id , ref_point_id , outwards , past_ref_point )
				VALUES ( rec.id , rpid , FALSE , FALSE );
			DELETE FROM fleets.ms_space WHERE movement_id = rec.id;
			UPDATE fleets.movements
				SET state_time_left = rec.flight_time + 1
				WHERE fleet_id = rec.id;
		END IF;
	END LOOP;
	
	-- Decrease movement and state time
	UPDATE fleets.movements
		SET state_time_left = state_time_left - 1 ,
			time_left = time_left - 1
		WHERE fleet_id IN (
			SELECT f.id FROM sys.updates su
					INNER JOIN verse.updates vu ON vu.update_id = su.id
					INNER JOIN verse.planets p ON p.name_id = vu.planet_id
					INNER JOIN fleets.fleets f ON f.location_id = p.name_id
					INNER JOIN fleets.movements fm ON fm.fleet_id = f.id
					INNER JOIN emp.empires e ON e.name_id = f.owner_id
				WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
					AND su.gu_type = 'PLANET_FLEET_MOVEMENTS'
					AND f.status = 'AVAILABLE' );
END;
$$ LANGUAGE plpgsql;