#ifndef CLASSIFIER_H
#define CLASSIFIER_H

#include "freesasa_internal.h"

/**
    This classifier only has the sasa_class() and class2str()
    functions, which returns 1 for protein backbone atoms, and 0
    else. Backbone atoms are CA, N, C and O.
 */
extern const freesasa_classifier freesasa_backbone_classifier;

/** Classifier that classifies each atom according to residue */
extern const freesasa_classifier freesasa_residue_classifier;

/**
    The following three structs and the following functions are only
    exposed in a header because the autogenerated static classifiers
    need to see them, they are not intended for use outside of this
    context. Therefore the functions to modify the structs are hidden
    inside classifier.c.

    Names of classes, types, etc are stored in arrays to simplify
    generic searching.
*/

/**
    Struct to store information about the types-section in a user-config.
 */
struct classifier_types {
    int n_types;                     /**< number of types */
    char **name;                     /**< names of types */
    double *type_radius;             /**< radius of type */
    freesasa_atom_class *type_class; /**< class of each type */
};

/**
     Configuration info for each residue type.
 */
struct classifier_residue {
    int n_atoms;                     /**< Number of atoms */
    char *name;                      /**< Name of residue */
    char **atom_name;                /**< Names of atoms */
    double *atom_radius;             /**< Atomic radii */
    freesasa_atom_class *atom_class; /**< Classes of atoms */
    freesasa_nodearea max_area;      /**< Maximum area (for RSA) */
};

/**
    Stores a user-configuration as extracted from a configuration
    file. No info about types, since those are only a tool used
    intermediately in assigment of radii and classes.

    An array of the names of residues is stored directly in the struct
    to facilitate searching for residues. The class_name array should
    be a clone of that found in struct types (can be done bye
    config_copy_classes()).

    Only for internal use.
 */
struct freesasa_classifier {
    int n_residues;      /**< Number of residues */
    char **residue_name; /**< Names of residues */
    char *name;
    struct classifier_residue **residue;
};

/**
    Get the VdW radius of an element
 */
double
freesasa_guess_radius(const char *symbol);

const freesasa_nodearea *
freesasa_classifier_residue_reference(const freesasa_classifier *classifier,
                                      const char *res_name);

/* The functions below are only exposed to allow testing */
freesasa_classifier *
freesasa_classifier_new(void);

struct classifier_types *
freesasa_classifier_types_new(void);

void freesasa_classifier_types_free(struct classifier_types *t);

struct classifier_residue *
freesasa_classifier_residue_new(const char *name);

void freesasa_classifier_residue_free(struct classifier_residue *res);

int freesasa_classifier_add_residue(struct freesasa_classifier *c,
                                    const char *name);

int freesasa_classifier_add_atom(struct classifier_residue *res,
                                 const char *name,
                                 double radius,
                                 int the_class);

int freesasa_classifier_add_type(struct classifier_types *types,
                                 const char *type_name,
                                 const char *class_name,
                                 double r);

int freesasa_classifier_add_class(struct classifier_types *types,
                                  const char *name);

/* These three are used to calculate residue type areas */

int freesasa_classify_n_residue_types(void);

int freesasa_classify_residue(const char *res_name);

const char *
freesasa_classify_residue_name(int residue_type);

#endif /* CLASSIFIER_H */
