#include "linkedlist.h"

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

void linkedlist::insertHead(int id) {
    head = new node(id, head);
}

void linkedlist::insertTail(int id) {
    if(head == NULL) {
        insertHead(id);
        return;
    }
    node* node_ptr = head;
    while(node_ptr != NULL) {
        if(node_ptr->next == NULL) {
            node_ptr->next = new node(id, NULL);
            break;
        }
        node_ptr = node_ptr->next;
    }
}

void linkedlist::insertAfter(int id, int insertionNode) {
    node* node_ptr = head;
    while(node_ptr != NULL) {
        if(node_ptr->id == insertionNode) {
            node* temp = new node(id, NULL);
            temp->next = node_ptr->next;
            node_ptr->next = temp;
        }
        node_ptr = node_ptr->next;
    }
}

void linkedlist::remove(int id) {
    node* node_ptr = head;
    if(node_ptr->id == id) {
        node* ptr = head;
        head = head->next;
        delete ptr;
        return;
    }
    while(node_ptr != NULL) {
        if(node_ptr->next == NULL)
            return;
        if(node_ptr->next->id == id) {
            node* ptr = node_ptr->next;
            node_ptr->next = node_ptr->next->next;
            delete ptr;
        }
        node_ptr = node_ptr->next;
    }
}

void linkedlist::clear() {
    node* node_ptr = head;
    while(head) {
        node_ptr = head;
        head = head->next;
        delete node_ptr;
    }
}

int linkedlist::at(int index) {
    if(index < 0) {
        return -1;
    }
    if(size() <= index) {
        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->id;
}

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

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