/*******************************************************************************
*
*       This file is part of the General Hidden Markov Model Library,
*       GHMM version __VERSION__, see http://ghmm.org
*
*       Filename: ghmm/ghmmwrapper/pclasschange.c
*       Authors:  Matthias Heinig, Janne Grunau
*
*       Copyright (C) 1998-2004 Alexander Schliep
*       Copyright (C) 1998-2001 ZAIK/ZPR, Universitaet zu Koeln
*       Copyright (C) 2002-2004 Max-Planck-Institut fuer Molekulare Genetik,
*                               Berlin
*
*       Contact: schliep@ghmm.org
*
*       This library is free software; you can redistribute it and/or
*       modify it under the terms of the GNU Library General Public
*       License as published by the Free Software Foundation; either
*       version 2 of the License, or (at your option) any later version.
*
*       This library 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
*       Library General Public License for more details.
*
*       You should have received a copy of the GNU Library General Public
*       License along with this library; if not, write to the Free
*       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*       This file is version $Revision: 1713 $
*                       from $Date: 2006-10-16 10:06:28 -0400 (Mon, 16 Oct 2006) $
*             last change by $Author: grunau $.
*
*******************************************************************************/

/* XXX FIXME: breaks out of tree build of ghmmwrapper */
#include "../config.h"

#include <stdlib.h>

#include "pclasschange.h"

/* classification functions for the pairhmm genefinder 
   transition class 0 is the default class */

/* if the sum of the ka values is less than the threshold return 1 */
int lt_sum(ghmm_dpmodel * mo, ghmm_dpseq * X, ghmm_dpseq * Y, int index_x, int index_y, void * user_data) {
  /* cast the user data */
  threshold_user_data * td = (threshold_user_data *)user_data;
  if (ghmm_dpseq_get_double (X, td->seq_index, index_x + td->offset_x) + 
      ghmm_dpseq_get_double (Y, td->seq_index, index_y + td->offset_y) < 
      td->threshold)
    return 1;
  else
    return 0;
}

/* if the sum of the ka values is greater than the threshold return 1 */
int gt_sum(ghmm_dpmodel * mo, ghmm_dpseq * X, ghmm_dpseq * Y, int index_x, int index_y, void * user_data) {
  /* cast the user data */
  threshold_user_data * td = (threshold_user_data *)user_data;
  if (ghmm_dpseq_get_double (X, td->seq_index, index_x + td->offset_x) + 
      ghmm_dpseq_get_double (Y, td->seq_index, index_y + td->offset_y) >
      td->threshold)
    return 1;
  else
    return 0;
}

/* reads int sequences of boolean precomputed classification. If both positions
   are true return true else false */
int boolean_and(ghmm_dpmodel * mo, ghmm_dpseq * X, ghmm_dpseq * Y, int index_x, int index_y, void * user_data) {
  boolean_user_data * td = (boolean_user_data *)user_data;
  if (ghmm_dpseq_get_char (X, td->seq_index, index_x + td->offset_x) && 
      ghmm_dpseq_get_char (Y, td->seq_index, index_y + td->offset_y))
    return 1;
  else
    return 0;
}

/* reads int sequences of boolean precomputed classification. If one position
   is true return true else false */
int boolean_or(ghmm_dpmodel * mo, ghmm_dpseq * X, ghmm_dpseq * Y, int index_x, int index_y, void * user_data) {
  boolean_user_data * td = (boolean_user_data *)user_data;
  if (ghmm_dpseq_get_char (X, td->seq_index, index_x + td->offset_x) ||
      ghmm_dpseq_get_char (Y, td->seq_index, index_y + td->offset_y))
    return 1;
  else
    return 0;
}

void set_to_lt_sum(ghmm_dpmodel_class_change_context * pccc, int seq_index, double threshold, int offset_x, int offset_y) {
  if (pccc) {
    threshold_user_data * td;
    td = calloc (1, sizeof (td));
    td->seq_index = seq_index;
    td->threshold = threshold;
    td->offset_x = offset_x;
    td->offset_y = offset_y;
    pccc->user_data = td;
    pccc->get_class = &lt_sum;
  }
  else
    fprintf(stderr, "set_to_lt_sum_ka: No class change context\n");
}

void set_to_gt_sum(ghmm_dpmodel_class_change_context * pccc, int seq_index, double threshold, int offset_x, int offset_y) {
  if (pccc){
    threshold_user_data * td;
    td = calloc (1, sizeof (td));
    td->seq_index = seq_index;
    td->threshold = threshold;
    td->offset_x = offset_x;
    td->offset_y = offset_y;
    pccc->user_data = td;
    pccc->get_class = &gt_sum;
  }
  else
    fprintf(stderr, "set_to_gt_sum_deltaka: No class change context\n");
}

void set_to_boolean_and(ghmm_dpmodel_class_change_context * pccc, int seq_index, int offset_x, int offset_y) {
  if (pccc){
    boolean_user_data * td;
    td = calloc (1, sizeof (td));
    td->seq_index = seq_index;
    td->offset_x = offset_x;
    td->offset_y = offset_y;
    pccc->user_data = td;
    pccc->get_class = &boolean_and;
  }
  else
    fprintf(stderr, "set_to_boolean_and: No class change context\n");
}

void set_to_boolean_or(ghmm_dpmodel_class_change_context * pccc, int seq_index, int offset_x, int offset_y) {
  if (pccc){
    boolean_user_data * td;
    td = calloc (1, sizeof (td));
    td->seq_index = seq_index;
    td->offset_x = offset_x;
    td->offset_y = offset_y;
    pccc->user_data = td;
    pccc->get_class = &boolean_or;
  }
  else
    fprintf(stderr, "set_to_boolean_and: No class change context\n");
}

