// $Header: /u/boat/pdb/Src/Include/RCS/cstrucutre, v 1 1993/01/07 01:56:26 Weider $
  /*******************************************
	cstructure.h

	This is the abstrct interface of protein definition
	including protein structure defination, iterators, and filters
	for protein, entity, secondary structures, subentitys, and atom

	$Log: protein.h,v $

	* Revision 2 1992/11/5 Weider

	* Revision 1.4  1992/10/03  01:56:26  karthik
	* This is new protein class definition, modified by Weider.
	*
	* Revision 1.2  1992/10/02  01:13:36  karthik
	* This is a general update, made before weider@cs's changes are added.
	* Modifications to previous version include -DMOTIF compiler option
	* support.
	*

   $Author: karthik $


***********************************************************************/

/************************************************************
   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_structure.h
   Responsable: Weider Chang, Ph.D

 **************************************************************/

#ifndef _H_COREATOM
#define _H_COREATOM

#include "oopdb_setup.h"


#define ILEGAL_NUMBER -9999

class Atom;

#define NAME_OXT ("OXT")
#define NAME_SG  ("SG")
#define MISS_SUBE ("?")

class SubEntity;
class Entity;
class SecondaryStruc;
class Compound;
class PDB_Info;
class LineBuffer;
class Site;
class ConnectivitySet;

#include "bonds.h"

#ifndef _H_BOND_ATOM
#define _H_BOND_ATOM

struct Bound_atom;

typedef struct List_of_atoms {
  Atom * bound_atom;
  List_of_atoms * next;
};


class SubEntityList {
 public:
  SubEntity * subentity_p;
  SubEntityList * next_p;
};

#endif

#ifndef _H_HISTOGRAMVALUES
#define _H_HISTOGRAMVALUES

typedef struct HistogramValues {
  double value;
  SubEntity * subentity_p;
  HistogramValues * next_p;
};

#endif

class IntrAtom {

  friend class IntrPdbFile;
  friend class IntrSubEntity;
  friend class IntrCAAResidue;
  friend class AtomIter;

 protected:
  IntrAtom();
  Atom * alt_p;
  Atom * next_p; 
  Atom * previous_p;
  SubEntity * subentity_p;
  int num_alt_position;
  char d_alt_loc;
  double d_x_pos;
  double d_y_pos;
  double d_z_pos;
  double d_occ;
  double d_temper;
  int footnote;
  Atom *next_atom_p() const {return next_p;}
  void add_alt_atom(Atom*);
	
 public:
  int d_no;
  char d_name[5];
  double d_x(int =0) const;
  double d_y(int =0) const;
  double d_z(int =0) const;
  double* d_x_p(int =0) const;
  double* d_y_p(int =0) const;
  double* d_z_p(int =0) const;
  double d_temperature(int =0) const;
  double d_occupancy(int =0) const;
  const SubEntity* mySubEntity() const { return subentity_p;}
  const Entity* myEntity () const;
  const SecondaryStruc* mySecondary() const;
  const Compound* myCompound() const;
  char d_alt_location(int =0) const;
  int is_missing_atom() const {return (d_no==ILEGAL_NUMBER);};
  int number_of_alt_position() const {return num_alt_position;}
  Atom *alt_atom() const {return alt_p;}
  Atom *nth_alt_atom(int =0) const;
  List_of_atoms * bound_atoms() const;
  
};

#endif

#include "subentity.h"
#include "connectivity.h"

#ifdef _H_ATOM
#ifndef _H_CORESECONDARYSTRUC
#define _H_CORESECONDARYSTRUC


class IntrSecondaryStruc  {

  friend class IntrCompound;
  friend class IntrPdbFile;
  friend class SecondaryStrucIter;
  friend SubEntityIter;

 protected:
  IntrSecondaryStruc();
  SecondaryStruc * next_p; 
  SecondaryStruc * previous_p;
  Compound * compound_p;
  char * comment;

 public:
  SubEntity * begin_subentity_p;
  SubEntity * end_subentity_p;
  char d_type[6];			/* HELIX, STRAND, or TURN */
  int d_serial_no;
  char d_identifier[4];
  const Compound* myCompound() const{ return compound_p; }
  int assign_subentities(SubEntity& subentity1, SubEntity& subentity2);

};

