#include<stdlib.h>
#include<stdio.h>
#include<time.h>

int suche(int **pos, int *s, int *e, int x) {
  // Binary search wobei e IMMER hinter das letzte element zeigen muss!
  
  if (s == NULL || e == NULL || s > e) {
      *pos = NULL;
      return 0;
  }

  while (s < e) {
      int l = e - s;
      int m = l / 2;

      if (s[m] == x) { 
          *pos = s + m;
          return 1;
      } 
      else if (s[m] > x) {
          e = s + m;
      } 
      else {
          s = s + m + 1;
      }
  }

  *pos = NULL;
  return 0;
}

// Main loop for the problem
int main(int argc, char *argv[]) {
  srand(time(NULL));
  // Check for the right amount of args
  if (argc != 3) {
    printf("wrong amount of arguments!\n");
    return 1;
  }

  // Get the parameters
  int n = atoi(argv[1]);
  int k = atoi(argv[2]);

  // Checken ob das n Arguemnt richtig gegeben wurde
  if (n < 1) {
    printf("n ist zu klein gewaehlt oder konnte nicht gelesen werden!\n");

    // Hier wird die suche mit Null pointern gestartet 
    int buf = suche(0, 0, 0, 0);
    printf("Ergebnis der Suche: %d.\n", buf);

    return 1;
  } 


  // Generate random ascending field of length n
  int *m = malloc(sizeof(int) * n);
  if (!m) {
    printf("it was not possible to allocate memory!\n");
    return 1;
  }

  // Erzeugen eins aufsteigenden Feldes
  m[0] = rand()%n+1;
  for(int i = 1; i < n; i++) {
    m[i] = m[i-1] + rand()%(n*2)+1;

    // Es soll nach moeglichen Ueberlaufen geprueft werden
    // Wie kann man das anders machen als zu pruefen ob die zahl kleiner ist?
    if (m[i] < m[i-1]) {
      printf("es gab ein Problem!\n");
      return 1;
    }
  }

  // Print the field
  for(int i = 0; i < n - 1; i++) {
    printf("%d ", m[i]);
  }
  printf("%d\n", m[n-1]);


  int *pos;
  int buf;
  if (k >= 0 && k < n) {
    // k ist ein valider Index vom Feld
    printf("%d", m[k]);
    buf = suche(&pos, m, m+n, m[k]);
  } else {
    buf = suche(&pos, m, m+n, k);
  }

  printf("Das Ergebnis der Suche ist %d.\n"
         "Der Zeiger hat die relative position (Nur relevant wenn suche 1) %d.\n"
         "Der Zeiger hat die absolute Postion (Nur relevant wenn suche 0) %d.\n", buf, pos - m, pos); 


  // Noch zu tun ist das aufrufen von der find methode in den verschiedenen aesten.
  // und das jeweilige zurueckgeben ob der Wert gefunden wurde und der pointer.
  
  free(m);
  
  return 0;
}

