/*
 * Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
 *
 * This file is part of PeerfactSim.KOM.
 * 
 * PeerfactSim.KOM 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 3 of the License, or
 * any later version.
 * 
 * PeerfactSim.KOM 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 PeerfactSim.KOM.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package de.tud.kom.p2psim.api.uav;


import de.tud.kom.p2psim.impl.energy.components.ActuatorComponent;

/**
 * Interface for thrust/acceleration-based UAV models. Multicopter!
 * 
 * @author Julian Zobel
 * @version 1.0, 19.01.2022
 */
public interface MulticopterModel {
	// NO - NO CHANGY
	public final double AIRDENSITY = 1.2045; // kg/m^3
	public final double GRAVITY = 9.807; // m/s^2
	
	/**
	 * Query if the multicopter's motors are active and usable.
	 * 
	 * @return
	 */
	public boolean isOn();
	
	/**
	 * Maximum provided thrust by the multicopter motors (full throttle, maximum rotation).
	 * 
	 * @return
	 */
	public double maxThrust();
	
	/**
	 * Minimum provided thrust by the multicopter motors (idle, minimum rotation)
	 * 
	 * @return
	 */
	public double minThrust();
	
	/**
	 * Thrust requires to hold the multicopter on a stable level in the air.
	 * 
	 * @return
	 */
	public double hoverThrust();
	
	/**
	 * Thrust required for a certain horizontal velocity. Includes vertical thrust component.
	 * 
	 * @param velocity
	 * @return
	 */
	public double thrustForHorizontalVelocity(double velocity);
	
	/**
	 * Thrust required for the maximum possible horizontal velocity. Includes vertical
	 * thrust component. 
	 * 
	 * @return
	 */
	public double thrustForHorizontalMaxVelocity();
		
	/**
	 * Thrust required for a controlled vertical descent.
	 * 
	 * @param velocity
	 * @return
	 */
	public double verticalDescentThrust(double velocity);
	
	/**
	 * Thrust required for vertical ascent.
	 * 
	 * @param velocity
	 * @return
	 */
	public double verticalAscentThrust(double velocity);
		
	/**
	 * Optimal horizontal speed of the multicopter w.r.t. energy consumption.
	 * @return
	 */
	public double optimalSpeed();
	
	/**
	 * Maximum horizontal velocity. 
	 * @return
	 */
	public double horizontalMaxVelocity();	
	
	/**
	 * Minimum horizontal velocity. 
	 * @return
	 */
	public double horizontalMinVelocity();
	
	/**
	 * Maximum velocity for vertical ascent.
	 * @return
	 */
	public double verticalAscentMaxVelocity();
	
	/**
	 * Maximum velocity for vertical descent.
	 * @return
	 */
	public double verticalDescentMaxVelocity();
	
	/**
	 * Optimal velocity when flying a curve.
	 * @return
	 */
	public double curveVelocity();
	
	/**
	 * Maximum acceleration for horizontal flight.
	 * @return
	 */
	public double horizontalMaxAcceleration();
	
	/**
	 * Maximum deceleration in horizontal flight.
	 * @return
	 */
	public double horizontalMaxDeceleration();
	
	/**
	 * Maximum acceleration for vertical descent.
	 * @return
	 */
	public double verticalDescentMaxAcceleration();
	
	/**
	 * Maximum acceleration for vertical ascent.
	 * @return
	 */
	public double verticalAscentMaxAcceleration();
		
	/**
	 * Maximum turn angle (rad per second), that the multicopter can change its facing while hovering.
	 * @return
	 */
	public double getMaximumTurnAngle();
	
	/**
	 * The radius of the curve/circle the multicopter can fly with a given velocity.
	 * @param curveVelocity
	 * @return
	 */
	public double getCurveRadius(double curveVelocity);
	
	/**
	 * The acceleration, the multicopter is subject to when flying a curve/in a circle with a given velocity.
	 * @param curveVelocity
	 * @return
	 */
	public double getCurveCentripedalAcceleration(double curveVelocity);
	
	/**
	 * Pitch angle (Angle of attack) required to achieve a given velocity.
	 * @param velocity
	 * @return
	 */
	public double pitchAngleForHorizontalVelocity(double velocity);

	/**
	 * Power consumption in watt, when flying a given velocity.
	 * @param velocity
	 * @return
	 */
	public double powerConsumptionWatt(double velocity);

	/**
	 * Sets the actuator of the multicopter.
	 * @param motor
	 */
	public void setMotor(ActuatorComponent motor);
	
	/**
	 * Puts load on the multicopter's motors for a given phase time, such that the
	 * given thrust is provided within that time.
	 *  
	 * @param thrust
	 * @param phaseTime
	 */
	public void thrust(double thrust, long phaseTime);
	
	/**
	 * Hacky factory interface for multicopter model factories.
	 * 	
	 * @author Julian Zobel
	 * @version 1.0, 20.01.2022
	 */
	public interface Factory {
		public MulticopterModel createComponent();
	}
}
