// Arup Guha
// 11/2/2011
// Written in COP 3223H to illustrate using string functions and sorting.

#include <stdio.h>
#include <ctype.h>
#include <string.h>

void sort(char words[][20], int numwords);
int findMinIndex(char words[][20], int low, int high);
void toLowerCase(char word[]);
void printWords(char words[][20], int numwords);

int main() {

    FILE* ifp = fopen("input.txt", "r");

    // File opened successfully.
    if (ifp != NULL) {

        char words[1000][20];

        // Read at most 1000 words from the file.
        int numwords = 0;
        while (!feof(ifp) && numwords < 1000) {
            char temp[20];

            fscanf(ifp, "%s", temp);

            // Only store real strings.
            if (strlen(temp) > 0) {
                strcpy(words[numwords], temp);
                numwords++;
            }
        }

        // Check the list beforehand.
        printf("Before:\n\n");
        printWords(words, numwords);
        printf("\n\n");

        sort(words, numwords);

        // And afterwards.
        printf("After:\n\n");
        printWords(words, numwords);
        printf("\n\n");
    }
    else {
        printf("Sorry no input file input.txt found.\n");
    }
}

// Sorts the first numwords in the array words using case-insensitive
// comparisons.
void sort(char words[][20], int numwords) {

    int i;

    // Place the correct word in index i.
    for (i=0; i<numwords-1; i++) {

        int minindex = findMinIndex(words, i, numwords-1);

        // Swaps minimum word in to spot i.
        char temp[20];
        strcpy(temp, words[minindex]);
        strcpy(words[minindex], words[i]);
        strcpy(words[i], temp);
    }

}

// Finds the index in [low, high] that stores the first word
// alphabetically in words, without regard to case.
int findMinIndex(char words[][20], int low, int high) {

    // This is our best for now.
    int best = low;
    int i;

    // Look for a word that comes before best.
    for (i=low+1; i<=high; i++) {

        // Makes sure
        char temp1[20], temp2[20];
        strcpy(temp1, words[best]);
        strcpy(temp2, words[i]);
        toLowerCase(temp1);
        toLowerCase(temp2);

        // If the string in index i comes before
        // the string in index best, reset best to i.
        if (strcmp(temp2, temp1) < 0)
            best = i;
    }

    return best;
}

// Changes word to contain all lowercase letters.
void toLowerCase(char word[]) {

    int i = 0;
    while (word[i] != '\0') {
        word[i] = tolower(word[i]);
        i++;
    }
}

// Prints out the first numwords words in words.
void printWords(char words[][20], int numwords) {

    int i;
    for (i=0; i<numwords; i++)
        printf("%s\n", words[i]);
}
