/* lzs.c 
 *
 * contains functions useful for work 
 * with linearly concatenated list
 * ----------------------------------------
 */

#include "main.h"

/* ------------------------------------------------------------------------- */
/* creating a neighbour of the given element                                 */
PRVEK *vytvor_souseda (SEZNAM *p_sf, PRVEK *p_pa, int c_seznam, int c_soused) {
/* ------------------------------------------------------------------------- */

  PRVEK *p_pf=NULL;
  SEZNAM *p_sspoj=NULL, *p_sudaje=NULL;

  if (p_pa == NULL) {
    /* creates a first neighbour of the given SEZNAM element
     * puts information (index, chemical symbol and coordinates) into it
     * returns a pointer on it
     */   
    p_sspoj = najdi_prvek_seznamu_podle_cisla (p_sf,c_seznam);
    if ((p_sspoj -> dalsi_prvek = (PRVEK *) malloc (sizeof(PRVEK))) == NULL) {
      printf ("There is no more free space on heap.\nProgram will be terminated.\n");
      return NULL;
    } 
    p_pf = p_sspoj -> dalsi_prvek;
    p_sudaje = najdi_prvek_seznamu_podle_cisla (p_sf, c_soused);
    p_pf -> cislo = p_sudaje -> cislo;
    strcpy (p_pf -> ch_znacka, p_sudaje -> ch_znacka);
    p_pf -> x = p_sudaje -> x;
    p_pf -> y = p_sudaje -> y;
    p_pf -> z = p_sudaje -> z;
    p_pf -> dalsi = NULL; 
    return p_pf;

  } else { 
    /* creates new neighbour of the given SEZNAM element 
     * connects it to the previous neighbour (pointer on previous neighbour
     * is given as a parameter)
     * puts information (index, chemical symbol and coordinates) into it
     * returns a pointer on it
     */
    if ((p_pa -> dalsi = (PRVEK *) malloc (sizeof(PRVEK))) == NULL) {
      printf ("There is no more free space on heap.\nProgram will be terminated.\n");
      return (NULL);
    }
    p_pa = p_pa -> dalsi;
    p_sudaje = najdi_prvek_seznamu_podle_cisla(p_sf,c_soused);
    if (p_sudaje != NULL) {
      p_pa -> cislo = p_sudaje -> cislo;
    } else { 
      printf("Element with index %d not found. Program will be terminated.\n",p_sudaje->cislo);
      exit(1);
    }
    strcpy (p_pa -> ch_znacka, p_sudaje -> ch_znacka);
    p_pa -> x = p_sudaje -> x;
    p_pa -> y = p_sudaje -> y;
    p_pa -> z = p_sudaje -> z;
    p_pa -> dalsi = NULL;
    return p_pa;
   }
}

/* ------------------------------------------------------------------------- */
/* goes through neighbours of the given SEZNAM element                       *
 * and returns a pointer on the last of them                                 */
PRVEK *najdi_konec_sousedu_prvku_seznamu(SEZNAM *p_sf, int c_seznam) {
/* ------------------------------------------------------------------------- */

  PRVEK *p_pa=NULL;
  SEZNAM *p_sa=NULL;

  p_sa = najdi_prvek_seznamu_podle_cisla(p_sf, c_seznam);
  p_pa = p_sa -> dalsi_prvek;
  while (p_pa -> dalsi != NULL) {p_pa = p_pa -> dalsi;}  
  return p_pa;  
}


/* ------------------------------------------------------------------------- */
/* writes index and chemical symbol of neighbours of given SEZNAM element    */
void vypis_info_o_sousedech_prvku (SEZNAM *p_sa) {
/* ------------------------------------------------------------------------- */
  PRVEK *p_pa=NULL;

  p_pa = p_sa -> dalsi_prvek;
  printf("Neighbours of given SEZNAM element are:\n");
  while (p_pa != NULL) {
    printf ("%d%s ",p_pa -> cislo, p_pa -> ch_znacka);
    p_pa = p_pa -> dalsi;
  } 
  printf("\n");
}

/* ------------------------------------------------------------------------- */
/* writes index and chemical symbol of SEZNAM element                        *
 * which is given as parameter                                               */
