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

/*
 spojovy seznam:
,,
 |
 [1 | .]
 .    |      
 .    `-> [2 | .]
 .             |
 .             `-> [3 | X]
 */

struct Node {
  int value;
  struct Node* next;
};

void PrintList(struct Node* head) {
  while (head)
  {
    printf("%d\n", head->value);
    head = head->next;
  }
}

void push_node(int value, struct Node** head){
  struct Node* new_head = malloc(sizeof(struct Node));
  new_head->value = value;
  new_head->next = *head;
  *head = new_head;
}


void pop_node(struct Node** head) {
  struct Node* temp;
  temp = (*head)->next;
  free(*head);
  *head = temp;
}



void list_delete(struct Node** head) {
  while (*head)
    pop_node(head);
}
// #define hej ano
//         [1] -> [2] -> [3] -> NULL
// NULL <- [1] <- [2] <- [3] <- last
//                              next -> NULL 

// NULL <- last
//         next -> [1] -> [2] -> ....

// NULL <- [1] <- last
//                next -> [2] -> [3] -> NULL



void reverse_list(struct Node** head){
  struct Node *last = NULL, *next = *head;

  while(next) {
    struct Node* temp;
    temp = next->next;
    next->next = last;
    last = next;
    next = temp;
  }
  *head = last;
}

void swap(int* a, int* b){
  int c= *a;
  *a = *b;
  *b = c;
}

void bubble_sort(struct Node* head){
  struct Node *i, *j;
  for(i=head; i; i=i->next){
    for(j=head; j->next; j=j->next){
      if (j->value > j->next->value)
        swap(&j->value, &j->next->value);
    }
  }
}

int f(int x) {
  return 2*x;
}

int (*p);
int (*pf)(int);

void list_map(int (*func)(int), struct Node* head){
  for(; head; head = head->next)
    head->value = func(head->value);   
}


// map (*2) [1,2,3]   --> [2,4,6]

// int f(int);
// map(f, l);

int main(void) {

  struct Node* l = NULL;
  push_node(42, &l);
  push_node(37, &l);
  push_node(69, &l);
  push_node(9, &l);
  push_node(600, &l);
  
  PrintList(l);
  printf("\n\n");;
  reverse_list(&l);
  PrintList(l);
  printf("\n\n");;
  bubble_sort(l);

  PrintList(l);

  list_map(f, l);
  PrintList(l);

  list_delete(&l);
  
  return 0;
}
