/*
 * This file is part of the Owl Positioning System (OwlPS) project.
 * It is subject to the copyright notice and license terms in the
 * COPYRIGHT.t2t file found in the top-level directory of this
 * distribution and at
 *   https://code.lm7.fr/mcy/owlps/src/master/COPYRIGHT.t2t
 * No part of the OwlPS Project, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms
 * contained in the COPYRIGHT.t2t file; the COPYRIGHT.t2t file must be
 * distributed along with this file, either separately or by replacing
 * this notice by the COPYRIGHT.t2t file's contents.
 */


#ifndef _OWLPS_POSITIONING_RESULT_HH_
#define _OWLPS_POSITIONING_RESULT_HH_

class Request ;

#include "point3d.hh"

#include <string>

/// Represents a result computed by a positioning algorithm
class Result
{
protected:
  /// Request sent by the mobile
  const Request *request ;
  /// Algorithm used to compute the position
  std::string algorithm ;
  /// Computed coordinates of the mobile
  Point3D position ;
  /// Distance error between the real coordinates and the computed point
  /** The error is set to -1 if the real coordinates are unknown. */
  float error ;

public:
  Result(const Request *const _request = nullptr,
         const std::string &_algorithm = "UnknownAlgorithm"):
    request(_request), algorithm(_algorithm), error(-1) {}
  Result(const Request *const _request, const std::string &_algorithm,
         const Point3D &_position):
    request(_request), algorithm(_algorithm), position(_position),
    error(-1) {}
  Result(const Request *const _request, const std::string &_algorithm,
         const Point3D &_position, const Point3D &real_position) ;
  ~Result(void) {}

  /** @name Read accessors */
  //@{
  const Request* get_request(void) const ;
  const std::string& get_algorithm(void) const ;
  const Point3D& get_position(void) const ;
  float get_error(void) const ;
  std::string in_which_area(void) const ;
  //@}

  /** @name Write accessors */
  //@{
  /// Sets the position
  void set_position(const Point3D &_position) ;
  /// Computes the distance between #position and `real_position`
  void compute_error(const Point3D &real_position) ;
  //@}

  /** @name Operators */
  //@{
  Result& operator=(const Result &source) ;
  bool operator==(const Result &source) const ;
  bool operator!=(const Result &source) const ;
  //@}

  /** @name Conversion accessors */
  //@{
  /// Converts to a CSV string
  const std::string to_csv(void) const ;
  //@}

  /// Displays a Result
  friend std::ostream& operator<<(std::ostream &os, const Result &r) ;
} ;



/* *** Read accessors *** */


inline const Request* Result::get_request() const
{
  return request ;
}


inline const std::string& Result::get_algorithm() const
{
  return algorithm ;
}


inline const Point3D& Result::get_position() const
{
  return position ;
}


inline float Result::get_error() const
{
  return error ;
}



/* *** Write accessors *** */


inline void Result::set_position(const Point3D &_position)
{
  position = _position ;
}



/* *** Operators *** */


inline bool Result::operator!=(const Result &source) const
{
  return !(*this == source) ;
}



#endif // _OWLPS_POSITIONING_RESULT_HH_