void vypis_info_o_prvku_seznamu (SEZNAM *p_sa){
/* ------------------------------------------------------------------------- */
  printf ("Given pointer actually points at SEZNAM element with:\n");
  printf ("  index %d and chemical symbol %s.\n",p_sa -> cislo, p_sa -> ch_znacka);
}

/* ------------------------------------------------------------------------- */
/* according to the given index this function finds SEZNAM element           *
 * in the structure and returns pointer on it                                */
SEZNAM *najdi_prvek_seznamu_podle_cisla (SEZNAM *p_sf, int c) {
/* ------------------------------------------------------------------------- */
  SEZNAM *p_sa=NULL;

  p_sa = p_sf;
  while (p_sa != NULL) {
    if (p_sa -> cislo == c) {return p_sa;}
    p_sa = p_sa -> dalsi_seznam;
  }
  return NULL;
}

/* ------------------------------------------------------------------------- */
/* goes through the SEZNAM structure and returns pointer on its last element */
SEZNAM *najdi_konec_seznamu(SEZNAM *p_sf) {
/* ------------------------------------------------------------------------- */
  SEZNAM *p_sa=NULL;

  p_sa = p_sf; 
  while (p_sa -> dalsi_seznam != NULL) {p_sa = p_sa -> dalsi_seznam;}
  return p_sa;
}

/* ------------------------------------------------------------------------- */
/* creates new SEZNAM element                                                */
SEZNAM *vytvor_prvek_seznamu (SEZNAM *p_sa, int c, char z[3], char a[3], int rS, float s1, float s2, float s3) {
/* ------------------------------------------------------------------------- */
  if (p_sa == NULL) {
      /* creates first SEZNAM element, puts into it 
       * relevant index and chemical symbol and 
       * returns a pointer on it 
       */
      SEZNAM *p_sf=NULL;

      if ((p_sf = (SEZNAM *) malloc (sizeof(SEZNAM))) == NULL) {
          printf ("There is no more free space on heap.\nProgram will be terminated.\n");
          return(NULL);
      }
      p_sf -> cislo = c;
      strcpy(p_sf -> ch_znacka, z);
      strcpy(p_sf -> resName, a);
      p_sf -> resSeq = rS;
      p_sf -> x = s1;
      p_sf -> y = s2;
      p_sf -> z = s3;
      p_sf -> ucsf = 0;
      p_sf -> sur_atom = -1;
      p_sf -> dalsi_seznam = NULL;
      p_sf -> dalsi_prvek = NULL;
 
      return p_sf;
  } else {
     /* creates new SEZNAM element, 
      * connects it with previous SEZNAM element (pointer on previous 
      * element is given as parameter),
      * puts into it index and chemical symbol,
      * returns a pointer on it 
      */
      if ((p_sa -> dalsi_seznam = (SEZNAM *) malloc (sizeof(SEZNAM))) == NULL) {
         printf ("There is no more free space on heap.\nProgram will be terminated.\n");
         return(NULL);
      }
      p_sa = p_sa -> dalsi_seznam;
      p_sa -> cislo = c;
      strcpy(p_sa -> ch_znacka, z);
      strcpy(p_sa -> resName, a);
      p_sa -> resSeq = rS;
      p_sa -> x = s1;
      p_sa -> y = s2;
      p_sa -> z = s3;
      p_sa -> ucsf = 0;
      p_sa -> sur_atom = -1;
      p_sa -> dalsi_prvek = NULL;
      p_sa -> dalsi_seznam = NULL;
      return p_sa;
  }
}
/* ------------------------------------------------------------------------- */
/* destroying SEZNAM elements                                                */
void zrus_seznam(SEZNAM *p_sf) {
/* ------------------------------------------------------------------------- */
  SEZNAM *p_sa=NULL;
  PRVEK *p_pf=NULL, *p_pa=NULL;
  
  while (p_sf !=NULL) {
     p_sa = p_sf;
     p_sf = p_sa -> dalsi_seznam;
     p_pf = p_sa -> dalsi_prvek;
     while (p_pf != NULL) {
       p_pa = p_pf;
       p_pf = p_pa -> dalsi; 
       free((void *) p_pa);
     }
     free((void *) p_sa);
     
  }
}

