#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <windows.h>
#include <tchar.h>
#include "zip.h"
#include "st.h"
#include "file.h"

using namespace std;
using namespace io_tools;

class ZipCommand {
public:
   void compress(HZIP hz, const string & file1) {
      list< string > theq;
      string file0;
      theq.push_back(file1);
      while(theq.size()) {
         file0 =  theq.front();
         theq.pop_front();
         if(file0 != "." && file0 != "..") {
            File::dir_vector_type file_vec;
            File file(file0);
            if(file.exists()) {
               if(file.is_directory()) {
                  if(file.dir(file_vec)) {
                     for(int i = 0; i < file_vec.size(); i++) {
                        if(file_vec[i].name() != "." && file_vec[i].name() != "..") {
                           //compress(hz, file0 + "\\" + file_vec[i].name());
                           theq.push_back(file0 + "\\" + file_vec[i].name());
                        }
                     }     
                  }
               }
               else {
                  cout << "zip: " << file0 << endl;
                  ZipAdd(hz, file0.c_str(), file0.c_str());
               }
            }
         }
      }
   }

   int run(int argc, char ** argv) {
      string filename;
      vector< string > file_vec; 
      int i;

      if(argc < 3) 
         throw "usage: zip -r <out-file> <input_files>";

      for(i = 1; i < argc; i++) {
         if(strcmp(argv[i], "-r") == 0) {
            i++;
            if(i < argc) {
               filename = argv[i];
            }
         }
         else {
            file_vec.push_back(argv[i]);
         }
      }

      HZIP hz = CreateZip(filename.c_str(),0);

      if(hz == NULL)
         throw "unable to open zip file...";

      cout << "create: " << filename << endl;

      for(i = 0; i < file_vec.size(); i++) {
         compress(hz, file_vec[i]);
      }

      CloseZip(hz);

      cout << "done..." << endl;

      return 0;
   }
};

#ifdef NO_MAIN
extern "C" {
extern int zip_main(int argc, char ** argv);
}
int zip_main(int argc, char ** argv)
#else
int main(int argc, char ** argv)
#endif
{
   int rc = 0;
   try {
      ZipCommand command;
      rc = command.run(argc,argv); 
   }
   catch(const char * message) {
      cout << message << endl;
      rc = 1;
   }
   catch(...) {
      cout << "exception..." << endl;
      rc = 1;
   }
   return rc;
}
