#include "general-list.h"
#include <math.h>

/****
 *
 * Implementation of general-list.h.
 *
 * THIS IS A SKELETON, with function bodies to be filled in for lab 3.
 *
 * While this skeleton shows you which function bodies you need to fill in, I
 * strongly recommend that you do this lab by copying GeneralList.java to your
 * version of general-list.c, and then modifying the Java code into legal C
 * code.  This will save you a lot of time typing, and avoid simple errors of
 * translation.
 * 
 */

GeneralList* newGeneralList() {

}

GeneralList* newGeneralListArray(char* array[], int numElems) {

}


/*-*
 * Constructive (i.e., storage) methods
 */

GeneralList* putFirst(GeneralList* list, char* element) {

}

GeneralList* putLast(GeneralList* list, char* element) {

}

GeneralList* put(GeneralList* list, char* element, int i) {

}

GeneralList* set(GeneralList* list, char* element, int i) {

}

char* getFirst(GeneralList* list) {

}

char* getLast(GeneralList* list) {

}

char* get(GeneralList* list, int i) {

}

char* removeFirst(GeneralList* list) {

}

char* removeLast(GeneralList* list) {

}

char* removeIth(GeneralList* list, int i) {

}


/*-*
 * Searching and sorting methods.
 */

bool elementOf(GeneralList* list, char* element) {

}

int findIndex(GeneralList* list, char* element) {

}

GeneralList* sort(GeneralList* list) {

}

/*-*
 * Utility methods
 */

GeneralList* subList(GeneralList* list, int i, int j) {

}

int length(GeneralList* list) {

}

bool isEmpty(GeneralList* list) {

}

bool equals(GeneralList* list1, GeneralList* list2) {

}

char* toString(GeneralList* list) {

    /* HINT -- use the macro newstrcat */

}


/*-*
 * Internal methods
 */

GeneralListNode* getIthNode(GeneralList* list, int i) {

    int j;                           // Traversal counter
    GeneralListNode* node;           // Traversal pointer

    /*
     * If i is in first half of the list, locate the node starting from the
     * front, else from the back.
     */
    if (i < list->length / 2) {
	for (j = 0, node = list->first; j < i; j++, node = node->next) ;
    }
    else {
	for (j = list->length-1, node = list->last; j > i; j--, node = node->prev) ;
    }

    return node;

}

int linearSearch(GeneralList* list, char* element) {

    GeneralListNode* node;           // Traversal pointer
    int i;                           // Traversal index

    for (node = list->first, i = 0; node != null; node = node->next, i++) {
	if (valueEquals(element, node->value)) {
	    return i;
	}
    }
    return -1;
}

int binarySearch(GeneralList* list, char* element) {

    int midpoint;                   // Midpoint of startPos/endPos interval
    int startPos = 0;               // Initial start position
    int endPos = list->length - 1;  // Initial end position

    /*
     * Iterate through the list while the length of the startPos/endPos
     * interval is >= 1 and we haven't yet found the searched-for element.
     * For each loop iteration, compute the interval midpoint and then do
     * one of the following:
     *
     *     (a) If the searched-for element is at the midpoint, return
     *         successfully.
     *
     *     (b) If the searched-for element is less than the midpoint
     *         element, search the lower half of the list.
     *
     *     (c) If the searched-for element is greater than the midpoint
     *         element, search the upper half of the list.
     */
    while (startPos <= endPos) {
	midpoint = (startPos + endPos) / 2;
	if (valueEquals(element, list->sortedArray[midpoint]->value)) {
	    return midpoint;
	}
	else if (valueCompareTo(element, list->sortedArray[midpoint]->value) < 0 ) {
	    endPos = midpoint - 1;
	}
	else
	    startPos = midpoint + 1;
    }

    /*
     * Fail if we never find the element.
     */
    return -1;

}

void swapNodeValues(GeneralListNode* n1, GeneralListNode* n2) {

    char* temp;            // Temp value;

    /*
     * Use standard swap logic.
     */
    temp = n1->value;
    n1->value = n2->value;
    n2->value = temp;

}