/*
 *   ORXONOX - the hottest 3D action shooter ever to exist
 *                    > www.orxonox.net <
 *
 *
 *   License notice:
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation; either version 2
 *   of the License, or (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 *   Author:
 *      Gani Aliguzhinov
 *   Co-authors:
 *      ...
 *
 */

#ifndef _Actionpoint_H__
#define _Actionpoint_H__

#include <string>                           //need string for XML input

#include "core/XMLPort.h"                   //need XMLPort
#include "worldentities/StaticEntity.h"     //this is a child of StaticEntity

namespace orxonox
{ 
    /**
    @brief
        Actionpoints are used by ActionpointController and all derived classes.
        Such classes will execute actions set in Actionpoints.

        In XML file one can pass an array of Actionpoints to a controller. Each
        Actionpoint can take action type, string and boolean or 
        action and two booleans as an argument.
        If action is set to fly, Actionpoint's position is assumed to be the desired
        location.
        Example XML code:

        @code
        <SpaceShip position="-2000, 1500, -1000" lookat="0,0,0" team=0 name="thisShipName">
          <templates>
            <Template link=spaceshipassff />
          </templates>
          <controller>
            <DivisionController team=0 formationMode="WALL">
              <actionpoints>
                <Actionpoint position="0,0,0" action="FLY" /> 
                <Actionpoint position="-1000,750,-500" action="ATTACK" attack="someShipName" />
                <Actionpoint position="-1000,750,-500" action="PROTECT" protectMe=true />
                <Actionpoint position="-1000,750,-500" action="PROTECT" protect="otherShipName" /> 
                <Actionpoint position="-1000,750,-500" action="FIGHTALL" />
               </actionpoints>
            </DivisionController>
          </controller>
        </SpaceShip>
        @endcode

        Example with loops:

        @code
        <SpaceShip position="-1500, 1500, -1000" lookat="0,0,0" team=0 name="thisShipName">
          <templates>
            <Template link=spaceshipassff />
          </templates>
          <controller>
            <DivisionController team=0 formationMode="finger4">
              <actionpoints>
                <Actionpoint position="  0,2000,-600" action="FLY" loopStart=true/>
                <Actionpoint position="  0,2000,-700" action="FLY"  />
                <Actionpoint position="100,2000,-700" action="FLY" />
                <Actionpoint position="100,2000,-600" action="FLY" loopEnd=true />
              </actionpoints>
            </DivisionController>
          </controller>
        </SpaceShip>
        @endcode
        
        One can also use other Worldentities instead of Actionpoints just like Waypoints, but those points
        will be included in loop.
        For more information read descriptions of the methods.
    */
    class _OrxonoxExport Actionpoint : public StaticEntity
    {
        public:
            Actionpoint(Context* context);
            virtual ~Actionpoint() = default;

            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode) override;

            /** @brief Decides what AI will do. @param val action to execute */
            void setActionXML(std::string val)
                { this->actionName_ = getUppercase (val); }
            std::string getActionXML() const
                { return this->actionName_; }

            /** @brief Makes AI follow an entity. @param val name of entity to protect */
            void setProtectXML(std::string val)
                { this->name_ = val; }
            std::string getProtectXML() const
                { return this->name_; }

            /** @brief Makes AI attack an entity. @param val name of entity to attack */
            void setAttackXML(std::string val)
                { this->name_ = val; }
            std::string getAttackXML() const
                { return this->name_; }

            /** @brief Makes AI follow human player. @param c protect Human? */
            void setProtectMeXML(bool c)
                { this->bProtectMe_ = c; }
            bool getProtectMeXML() const
                { return this->bProtectMe_; }

            /** @brief Starts a loop of Actionpoints. @param value start loop? */
            void setLoopStart(bool value)
                { this->bLoopStart_ = value; }
            bool getLoopStart() const
                { return this->bLoopStart_; }
            /** @brief Ends a loop of Actionpoints. @param value end loop? */
            void setLoopEnd (bool value)
                { this->bLoopEnd_ = value; }
            bool getLoopEnd() const
                { return this->bLoopEnd_; }

            std::string getName() const;

        private:    
            std::string actionName_;    //!< can be set to "FLY", "ATTACK",
                                        //!< "PROTECT", "FIGHT", "FIGHTALL"
                                        //!< or "NONE".

            std::string name_;          //!< name of the ship that is to be
                                        //!< attacked or protected.

            bool bLoopStart_;           //!< if true, this and all following Actionpoints
                                        //!< until the first Actionpoint with bLoopEnd_
                                        //!< set to true are executed in a loop.

            bool bLoopEnd_;             //!< if true, this is the last element of
                                        //!< a loop started by loopStart=true argument

            bool bProtectMe_;           //!< if player is to be protected,
                                        //!< instead of passing name, one has
                                        //!< to set protectMe to true.
    };
}

#endif /* _Actionpoint_H__ */
