

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/
//_/_/  This file is part of CMSDK version 2.1.1.260726 (26 July 2026)
//_/_/  
//_/_/  developed by
//_/_/  
//_/_/  Communicative Machines Ltd. 
//_/_/    http://cmlabs.com/
//_/_/  Copyright (c) 2026
//_/_/  
//_/_/  in collaboration with 
//_/_/  
//_/_/  Icelandic Institute for Intelligent Machines ses
//_/_/    Menntavegur 1
//_/_/    101 Reykjavik
//_/_/    ICELAND
//_/_/    http://www.iiim.is/
//_/_/
//_/_/  and is released under the following
//_/_/  
//_/_/  EXTENDED BSD License
//_/_/
//_/_/  Redistribution and use in source and binary forms, with or without
//_/_/  modification, is permitted provided that the following conditions 
//_/_/  are met:
//_/_/
//_/_/  - Redistributions of source code must retain the above copyright 
//_/_/    and collaboration notice, this list of conditions and the following 
//_/_/    disclaimer.
//_/_/
//_/_/  - Redistributions in binary form must reproduce the above copyright 
//_/_/    notice, this list of conditions and the following disclaimer in the 
//_/_/    documentation and/or other materials provided with the distribution.
//_/_/
//_/_/  - Neither the name of its copyright holders nor the names of its 
//_/_/    contributors may be used to endorse or promote products derived from 
//_/_/    this software without specific prior written permission.
//_/_/
//_/_/  - CADIA Clause: The license granted in and to the software under this 
//_/_/    agreement is a limited-use license. The software may not be used in 
//_/_/    furtherance of: (i) intentionally causing bodily injury or severe 
//_/_/    emotional harm to any person; (ii) invading the personal privacy or 
//_/_/    violating the human rights of any person; or (iii) committing or 
//_/_/    preparing for any act of war. 
//_/_/
//_/_/  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//_/_/  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//_/_/  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
//_/_/  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
//_/_/  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
//_/_/  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
//_/_/  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
//_/_/  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
//_/_/  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
//_/_/  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
//_/_/  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
/*! @file VantagePoints.h
    @brief Management of a fixed set of spatial "perch" points that entities can reserve, occupy and free.

    A VantagePoints collection is defined in PsySpec XML and models discrete
    observation positions (e.g. camera vantage points or avatar perches).
    Each PerchPoint carries overlap weights against the other points so a
    controller can pick maximally distinct viewpoints. */
#if !defined(_VANTAGEPOINTS_H_)
#define _VANTAGEPOINTS_H_

#include "MathClasses.h"
#include "Utils.h"
#include "xml_parser.h"

namespace cmlabs {

/*! @brief Lifecycle of a perch point: FREE, RESERVED (claimed, not yet reached), OCCUPIED, LEAVING (being vacated). */
enum PerchState { FREE = 0, RESERVED = 1, OCCUPIED = 2, LEAVING = 3 };
/*! @brief State of the whole vantage system: IDLE, INMOTION (reconfiguring) or SETTLED. */
enum VantageState { IDLE = 0, INMOTION = 1, SETTLED = 2 };

/*! @brief One perch: id, occupancy state, occupying entity, last-visit time, label, opaque data and overlap weights against other perches. */
struct PerchPoint {
	uint32 id;
	PerchState state;
	uint32 entityID;
	uint64 lastVisit;
	std::string label;
	std::string data;
	std::vector<double> overlaps;
};

/*! @brief Registry of perch points parsed from PsySpec XML, with reserve/occupy/free bookkeeping. */
class VantagePoints {
public:
	VantagePoints();
	~VantagePoints();

	/*! @brief Parse the configuration from XML text. @param xml PsySpec XML. @return true on success. */
	bool init(const char* xml);
	/*! @brief Parse the configuration from an already-parsed XML node. @param node Configuration node. @return true on success. */
	bool init(XMLNode node);
	/*! @brief Reserve the best available (least-overlapping free) point for an entity. @param entityID Claiming entity. @return Point id, or 0 when none is free. */
	uint32 reserveNextPoint(uint32 entityID);
	/*! @brief Mark a reserved point as occupied. @param id Point id. @param entityID Must match the reserving entity. @return true on success. */
	bool occupyPoint(uint32 id, uint32 entityID);
	/*! @brief Release a point held by @p entityID. @param id Point id. @param entityID Holder. @return true on success. */
	bool freePoint(uint32 id, uint32 entityID);

	/*! @brief Opaque data string attached to a point in the XML. @param id Point id. @return Data text, or NULL for an unknown id. */
	const char* getPointData(uint32 id);
	/*! @brief Label of a point. @param id Point id. @return Label text, or NULL for an unknown id. */
	const char* getPointLabel(uint32 id);

	/*! @brief Self test. @return true when all checks pass. */
	static bool UnitTest();

	uint32 count;       //!< Number of perch points.
	VantageState state; //!< Current system state.

private:
	std::map<uint32, PerchPoint> points;
	uint32* inUseMap;
	uint64 intrinsicTimescaleMS;
	int32 timeoutMS;
	uint64 motionStartedTime;
};

} // namespace cmlabs

#endif //_VANTAGEPOINTS_H_

