/////////////////////////////////////////////////////////////////////
// client.cpp - Midterm Questions #2 and #3                        //
//                                                                 //
// Jim Fawcett, CSE775 - Distributed Objects, Spring 2007          //
/////////////////////////////////////////////////////////////////////

#define _WIN32_WINNT 0x0501
#include <atlbase.h>
#include <atlsafe.h>
#include "../FileHandler/FileHandler.h"
#include <iostream>

void main()
{
  std::wcout << L"\n  File Handler Interface ";
  std::wcout << L"\n ========================\n";

  HRESULT hr = CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
  if(!SUCCEEDED(hr))
  {
    std::wcout << L"\n  could not initialize COM";
  }

  try
  {
    CComQIPtr<IFileHdlr> pReadFileHandler;
    pReadFileHandler.CoCreateInstance(CLSID_FileHdlr);
    CComQIPtr<IFileHdlr> pWriteFileHandler;
    pWriteFileHandler.CoCreateInstance(CLSID_FileHdlr);
    
    if(pWriteFileHandler != 0)
    {
      CComBSTR path(L"..");
      pWriteFileHandler->SetWritePath(path);
    }
    if(pReadFileHandler != 0)
    {
      CComBSTR path(L".");
      pReadFileHandler->SetReadPath(path);

      SAFEARRAY files;
      SAFEARRAY* pFiles = &files;
      pReadFileHandler->GetFiles(&pFiles);
      CComSafeArray<BSTR> Files;
      Files.Attach(pFiles);
      HRESULT hr;

      for(int i=0; i<(int)Files.GetCount(); ++i)
      {
        int len = Files[i].Length();
        if(len > 3)
        {
          OLECHAR* pStr = Files[i];
          if(wcscmp(L"cpp",pStr + len - 3) == 0)
          {
            std::wcout << "\n\n    Opening " << Files[i].Copy();
            hr = pReadFileHandler->OpenFileReader(pStr);
            if(SUCCEEDED(hr))
            {
              std::wcout << L"\n    Open successful\n\n";
              BYTE* pBuffer;
              int size;
//
              do
              {
                pReadFileHandler->GetBlock(&size, (BYTE**)&pBuffer);
                if(size > 0)
                  std::cout << (char*)pBuffer;
                CoTaskMemFree(pBuffer);
              } while (size > 0);

              pReadFileHandler->CloseFileReader(pStr);
              std::wcout << "\n";

              if(!pWriteFileHandler)
              {
                std::wcout << "\n  failed to create file writer";
                break;
              }
              CComBSTR file = L"OutFile.txt";
              std::wcout << "\n\n    Opening for Writing " << file.Copy();
              hr = pWriteFileHandler->OpenFileWriter(file);
              if(SUCCEEDED(hr))
              {
                std::wcout << L"\n    Open for Write successful";
                hr = pReadFileHandler->OpenFileReader(pStr);
                if(SUCCEEDED(hr))
                {
                  std::wcout << L"\n    Open for Read successful";
                  BYTE* pBuffer;
                  int size;
                  do
                  {
                    pReadFileHandler->GetBlock(&size, (BYTE**)&pBuffer);
                    if(size > 0)
                      pWriteFileHandler->PutBlock(size,pBuffer);
                    CoTaskMemFree(pBuffer);
                  } while (size > 0);
                }
                else
                {
                  std::wcout << L"\n    Open for read failed\n\n";
                }
                pReadFileHandler->CloseFileReader(pStr);
                pWriteFileHandler->CloseFileWriter(file.Copy());
                std::wcout << "\n    file " << file.Copy() << " written";
              }
              else
              {
                std::wcout << L"\n    open for write failed\n\n";
              }
            }
          }
        }
      }
    }
  }
  catch(std::exception& ex)
  {
    std::wcout << L"\n  " << ex.what() << L"\n\n";
    return;
  }
  std::wcout << L"\n\n";
  CoUninitialize();
}