#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

//-------------------------------------------------------------------------------------
// CONSTANTS and TYPES
//-------------------------------------------------------------------------------------



struct NODE
{
	char *data;
	struct NODE *link;
};

typedef enum BOOL { false, true } Boolean;
typedef struct NODE Node;





//-------------------------------------------------------------------------------------
// VARIABLES
//-------------------------------------------------------------------------------------

	Node *head = NULL;
	int size = 0;
	int traversal = 0;
//-------------------------------------------------------------------------------------
// PROTOTYPES
//-------------------------------------------------------------------------------------

// add an element to the beginning of the linked list
Boolean insert( char *new_string );
// empty the list so that we clear all memory and can start a fresh list
void clearList();
// tells us whether or not the given string is in the list
Boolean search( char *target );
// starts a list traversal by getting the data at top
char * firstItem();
// gets the data at the current traversal node and increments the traversal
char * nextItem();

//-------------------------------------------------------------------------------------
// FUNCTIONS
//-------------------------------------------------------------------------------------
	void validateNode( Node *node )
	{
		assert( node != NULL );
		assert( node->data != NULL);	
	}

Boolean insert( char *new_string )
{
	Node *new;
	Boolean isInserted = false;

	new = ( Node* )malloc( sizeof(Node) );
	assert ( new != NULL );
	
	assert( new_string != NULL );
	
	//if( head == NULL)
	//	head = ( Node* )malloc( sizeof( Node ) );
		new->data = ( char* )malloc( strlen( new_string ) );
		new->data = new_string;
		//printf("%s\n", new->data);
		assert( strcmp( new->data, new_string) == 0 );
		
		new->link = head;
		validateNode( new );
		
		head = new;
		validateNode( head );
		
		size++;
		
		isInserted = true;
	//printf("%s\n", head->data);
	
	return isInserted;

}//insert

void clearList()
{
	Node *curr = ( Node* )malloc( sizeof( Node ) );
	assert ( curr != NULL );
	
	Node *next = ( Node* )malloc( sizeof( Node ) );
	assert ( next != NULL );
	
	curr = head;
	validateNode(curr);

	while ( curr != NULL )
		{
			next = curr->link;
			free(curr);
			curr = next;
		}
		size = 0;
}//clearList

Boolean search( char *target )
{

	Boolean isFound = false;
	Node *curr = ( Node* )malloc( sizeof( Node ) );
	assert ( curr != NULL );
	
	curr = head;
	if( head != NULL )
	//printf("%d ", strcmp( curr->data, target ) );
	//validateNode( curr );
	
	while ( curr != NULL && strcmp( curr->data, target ) != 0 )
		{
			curr = curr->link;
		}
	
	if ( curr != NULL)
	{
		validateNode( curr );
		if ( strcmp( curr->data, target ) != 0 )
		{
			isFound = true;
			//printf("%s   ", curr->data);
		}
	}
	
	return isFound;
}

char * firstItem()
{
	char * temp = NULL;
	//printf("\n1\n");
	validateNode( head );
	
	if ( head != NULL )
		temp = head->data;
	//printf("%s", temp);
		
	return temp;
}

char * nextItem()
{
	char* temp = NULL;
	Node* curr = ( Node* )malloc( sizeof( Node ) );
	assert ( curr != NULL );
	curr = head;
	//int i = 0;
	if ( traversal < size )
	{
		for( int i = 0; i < traversal && curr != NULL; i++ )
			{
				curr = curr->link;
			}

		temp = curr->data;
		traversal++;
	}

	return temp;
}
// read from standard input, tokenize and insert words into a linked list
// note that we must ensure that there are no duplicates in our list
void loadFile()
{
#define LINE_SIZE 256
  char input[LINE_SIZE];
  char *token = NULL;
//printf("3");
  while ( fgets( input, LINE_SIZE, stdin ) )
  {//printf("1");
    // parse the data into separate elements
    token = strtok( input, " \t\n" );
    while ( token )
    { //printf("2");
      if ( !search( token ) ){
        insert( token );
		
		}
		
      token = strtok( NULL, " \t\n" );
    }
  }
  printf("%s\n", head->data);
}

// print the contents of the linked list to standard output
void printConcordance()
{
  char *theWord = firstItem();

  while ( theWord )
  {
   // printf( "%s\n", theWord );
    theWord = nextItem();
  }
}

void print()
{
	printf("%s   %u\n", head->data, strlen(head->data));
	Node *curr;
	curr = ( Node* )malloc( sizeof( Node ) );
	curr = head;
	validateNode( curr );
	
	
	while( curr )
	{
	//	printf("%s\n", curr->data );
		curr = curr->link;
	}
}

int main( int argc, char *argv[] )
{
  //printf("%s\n", head->data);
  loadFile();
  //printf("%s\n", head->data);
  //printConcordance();
  print();
  clearList();
	
  return EXIT_SUCCESS;
}