// readUsersFromFile.cpp
// P.Conrad, Fall 2004

// CISC181, A program to read usernames from a file instead of
// from the command line.   It is assumed that the file "usernames.txt"
// is in the "current directory" at the time the program is invoked.
// The output is still written to the screen.


// Note: This program is a HACK.    I hesitate to show it to you, because
//       it might not be the "best" style throughout.  Nevertheless, I'm going
//       to show it anyway, because you'll see a lot of code in the real world
//       that started out as a "hack" and ended up in production.

//       So you might as well see some now, and have a discussion about
//       the style points that arise...

#include <iostream>
using namespace std;


#include <fstream> // for reading directly from a disk file
using std::ifstream; // input file stream


void outputHTMLHeader(ostream &outf)
{
  outf << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
       << "<html>\n"
       << "<head>\n"
       << "<title>CISC181 04F class list</title>\n"
       << "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n"
       << "</head>\n"
       << "\n"
       << "<body>\n"
       << "<h3>CISC181 04F class list</h3>\n"
       << "<p>Sorted first by section, then by last name, \n"
       << "then by first name</p>\n"
       << "<p>If you are registered for CISC181 and your name \n"
       << "does not appear on this list, \n"
       << "please email Prof. Conrad to let him know. For the \n"
       << "web ring, link to the person\n"
       << "  whose name appears immediately below yours (even if \n"
       << " that person is in a different " 
       << "  section). The last person on the list should link back \n"
       << " to the first person\n"
       << "  on the list (completing the ring).</p>\n"
       << "<p>Note that when you establish your link, the person you \n"
       << " are linking &quot;to&quot; might\n"
       << "  not have completed their web page yet; email him/her \n"
       << " (his/her userid, followed\n"
       << "  by @udel.edu) to encourage him/her to do so! Only then \n"
       << " can you really test\n"
       << "  whether your link is correct or not.</p>\n"
       << "<p>Also, memorize who you are linking to; we'll use that \n"
       << " information to call\n"
       << "  the roll in future lecture and lab sessions.</p>\n"
       << "<table>\n"
       << endl;

}


void outputHTMLTrailer(ostream &outf)
{
  outf << "</body>\n"
       << "</html>\n"
       << endl;
}


void      outputUdelLinkCell(ostream &outf, 
			 const char * const  username, 
			 const char * const linkSuffix, 
			 const char * const linkText )
{
  const char * const linkPrefix="http://udel.edu/";
  
  outf << "    <td><a href=" << linkPrefix << "~" << username 
       << linkSuffix << ">" << linkText << "</a></td>" << endl;
}

const int MAX_USERNAME_LENGTH = 8; // restriction of 8 comes from Unix rules
const int MAX_NAME_LENGTH = 80; // make it nice and big
const int LINE_LENGTH = 80; // make it nice and big
const int MAX_SECT_LENGTH = 3; 

void      parseInputLine(char * const inputLine,
			 char * const username,
			 char * const studentFirstName,
			 char * const studentLastName,
			 char * const sectionString)
{
  char *usernamePtr;
  char *studentFirstNamePtr;
  char *studentLastNamePtr;
  char *sectionPtr;
  
  studentLastNamePtr = strtok(inputLine,",");
  strncpy(studentLastName, studentLastNamePtr, MAX_NAME_LENGTH);
  studentLastName[MAX_NAME_LENGTH]='\0'; // null terminate for safety      
  
  studentFirstNamePtr = strtok(NULL,",");
  strncpy(studentFirstName, studentFirstNamePtr, MAX_NAME_LENGTH);
  studentFirstName[MAX_NAME_LENGTH]='\0'; // null terminate for safety      

  usernamePtr = strtok(NULL,",");
  strncpy(username, usernamePtr, MAX_USERNAME_LENGTH);
  username[MAX_USERNAME_LENGTH]='\0'; // null terminate for safety


  
  sectionPtr = strtok(NULL,",");
  strncpy(sectionString, sectionPtr, MAX_SECT_LENGTH);
  sectionString[MAX_SECT_LENGTH]='\0'; // null terminate for safety      
}



int main(void)
{
  
  // try to open an input file
  
  ifstream userInputFile("usernames.txt",ios::in); // open the file
  
  
  
  // test whether the file was opened correctly using the
  // overloaded ! operator; returns false if opening the file failed
  
  if (!userInputFile) 
    {
      cerr << "usernames.txt file could not be opened" << endl;
      exit (-1);
    }
  
  ofstream outf("class.html",ios::out); // open the file    
  
  if (!outf) 
    {
      cerr << "class.html file could not be opened" << endl;
      exit (-1);
    }

  outputHTMLHeader(outf);
 
  char username[MAX_USERNAME_LENGTH+1];  // +1 because of \0
  char studentFirstName[MAX_NAME_LENGTH+1];  // +1 because of \0
  char studentLastName[MAX_NAME_LENGTH+1];  // +1 because of \0
  char inputLine[LINE_LENGTH+1]; //  +1 because of \0
  char sectionString[MAX_SECT_LENGTH+1]; //  +1 because of \0
  
  int count = 0;
  
  // try to read first line from input file
  
  
  userInputFile.getline(inputLine,LINE_LENGTH); 
  
  while (!userInputFile.eof())  // will stop at end of file, or at CTRL/D
    {
      count ++;
      // convert username into URL and print it out
      
      // parse comma separated fields using strtok
      
      parseInputLine(inputLine,username,studentFirstName,studentLastName,
		     sectionString);

      cout << "Student: " << studentFirstName  << " " << studentLastName<< " Userid: " << username 
	   << " Section: " << sectionString << endl;      

      outf << "<tr>\n";
      outputUdelLinkCell(outf, username, "", username); 
      outputUdelLinkCell(outf, username, "/cisc181", "cisc181"); 
      outputUdelLinkCell(outf, username, "/cisc181/lab08", "lab08"); 
      outputUdelLinkCell(outf, username, "/cisc181/proj1", "proj1"); 
      outf << "<td>" << studentFirstName << " " << studentLastName<< "</td>" 
	   << "<td>" << sectionString << "</td></tr>\n" << endl;


      // get the next line of input

      userInputFile.getline(inputLine,LINE_LENGTH); 
    }


  outputHTMLTrailer(outf);

  // a parting thought

  cout << "\nThere were " << count << " lines in this file\n" << endl;

  return 0;
} 


