/************************************************************
   Copyright (C) 1993 by The Trustees of Columbia University in the City 
   of New York

   OBJECT-ORIENTED Protein Data Bank Project
   Biochemistry and Molecular Biophysics, Computer Science depts.
 **************************************************************

   File: i_subentity.h
   Responsable: Weider Chang, Ph.D

 **************************************************************/
#ifndef _H_CORESUBENTITY
#define _H_CORESUBENTITY

#include "oopdb_setup.h"


enum SubEntityType {NC_NUCLEOTIDE, C_NUCLEOTIDE, NC_AA_RESIDUE,
		      C_AA_RESIDUE, SACCHARIDE, HET_MONOMER, 
		      HET_ENTITY, NULL_SUBENTITY_TYPE};

class SubEntityConnectivity;

class IntrSubEntity {
  friend class IntrPdbFile;
  friend class IntrCompound;
  friend class IntrSecondaryStruc;
  friend class IntrEntity;
  friend class IntrAtom;
  friend class SubEntityIter;
  friend class AtomIter;
  
 protected:
  
  IntrSubEntity();
  IntrSubEntity(char*);
  ~IntrSubEntity();
  
  Atom *d_atom_p;
  Atom *atom_to_previous, * atom_to_next;
  Entity *entity_p;
  SecondaryStruc *d_secondary_p;
  SubEntity *next_p;
  SubEntity *previous_p;
  SubEntityConnectivity *connectivity;
  Atom * nth_atom(int);
  Atom * last_atom();
  Bound_atom * bound_atoms(const Atom*) const;
  int last_atom_no();
  int assign_connectivity();
  SubEntityConnectivity * find_alt_connectivity(char*);
  SubEntity * insert_subentity_after(SubEntity*);
  void build_atoms();
  void add_term_ox();
  void assign_next(SubEntity *subentity){next_p=subentity;}
  void assign_previous(SubEntity *subentity){previous_p=subentity;}
  void add_atom(Atom &atom);
  void assign_secondary( SecondaryStruc* secondary_p);
  void assign_all_connectivity();
  void assign_atoms_to_pre_next();
  void build_alt_connectivity(char*);
  
 public:
  char d_name[4];
  int d_seq_no;
  char d_insert_code[2];
  Atom * atom_to_previous_subentity() const {return atom_to_previous;};
  Atom * atom_to_next_subentity() const {return atom_to_next;};
  Atom * find_atom(char*);
  const Entity* myEntity() const{ return entity_p; }
  const SecondaryStruc* mySecondaryStruc() const { return d_secondary_p;}
  const Compound* myCompound() const;
  double dihedral_angle();
  int is_missing_subentity() const {return(d_seq_no==ILEGAL_NUMBER);}
  int num_atoms();
  SubEntity * previous_subentity() const {return previous_p;};
  SubEntity * next_subentity() const { return next_p;}
  SubEntityType myType();
  virtual Atom * N_atom() const {return NULL;}
  virtual Atom * CA_atom() const {return NULL;}
  virtual Atom * C_atom() const {return NULL;}
  virtual double phi_angle(int =0) const {return ILEGAL_NUMBER;}
  virtual double psi_angle(int =0) const {return ILEGAL_NUMBER;}
  virtual double delta_omega(int =0) const {return ILEGAL_NUMBER;}
  virtual double omega_angle(int =0) const {return ILEGAL_NUMBER;}

};


#endif







