#ifndef PDB_FILE_H
#define PDB_FILE_H

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

#ifndef INPUT_H
#include "Input.h"
#endif

#ifndef ARRAY_H
#include "Array.h"
#endif

#ifndef TEXT_H
#include "Text.h"
#endif

namespace MM
{

class Pdb_file : public Model_file
{
//    typedef void  (*PF) (std::istream&);
//    std::map <Text, PF> input_map_;

    struct Joint_numbers 
    {
        Text        type_;
        int         first_, second_, third_;
        Array <int> atoms_;

        Joint_numbers (const Text &type, int first, int second, int third) 
            : type_(type), first_(first), second_(second), third_(third) { }
    public:
};
    Array <Joint_numbers> joint_numbers_;

    static Pdb_file     prototype_;

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

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

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


private:
/*  void read_residue( const char[], Input & );
    void read_chain(   const char[], Input &  );
    void read_model(   const char[], Input &  );
//*/

    enum Result {end_of_file, end_of_model, end_of_chain, end_of_residue, error};

    void    read_atom        (char line[], int & resudue_serial_number);
    Result  read_residue     (char first_word[], char line[], Input &);
    Result  read_chain       (char first_word[], char line[], Input &);//    void screamer  (  std::istream & );
    Result  read_model       (char first_word[], char line[], Input &);

    bool    find_residue_line(char first_word[], char line[], Input &);
    bool    find_chain_line  (char first_word[], char line[], Input &);
    bool    find_model_line  (char first_word[], char line[], Input &);
    
    int     get_element_N (char const word[]);
    Element get_element (char const word[]);
};

/**
 **************
 *	формат PDB файла
 *COLUMNS        DATA TYPE       FIELD
 *         DEFINITION
 *---------------------------------------------------------------------------------
 * 1 -  6        Record name     "ATOM
 *  "
 *
 * 7 - 11        Integer         serial        Atom serial
 * number.
 *
 *13 - 16        Atom            name          Atom
 * name.
 *
 *17             Character       altLoc        Alternate location
 * indicator.
 *
 *18 - 20        Residue name    resName       Residue
 * name.
 *
 *22             Character       chainID       Chain
 * identifier.
 *
 *23 - 26        Integer         resSeq        Residue sequence
 * number.
 *
 *27             AChar           iCode         Code for insertion of
 * residues.
 *
 *31 - 38        Real(8.3)       x             Orthogonal coordinates
 * for X in
 *                                             Angstroms.
 *
 *39 - 46        Real(8.3)       y             Orthogonal coordinates
 * for Y in
 *                                             Angstroms.
 *
 *47 - 54        Real(8.3)       z             Orthogonal coordinates
 * for Z in
 *                                             Angstroms.
 *
 *55 - 60        Real(6.2)       occupancy
 *     Occupancy.
 *
 *61 - 66        Real(6.2)       tempFactor    Temperature
 * factor.
 *
 *73 - 76        LString(4)      segID         Segment identifier,
 * left-justified.
 *
 *77 - 78        LString(2)      element       Element symbol,
 * right-justified.
 *
 *79 - 80        LString(2)      charge        Charge on the atom.
 */

}//MM

#endif //PDB_FILE_H