#endif
#endif

#ifdef _H_SECONDARYSTRUC
#ifndef _H_COREHELIX
#define _H_COREHELIX

class IntrHelix: public SecondaryStruc {
 public:
  IntrHelix();
  int d_helix_class;
};

#endif

#ifndef _H_CORESTRAND
#define _H_CORESTRAND

class IntrStrand: public SecondaryStruc {
 protected:
  IntrStrand();
 public:
  int d_parallel;               /* no of strands */
  HydroBond * d_hydro_bond_p;
};

#endif

#ifndef _H_CORETURN
#define _H_CORETURN

class IntrTurn: public SecondaryStruc {
// hairpin, etc...
};

#endif
#endif  /* _H_SECONDARYSTRUC */


#ifndef _H_CORECHAIN
#define _H_CORECHAIN

class IntrSite {
 protected:
  IntrSite();
  Site * next_p;
  Site * Previous_p;
  Compound *compound_p;
 public:
  SubEntityList subentities_p;
  void add_subentity(SubEntity&);
  const Compound * myCompound() const {return compound_p;}
  char d_identifier[5];
};
  

class IntrEntity {
  friend class IntrPdbFile;
  friend class IntrCompound;
  friend class EntityIter;
  friend class SubEntityIter;

 protected:
  IntrEntity();
  IntrEntity(const Entity*);
  ~IntrEntity();
  Entity * next_p;
  Entity * previous_p;
  Compound * compound_p;
  SubEntity * subentities_p;
  int d_pos;
  int d_res_no;
  void add_subentity(SubEntity& subentity );
  void insert_first_subentity(SubEntity*);

 public:
  SubEntity * myFirstSubentity(){return subentities_p;}
  const Compound* myCompound() const { return compound_p; }
  char d_identifier[4];

};

#endif

#ifndef _H_COREINFO
#define _H_COREINFO

class IntrInfo {
  
/*
// these are the non-structual information of PDB file
// each pointer points to a single-link-list, each node represents a line
// in that catagory. May be NULL if info not exist in PDB file.
*/
 protected:
  IntrInfo();
  ~IntrInfo();

 public:
  LineBuffer *d_header_p;
  LineBuffer *d_obslte_p;
  LineBuffer *d_compnd_p;
  LineBuffer *d_source_p;
  LineBuffer *d_expdta_p;
  LineBuffer *d_author_p;
  LineBuffer *d_revdat_p;
  LineBuffer *d_sprsde_p;
  LineBuffer *d_jrnl_p;
  LineBuffer *d_remark_p;
};

#endif

#ifdef _H_PDBINFO
#define _H_CORECOMPOUND


class IntrCompound : public PDB_Info {
  friend class IntrPdbFile;
  friend class IntrEntity;
  friend class EntityIter;
  friend class SecondaryStrucIter;

 protected:
  IntrCompound();
  ~IntrCompound();
  CovalBond *coval_bonds_p;
  HydroBond *hydro_bonds_p;
  SaltBridg *salt_bridgs_p;
  SSBond *ss_bonds_p;
  ConnectivitySet *c_set_p;
  Entity *polymers_p;
  Entity *non_polymers_p;
  SecondaryStruc *d_secondary_p;
  void add_entity( Entity& entity);
  void add_secondary( SecondaryStruc& secondstruc );
  void add_bond(CovalBond*);
  void add_bond(HydroBond*);
  void add_bond(SaltBridg*);
  void add_bond(SSBond*);
  void add_het_subentity(SubEntity&);
  void assign_connectivity_map(ConnectivitySet *mp){c_set_p=mp;}
  SubEntity * find_empty_subentity(SubEntity*, char*, char*, int, int);
  SubEntity * insert_subentity_after(SubEntity*, SubEntity*, char*, int);
  SubEntity * find_pre_non_exc_subentity(SubEntity*);
  SubEntity * new_subentity(char*) const;
  
 public:
  char d_identifier[5];
  double ramachandran_quality() const;
  HistogramValues * omega_angles() const;
  HistogramValues * delta_omegas() const;
  ConnectivitySet *connectivity_set_p() const {return c_set_p;}
  void check_bonds();  //for debugging only.

};


#endif

















