/*
** NAME: TestMLDev
** AUTHOR: Mike Veroukis
*/

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/io.h>
#include <devices/serial.h>
#include <utility/tagitem.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>

#include <stdio.h>
#include <string.h>

#include <ModemLink/ModemLink.h>
#include <proto/ModemLink.h>
#include "devicestuff.h"

struct Library *ModemLinkBase;

void main(int argc, char **argv)
{
  struct IOExtLink *LinkWriteIO, *LinkReadIO;
  struct IOExtSer *SerIO;
  struct MsgPort *LinkWriteMP, *LinkReadMP, *SerMP;
  char buf[512];
  int Connect, BusyCount = 0;

  printf("Test ModemLink Device -- Let's hope this thing works!!!\n");

  if (argc < 3) {
    if (LinkWriteMP = CreateMsgPort()) {
      if (LinkWriteIO = CreateIORequest(LinkWriteMP, sizeof(struct IOExtLink))) {
        if (!(Connect = OpenDevice(MODEMLINKNAME, 0L, (struct IORequest *)LinkWriteIO, 0L))) {
          ModemLinkBase = (struct Library *)LinkWriteIO->IOLink.io_Device;

          if (OpenSerialDevice(&SerMP, &SerIO, "serial.device", 0L)) {

            if (argc == 2)
              do {
                if (BusyCount)
                  Delay(150);
                Connect = ML_DialTags(SerIO, argv[1], TAG_DONE);
                printf("Dialer ReturnCode: %d\n", Connect);
              } while (Connect == MODEM_BUSY && BusyCount++ < 2);
            else
              Connect = ML_AnswerTagList(SerIO, NULL);

            printf("Modem ReturnCode: %d\n", Connect);

            if (Connect == MODEM_CONNECT) {
              Connect = ML_EstablishTags(LinkWriteIO, SerIO, TAG_DONE);

              printf("Establish ReturnCode: %d\n", Connect);

              if (Connect == EstErr_OK) {
                printf("Connected!!!\n\n");
                printf("Type message and hit return to send\n");
                printf("Hit return to check for incomming messages\n");
                printf("Enter '.' and hit return on a blank line to quit\n\n");

                if (CloneIO((struct IORequest *)LinkWriteIO, &LinkReadMP, (struct IORequest **)&LinkReadIO)) {
                  LinkReadIO->IOLink.io_Command = CMD_READ;
                  LinkReadIO->IOLink.io_Data = 0;
                  SendIO((struct IORequest *)LinkReadIO);

                  while (1) {
                    printf("\n: ");
                    gets(buf);
                    if (buf[0] == '.' && buf[1] == 0)
                      break;

                    if (buf[0] > ' ') {
                      printf("Sending: [%s]\n", buf);

                      LinkWriteIO->IOLink.io_Command = CMD_WRITE;
                      LinkWriteIO->IOLink.io_Data = &buf;
                      LinkWriteIO->IOLink.io_Length = strlen(buf) + 1;
                      DoIO((struct IORequest *)LinkWriteIO);
                    }

                    if (CheckIO((struct IORequest *)LinkReadIO)) {
                      WaitIO((struct IORequest *)LinkReadIO);
                      DisplayBeep(NULL);

                      if (!LinkReadIO->IOLink.io_Error) {
                        printf(">> [%s]\n", LinkReadIO->IOLink.io_Data);

                        FreeMem(LinkReadIO->IOLink.io_Data, LinkReadIO->IOLink.io_Length);

                        LinkReadIO->IOLink.io_Command = CMD_READ;
                        LinkReadIO->IOLink.io_Data = 0;
                        SendIO((struct IORequest *)LinkReadIO);
                      }
                      else
                        printf("io_Error: %X\n", LinkReadIO->IOLink.io_Error);
                    }

                    LinkWriteIO->IOLink.io_Command = MLCMD_QUERY;
                    DoIO((struct IORequest *)LinkWriteIO);
                    if (LinkWriteIO->IOLink.io_Error)
                      break;
                  }

                  if (!LinkReadIO->IOLink.io_Error) {
                    AbortIO((struct IORequest *)LinkReadIO);
                    if (!CheckIO((struct IORequest *)LinkReadIO))
                      WaitIO((struct IORequest *)LinkReadIO);
                  }

                  DeleteIO_MP(LinkReadMP, (struct IORequest *)LinkReadIO);
                }

                ML_Terminate(LinkWriteIO);
              }
            }

            SafeCloseDevice(SerMP, (struct IORequest *)SerIO);
          }

          CloseDevice((struct IORequest *)LinkWriteIO);
        }
        else
          printf("ERROR: Could not open modemlink.device\n");

        DeleteIORequest((struct IORequest *) LinkWriteIO);
      }

      DeleteMsgPort(LinkWriteMP);
    }
  }
  else
    printf("\nUSAGE: TestMLDev <PhoneNumber>\n");
}
