#include "linkedlist.h"

linkedlist::linkedlist(): head(NULL) {}
linkedlist::~linkedlist(){clear();}

bool linkedlist::is_it_zero(int value) {
    if(value < 0)
        return false;
    else
        return true;
}

bool linkedlist::has_a(int value) {
  //  cout << "has_a(" << value << ")" << endl;
    node* node_ptr = head;
    if(head == NULL)
        return false;
    while(node_ptr != NULL) {
        if(node_ptr->value == value)
            return true;
        node_ptr = node_ptr->next;
    }
    return false;
}

void linkedlist::insertHead(int value) {
   // cout << "inserthead(" << value << ")" << endl;
   // cout << *this << endl;
    if(!is_it_zero(value))
        return;
    if(has_a(value))
        return;
    head = new node(value, head);
  //  cout << *this << endl << endl;
}

void linkedlist::insertTail(int value) {
   // cout << "insertTail(" << value << ")" << endl;
   // cout << *this << endl;
    if(!is_it_zero(value))
        return;
    if(has_a(value))
        return;
    if(head == NULL) {
        insertHead(value);
        return;
    }
    node* node_ptr = head;
    while(node_ptr != NULL) {
        if(node_ptr->next == NULL) {
            node_ptr->next = new node(value, NULL);
            break;
        }
        node_ptr = node_ptr->next;
    }
  //  cout << *this << endl << endl;
}

void linkedlist::insertAfter(int value, int insertionNode) {
  //  cout << "insertAfter(" << value << ", insertionNode" << insertionNode << ")" << endl;
  //  cout << *this << endl;
    if(value < 0 || insertionNode < 0) {
        //cout << "first check" << endl;
        return;
    }
    if(has_a(value) || !has_a(insertionNode)) {
        //cout << "failing" << endl;
        return;
    }
    node* node_ptr = head;
    while(node_ptr != NULL) {
        if(node_ptr->value == insertionNode) {
            node* temp = new node(value, NULL);
            temp->next = node_ptr->next;
            node_ptr->next = temp;
        }
        node_ptr = node_ptr->next;
    }
  //  cout << *this << endl << endl;
}

void linkedlist::remove(int value) {
 //   cout << "remove(" << value << ")" << endl;
 //   cout << *this << endl;
    if(!is_it_zero(value))
        return;
    if(!has_a(value))
        return;
    node* node_ptr = head;
    if(node_ptr->value == value) {
        //cout << "first" << endl;
        node* ptr = head;
        head = head->next;
        delete ptr;
        return;
    }
    while(node_ptr != NULL) {
        if(node_ptr->next == NULL)
            return;
        if(node_ptr->next->value == value) {
            node* ptr = node_ptr->next;
            node_ptr->next = node_ptr->next->next;
            delete ptr;
        }
        node_ptr = node_ptr->next;
    }
 //   cout << *this << endl << endl;
}

void linkedlist::clear() {
 //   cout << "clear()" << endl;
    node* node_ptr = head;
    while(head) {
        node_ptr = head;
        head = head->next;
        delete node_ptr;
    }
}

int linkedlist::at(int index) {
  //  cout << *this << endl;
  //  cout << "at(" << index << ")" << endl;
    if(index < 0) {
        //cout << "is it zero" << endl;
        return -1;
    }
    if(size() <= index) {
       // cout << "this is the index=" << index << " size(" << size() << ")"<<endl;
        return -1;
    }
    node* node_ptr = head;
    for(int i = 0; i < index; i++){
        node_ptr = node_ptr->next;
    }
    if(head == NULL)
        return -1;
    return node_ptr->value;
}

int linkedlist::size() {
    int size_of_list = 0;
    node* node_ptr = head;
    while(node_ptr != NULL) {
        size_of_list++;
        node_ptr = node_ptr->next;
    }
   // cout << "size(" << size_of_list << ")" << endl;
    return size_of_list;
}

ostream & operator<<(ostream & os, linkedlist & f) {
    node* node_ptr = f.head;
    while(node_ptr != NULL) {
        os << node_ptr->value << ",";
        node_ptr = node_ptr->next;
    }
    return os;
}
