#ifndef MOL2_FILE_H
#define MOL2_FILE_H

#ifndef MODEL_FILE_H
#include "Model_file.h"
#endif

#ifndef ELEMENT_H
#include "Element.h"
#endif

#include <iosfwd>
#include <string>
#include <vector>

namespace MM
{
class Mol2_file : public Model_file
{
    int         line_counter_;
    int         section_data_line_counter_;
    void        (Mol2_file::*read_data_line_function_)(std::string & line);

    static Mol2_file    prototype_;

public:
    explicit            Mol2_file (Prototype const &);
    explicit            Mol2_file (Model & model);
    virtual Model_file *clone (Model & model) const;

    virtual bool        support_input     () const {return true;}
    virtual bool        support_output    () const {return false;}
    virtual bool        support_bonds     () const {return true;}
    virtual bool        support_molecules () const {return false;}

    virtual Text const &type_name () const {static Text t("SYBYL mol2"); return t;}
    virtual void        save            (bool to_comment);
    virtual void        check_file_name ();
    virtual void        add             (Text const & file_name);


    struct SYBYL_atom_type
    {
        Element         element_; 
        std::string     n_;  
        std::string     code_;
        std::string     definition_;

        SYBYL_atom_type (const Element     & element, 
                         const std::string & n, 
                         const std::string & code, 
                         const std::string & definition)
        : 
            element_(element), n_(n), code_(code), definition_(definition) { }
    };

    static std::vector <SYBYL_atom_type> &      
                    atom_types ();

    bool            is_not_a_SYBYL (const std::string & atom_type, 
                                    Element & element) const;

private:
    bool            next_line         (std::ifstream & in, std::string & line);
    void            detect_record_type(                    std::string & line);
    void            read_data_line    (std::ifstream & in, std::string & line);

    void            read_ALT_TYPE               (std::string & line);
    void            read_ANCHOR_ATOM            (std::string & line);
    void            read_ASSOCIATED_ANNOTATION  (std::string & line);
    void            read_ATOM                   (std::string & line);
    void            read_BOND                   (std::string & line);
    void            read_CENTER_OF_MASS         (std::string & line);
    void            read_CENTROID               (std::string & line);
    void            read_COMMENT                (std::string & line);
    void            read_CRYSIN                 (std::string & line);
    void            read_DICT                   (std::string & line);
    void            read_DATA_FILE              (std::string & line);
    void            read_EXTENSION_POINT        (std::string & line);
    void            read_FF_PBC                 (std::string & line);
    void            read_FFCON_ANGLE            (std::string & line);
    void            read_FFCON_DIST             (std::string & line);
    void            read_FFCON_MULTI            (std::string & line);
    void            read_FFCON_RANGE            (std::string & line);
    void            read_FFCON_TORSION          (std::string & line);
    void            read_LINE                   (std::string & line);
    void            read_LSPLANE                (std::string & line);
    void            read_MOLECULE               (std::string & line);
    void            read_NORMAL                 (std::string & line);
    void            read_QSAR_ALIGN_RULE        (std::string & line);
    void            read_RING_CLOSURE           (std::string & line);
    void            read_ROTATABLE_BOND         (std::string & line);
    void            read_SEARCH_DIST            (std::string & line);
    void            read_SEARCH_OPTIONS         (std::string & line);
    void            read_SET                    (std::string & line);
    void            read_SUBSTRUCTURE           (std::string & line);
    void            read_U_FEAT                 (std::string & line);
    void            read_UNITY_ATOM_ATTR        (std::string & line);
    void            read_UNITY_BOND_ATTR        (std::string & line);
};

}//MM

#endif //MOL2_FILE_H
