#!/usr/bin/env python
# -------------------------------------------------------------------------------
# Name:     btrack
# Purpose:  A multi object tracking library, specifically used to reconstruct
#           tracks in crowded fields. Here we use a probabilistic network of
#           information to perform the trajectory linking. This method uses
#           positional and visual information for track linking.
#
# Authors:  Alan R. Lowe (arl) a.lowe@ucl.ac.uk
#
# License:  See LICENSE.md
#
# Created:  14/08/2014
# -------------------------------------------------------------------------------

__author__ = "Alan R. Lowe"
__email__ = "a.lowe@ucl.ac.uk"


import ctypes

from btrack import constants

H_TYPES = [
    "P_FP",
    "P_init",
    "P_term",
    "P_link",
    "P_branch",
    "P_dead",
    "P_merge",
]


class Hypothesis(ctypes.Structure):
    """Hypothesis structure.

    This is essentially a replicate of the C-structure used by the hypothesis
    engine. Added a few extra functions to enable quick assignment.

    unsigned int hypothesis;
    unsigned int ID;
    double probability;
    unsigned int link_ID;
    unsigned int child_one_ID;
    unsigned int child_two_ID;

    Notes:
      These are automatically generated by the optimiser
    """

    _fields_ = [
        ("hypothesis", ctypes.c_uint),
        ("ID", ctypes.c_uint),
        ("probability", ctypes.c_double),
        ("link_ID", ctypes.c_uint),
        ("child_one_ID", ctypes.c_uint),
        ("child_two_ID", ctypes.c_uint),
        ("parent_one_ID", ctypes.c_uint),
        ("parent_two_ID", ctypes.c_uint),
    ]

    @property
    def hypothesis_type(self):
        return constants.Fates(self.hypothesis)

    @property
    def log_likelihood(self):
        return self.probability


class PyHypothesisParams(ctypes.Structure):
    """HypothesisParams.

    A convenient way to send hypothesis generation parameters to the hypothesis
    engine.

      double lambda_time;   // lambda_1
      double lambda_dist;   // lambda_2
      double lambda_link;   // lambda_3
      double lambda_branch; // lambda_4
      double eta;           // default low probability
      double theta_dist;
      double theta_time;
      double dist_thresh;
      double time_thresh;
      unsigned int apop_thresh;
      double segmentation_miss_rate;
      double apoptosis_rate;
      bool relax;

    Notes:
        None

    """

    _fields_ = [
        ("lambda_time", ctypes.c_double),
        ("lambda_dist", ctypes.c_double),
        ("lambda_link", ctypes.c_double),
        ("lambda_branch", ctypes.c_double),
        ("eta", ctypes.c_double),
        ("theta_dist", ctypes.c_double),
        ("theta_time", ctypes.c_double),
        ("dist_thresh", ctypes.c_double),
        ("time_thresh", ctypes.c_double),
        ("apop_thresh", ctypes.c_uint),
        ("segmentation_miss_rate", ctypes.c_double),
        ("apoptosis_rate", ctypes.c_double),
        ("relax", ctypes.c_bool),
        ("hypotheses_to_generate", ctypes.c_uint),
    ]
