
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

typedef vector< string > args_type;

bool is_script_running()
{
   return true;
}

class wc {
   long line_count;
   long word_count;
   long char_count;
   bool count_line; 
   bool count_word;
   bool count_char;
   char* buffer;
   size_t size;
   size_t index;
public:
   wc() {
      line_count = 0L;
      word_count = 0L;
      char_count = 0L;
      count_line = false;
      count_word = false;
      count_char = false;
      buffer = new char [1];
      size = 0;
      index = 0;
   }
   ~wc() {
      delete [] buffer;
   }
   void error(const string & message) {
      cout << "error: " << message << endl;
   }
   void proc(ifstream & fin) {
      string temp;
      char ch = fin.get();
      bool in_word = false;
      int size = 0;
      while(!fin.fail() && is_script_running()) {
         if(count_line) {
            if(ch == '\n') {
               line_count++;
               size = 0;
            }
         }
         if(count_word) {
            if(!isspace(ch)) {
               if(in_word)
                  ;
               else {
                  word_count++;
                  in_word = true;
               }
            }
            else {
               in_word = false;
            }
         }
         if(count_char) {
            char_count++;
         }
         ch = fin.get();
         if(!fin.fail()) 
            size++;
      }
      if(size > 0) {
         if(count_line) {
            line_count++;
         }
      }
   }
   void proc() {
      bool in_word = false;
      char ch = cin.get();
      int size = 0;
      while(ch != EOF && is_script_running()) {
         if(count_line) {
            if(ch == '\n') {
               line_count++;
               size = 0;
            }
         }
         if(count_word) {
            if(!isspace(ch)) {
               if(in_word)
                  ;
               else {
                  word_count++;
                  in_word = true;
               }
            }
            else {
               in_word = false;
            }
         }
         if(count_char) {
            char_count++;
         }
         ch = cin.get();
         if(ch != EOF) {
            size++;
         }
      }
      if(size > 0) {
         if(count_line) {
            line_count++;
         }
      }
   }

   int run(const args_type & args) {
      string infile,outfile,temp;
      int rc = 0;
      for(int i = 0; i < args.size(); i++) {
         if(args[i] == "-l") {
            count_line = true;
         }
         else if(args[i] == "-w") {
            count_word = true;
         }
         else if(args[i] == "-c") {
            count_char = true;
         }
         else if(infile.size() == 0) {
            infile = args[i];
         }
         else if(outfile.size() == 0) {
            outfile = args[i];
         }
         else {
            error("unknown command line argument: " + args[i] + "\n");
         }
      }
      if(infile.size() == 0) {
         proc();
      }
      else {
         ifstream fin(infile.c_str(), ios::in);
         if(!fin.fail()) {
            proc(fin);
            fin.close();
         }
      }
      if(outfile.size() == 0 && is_script_running()) {
         if(count_line) {
            cout << line_count << endl;
         }
         else if(count_word) {
            cout << word_count << endl;
         }
         else if(count_char) {
            cout << char_count << endl;
         }
      }
      return rc;
   }
};


int
main(int argc, char* argv[])
{
   wc WC;
   args_type args;
   for(size_t i = 1; i < argc; i++) {
      args.push_back(argv[i]);
   }
   WC.run(args);
   return 0;
}
