#include "doublyLinkedSwap.h"

// Implement this function
void swapWithNext(Node *p) {

    // Check that the node being passed to function has value (in case it's the head or tail),
    // that the node before p has value (in case it's the head), that the node after p has
    // value (in case it's the tail), and that the node after p->next has value (in case it's
    // the node before the tail)
    if (p == nullptr || p->prev == nullptr || p->next == nullptr || p->next->next == nullptr) {

        return;

    }

    // Store current prev and next pointers of p
    Node *previousNode = p->prev;
    Node *nextNode = p->next;

    // Shift the prev and next pointers of p forward one node
    p->next = p->next->next;
    p->next->prev = p;

    // Shift the prev and next pointers of stored values to corresponding stored value
    previousNode->next = nextNode;
    nextNode->prev = previousNode;

    // Set the value of p->prev to the shifted stored next node
    p->prev = nextNode;
    // Set the value of nextNode->next to the shifted p
    nextNode->next = p;

}

// Be sure to comment out main() before submitting
// int main() {
    
//     int array[] = {1, 3, 6, 10, 15, 21, 28, 36, 45, 55};
//     Node *head = arrayToList(array, 10);
//     printForwards(head);
//     printBackwards(getTail(head));
    
//     cout << "Swap [0],[1]" << endl;
//     Node *p = getNode(head, 0);
//     swapWithNext(p);
//     printForwards(head);
//     printBackwards(getTail(head));
    
//     cout << "Swap [4],[5]" << endl;
//     p = getNode(head, 4);
//     swapWithNext(p);
//     printForwards(head);
//     printBackwards(getTail(head));
    
//     cout << "Swap [8],[9]" << endl;
//     p = getNode(head, 8);
//     swapWithNext(p);
//     printForwards(head);
//     printBackwards(getTail(head));

// }

// Do not modify anything below

Node *arrayToList(int array[], int size) {
    
    Node *head;
    Node *p;
    int pos = 0;
    if (size > 0) {
        
        head = new Node();
        head->prev = nullptr;
        head->value = 0;
        p = head;
        while (pos < size) {
            
            p->next = new Node();
            p->next->prev = p;
            p = p->next;
            p->value = array[pos];
            pos++;
        
        }
        p->next = new Node();
        p->next->prev = p;
        p = p->next;
        p->value = 0;
        p->next = nullptr;
    
    } else {
        
        return nullptr;
    
    }
    return head;

}

// Return pointer to end of the list
Node *getTail(Node *head) {
    
    Node *p = head;
    while (p->next != nullptr) {
        
        p = p->next;
    
    }
    return p;

}

// Return pointer to node with "index"
// First node "index" 0, second node "index" 1, ...
Node *getNode(Node *head, int index) {
    
    int pos = 0;
    Node *p = head->next;
    if (pos == index) {
        
        return p;
    
    } else if (index < 0) {
        
        return head;
    
    } else {
        
        while (pos < index && p->next != nullptr) {
            
            p = p->next;
            pos++;
        
        }
    
    }
    return p;

}

// Print list forwards from start
void printForwards(Node *head) {
    
    Node *p = head->next;
    while (p->next != nullptr) {
        
        cout << p->value << " ";
        p = p->next;
    
    }
    cout << endl;

}

// Print list backwards from end
void printBackwards(Node *tail) {
    
    Node *p = tail->prev;
    while (p->prev != nullptr) {
        
        cout << p->value << " ";
        p = p->prev;
    
    }
    cout << endl;

}