#include <windows.h>
#include <iostream>
#include <stdio.h>

#include "..\..\..\..\pilot_nt.h"
#include "..\..\..\..\deprtmnt.h"
#include "..\..\..\..\cardtype.h"
#include "..\..\..\..\errors.h"

#ifndef WINCE  
  #define DDL_NAME "pilot_nt.dll"
#else
  #define DDL_NAME L"pilot_nt.dll"
#endif




extern HMODULE LoadPilotNt(const char* name, const char** nameOfTheUncknownFunction);
extern void    FreePilotNt(HMODULE dll);


void WaitAnyKey(void)
{
  std::cout<<"Press any key dor continue,,,"<<std::endl;
  getchar();
  std::cout<<std::endl;
}


#ifndef WINCE
int main (int argc, char** argv)
#else
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
#endif
{
  //HMODULE dll = LoadLibrary(DDL_NAME);
  const char* nameOfTheUncknownFunction=NULL;
  HMODULE dll = LoadPilotNt(DDL_NAME, &nameOfTheUncknownFunction);
  if (!dll) 
  {
    if (!nameOfTheUncknownFunction)
    {
      std::cerr << "pilot_nt.dll not found";
      return -1;
    }
    else
    {
      std::cerr << "function " << nameOfTheUncknownFunction << " in " << DDL_NAME << " not found";
      return -2;
    }    
  }

  CONTEXT_PTR ctx=NULL;

  try {   

    //read card context
    std::cout << "Lets make authorization and complition.\nFirst step - call card_authorize15 for authorization.\nSecond step - call ctxGetBinary for read encrypted data" << std::endl;
    std::cout << "Thrid step - call card_authorize15 with Encrypted data for make complition." << std::endl;

    //read card and pay
    auth_answer14 argument;
    DWORD amount = 90000;


    //allocate context
    ctx=ctxAlloc();

    
    memset(&argument,0,sizeof(argument));
    argument.ans.TType = OP_PREAUTH;
    argument.ans.Amount = amount;


    DWORD result = card_authorize15(NULL, &argument, NULL, 0, ctx);
      
    std::cout << "Operation completed with code '" << result << "'!" << std::endl;
    char buf[MAX_ENCR_DATA*2+1];
    int getErr=ctxGetString(ctx, PAR_ENCRYPTED_DATA, buf, sizeof(buf));
    

    unsigned char bin_buf[MAX_ENCR_DATA];
    int out_sz;
    ctxGetBinary(ctx, PAR_ENCRYPTED_DATA, bin_buf, &out_sz, sizeof(bin_buf));
    ctxFree(ctx);
    ctx=NULL;


    //we need RRN for complition and card type? for skip manual card type selection
    char rrn[MAX_REFNUM];
    strncpy(rrn, argument.RRN, sizeof(rrn));
    rrn[sizeof(rrn)-1]=0;
    int CType = argument.ans.CType;

    if (getErr==ERR_OK)
      std::cout << "Encrypted data =  '" << buf << "'" << std::endl;

    std::cout << "RRN =  '" << rrn << "'" << std::endl;
    std::cout << "CType =  '" << CType << "'" << std::endl;

    if (argument.ans.Check)
      ::GlobalFree(argument.ans.Check);



    WaitAnyKey();
    
    std::cout << "Run complition..." << std::endl;
    
    memset(&argument,0,sizeof(argument));
    argument.ans.TType = OP_COMPLETION;
    argument.ans.Amount = (amount-10000);
    argument.ans.CType = CType;
    strncpy(argument.RRN, rrn, sizeof(argument.RRN));
    argument.RRN[sizeof(argument.RRN)-1]=0;

    //allocate context
    ctx=ctxAlloc();
    ctxSetBinary(ctx, PAR_ENCRYPTED_DATA, bin_buf, sizeof(bin_buf));

    //us encrypted data from output context from previos call. Put it as dataIn argument. 
    result = card_authorize15(NULL, &argument, NULL, ctx, 0);
      
    std::cout << "Operation completed with code '" << result << "'!" << std::endl;    

    if (argument.ans.Check)
      ::GlobalFree(argument.ans.Check);

  }
  catch(...)
  {

  }

  ctxFree(ctx);

  FreePilotNt(dll);
  return 0;
}

