#define _LOADSAVEPROJ_C

#include "common/extern.h"
#include "common/subtasksupp.h"
#include "common/asyncio.h"

#include "loadsaveproj.h"


/// struct proj_prefs *loadprefs(char *filename, struct proj_prefs *pprefs)

struct proj_prefs *
loadpprefs (struct IFFHandle *iff, struct proj_prefs *pprefs)
{

  static LONG propc[] =         // change PropChunks if change this!!!!!
   {
     ID_URLF, ID_DOWNDIR,
     ID_URLF, ID_INDEXNAME,
     ID_URLF, ID_PRJD,
  };

  struct StoredProperty *sp;
  LONG error = 0;

  if (pprefs)
    {
      if ((StopChunk (iff, ID_URLF, ID_FORM)) == 0)
        if ((error = ParseIFF (iff, IFFPARSE_SCAN)) == 0)
          {
            if ((PropChunks (iff, propc, 3)) == 0)
              {
                if ((StopOnExit (iff, ID_URLF, ID_FORM)) == 0)
                  {
                    if (((error = ParseIFF (iff, IFFPARSE_SCAN)) == 0) || (error == IFFERR_EOC))
                      {
                        if ((sp = FindProp (iff, ID_URLF, ID_DOWNDIR)))
                          {
                            FreeVecPooled (gd.gd_pool, pprefs->strdowndir);

                            #ifndef __DEMO__

                            if ((pprefs->strdowndir = (STRPTR) AllocVecPooled (gd.gd_pool, sp->sp_Size + 1)))
                              {
                                strncpy ((STRPTR) pprefs->strdowndir, (STRPTR) sp->sp_Data, sp->sp_Size);
                                pprefs->strdowndir[sp->sp_Size] = '\0';
                              }

                            #else

                            pprefs->strdowndir = (char *) newstrcpy (gd.gd_pool, "net/");

                            #endif

                          }

                        if ((sp = FindProp (iff, ID_URLF, ID_INDEXNAME)))
                          {
                            FreeVecPooled (gd.gd_pool, pprefs->indexname);
                            #ifndef __DEMO__
                            if ((pprefs->indexname = (STRPTR) AllocVecPooled (gd.gd_pool, sp->sp_Size + 1)))
                              {
                                strncpy ((STRPTR) pprefs->indexname, (STRPTR) sp->sp_Data, sp->sp_Size);
                                pprefs->indexname[sp->sp_Size] = '\0';
                              }
                            #else

                            pprefs->indexname = (char *) newstrcpy (gd.gd_pool, "index.html");

                            #endif

                          }

                        if ((sp = FindProp (iff, ID_URLF, ID_PRJD)))
                          {
                            #ifndef __DEMO__
                            pprefs->socknum = *((ULONG *) sp->sp_Data);
                            #else
                            pprefs->socknum = 1;
                            #endif
                          }

                      }
                    else if (error != IFFERR_EOF)
                      D (printf ("File trouncated\n"));
                  }
                else
                  D (printf ("Error StopChunk\n"));
              }
            else
              D (printf ("Error in propchunks\n"));

          }
        else
          error_req (STRING (MSG_OK, "*_OK"), STRING (ERR_BADFILE, "Bad file format"));
    }
  else                          //joust skip first FORM

    {
      if ((StopChunk (iff, ID_URLF, ID_FORM)) == 0)
        if ((error = ParseIFF (iff, IFFPARSE_SCAN)) == 0)
          {
            if ((PropChunks (iff, propc, 3)) == 0)
              {
                if ((StopOnExit (iff, ID_URLF, ID_FORM)) == 0)
                  {
                    if (((error = ParseIFF (iff, IFFPARSE_SCAN)) == 0) || (error == IFFERR_EOC))
                      {
                        ;
                      }
                    else if (error != IFFERR_EOF)
                      D (printf ("File trouncated\n"));
                  }
                else
                  D (printf ("Error StopChunk\n"));
              }
            else
              D (printf ("Error in propchunks\n"));

          }
        else
          error_req (STRING (MSG_OK, "*_OK"), STRING (ERR_BADFILE, "Bad file format"));

    }




  return (pprefs);
}

///

/// "struct URLNode *loadproj2 (struct IFFHandle *iff)"

struct URLNode *
loadproj2 (struct IFFHandle *iff)
{

  static LONG propc[] =         // change PropChunks if change this!!!!!
   {
     ID_URLF, ID_URL,
     ID_URLF, ID_URLDATA,

     ID_URLF, ID_TITLE,
     ID_URLF, ID_UNAME,
     ID_URLF, ID_PASSWD,
     ID_URLF, ID_ETAG,
     ID_URLF, ID_MIMETYPE,
     ID_URLF, ID_EXTENSIONS,
     ID_URLF, ID_TYPES,
  };

  struct URLNode *nd = NULL;
  struct StoredProperty *sp;
  LONG error = 0;

  if ((StopChunk (iff, ID_URLF, ID_FORM)) == 0)
    {
      if ((error = ParseIFF (iff, IFFPARSE_SCAN)) == 0)
        {
          if ((nd = (struct URLNode *) AllocSPooled (gd.gd_pool, sizeof (struct URLNode))))
            {
              if ((PropChunks (iff, propc, 9)) == 0)
                {
                  if ((StopOnExit (iff, ID_URLF, ID_FORM)) == 0)
                    {
                      if (((error = ParseIFF (iff, IFFPARSE_SCAN)) == 0) || (error == IFFERR_EOC))
                        {
                          if ((sp = FindProp (iff, ID_URLF, ID_URL)))
                            {
                              nd->url = (STRPTR) AllocVecPooled (gd.gd_pool, sp->sp_Size + 1);
                              strncpy ((STRPTR) nd->url, (STRPTR) sp->sp_Data, sp->sp_Size);

                              nd->url[sp->sp_Size] = '\0';

                              if ((sp = FindProp (iff, ID_URLF, ID_URLDATA)))
                                {
                                  memcpy (&nd->flags, sp->sp_Data, sizeof (struct URLData));

                                  // settings datas

                                  if (nd->size < 1000)
                                    sprintf (nd->buf_size, "%ld", nd->size);
                                  else if (nd->size < 1000000)
                                    sprintf (nd->buf_size, "%ld Kb", nd->size / 1000);
                                  else if (nd->size < 1000000000)
                                    sprintf (nd->buf_size, "%ld Mb", nd->size / 1000000);
                                  else
                                    sprintf (nd->buf_size, "n.a.");

                                  {
                                    struct DateTime dt;
                                    memcpy (&dt.dat_Stamp, &nd->date, sizeof (struct DateStamp));

                                    dt.dat_Format = FORMAT_DOS;
                                    dt.dat_Flags = DTF_SUBST;
                                    dt.dat_StrDay = NULL;
                                    dt.dat_StrTime = NULL;
                                    dt.dat_StrDate = nd->buf_date;

                                    if (!DateToStr (&dt))
                                      nd->buf_date[0] = '\0';
                                  }


                                  //


                                  if ((sp = FindProp (iff, ID_URLF, ID_TITLE)))
                                    {
                                      nd->title = (STRPTR) AllocVecPooled (gd.gd_pool, sp->sp_Size + 1);
                                      strncpy ((STRPTR) nd->title, (STRPTR) sp->sp_Data, sp->sp_Size);
                                      nd->title[sp->sp_Size] = '\0';
                                    }
                                  else
                                    nd->title = NULL;


                                  if ((sp = FindProp (iff, ID_URLF, ID_UNAME)))
                                    {
                                      nd->name = (STRPTR) AllocVecPooled (gd.gd_pool, sp->sp_Size + 1);
                                      strncpy (nd->name, (STRPTR) sp->sp_Data, sp->sp_Size);
                                      nd->name[sp->sp_Size] = '\0';
                                    }
                                  else
                                    nd->name = NULL;


                                  if ((sp = FindProp (iff, ID_URLF, ID_PASSWD)))
                                    {
                                      nd->password = (STRPTR) AllocVecPooled (gd.gd_pool, sp->sp_Size + 1);
                                      strncpy (nd->password, (STRPTR) sp->sp_Data, sp->sp_Size);
                                      nd->password[sp->sp_Size] = '\0';
                                    }
                                  else
                                    nd->password = NULL;

                                  if ((sp = FindProp (iff, ID_URLF, ID_ETAG)))
                                    {
                                      nd->etag = (STRPTR) AllocVecPooled (gd.gd_pool, sp->sp_Size + 1);
                                      strncpy ((STRPTR) nd->etag, (STRPTR) sp->sp_Data, sp->sp_Size);
                                      nd->etag[sp->sp_Size] = '\0';
                                    }
                                  else
                                    nd->etag = NULL;

                                  if ((sp = FindProp (iff, ID_URLF, ID_MIMETYPE)))
                                    {
                                      nd->type = (STRPTR) AllocVecPooled (gd.gd_pool, sp->sp_Size + 1);
                                      strncpy ((STRPTR) nd->type, (STRPTR) sp->sp_Data, sp->sp_Size);
                                      nd->type[sp->sp_Size] = '\0';
                                    }
                                  else
                                    nd->type = NULL;

                                  if ((sp = FindProp (iff, ID_URLF, ID_EXTENSIONS)))
                                    {
                                      nd->extensions = (STRPTR) AllocVecPooled (gd.gd_pool, sp->sp_Size + 1);
                                      strncpy ((STRPTR) nd->extensions, (STRPTR) sp->sp_Data, sp->sp_Size);
                                      nd->extensions[sp->sp_Size] = '\0';
                                    }
                                  else
                                    nd->extensions = NULL;

                                  if ((sp = FindProp (iff, ID_URLF, ID_TYPES)))
                                    {
                                      nd->types = (STRPTR) AllocVecPooled (gd.gd_pool, sp->sp_Size + 1);
                                      strncpy ((STRPTR) nd->types, (STRPTR) sp->sp_Data, sp->sp_Size);
                                      nd->types[sp->sp_Size] = '\0';
                                    }
                                  else
                                    nd->types = NULL;

                                  return (nd);

                                }       // ! nd->url

                              else
                                D (printf ("Format/load error\n"));

                              FreeSPooled (gd.gd_pool, nd->url, sizeof (struct URLNode))
                            }   // ! nnd->datas

                          else
                              D (printf ("Format/load error\n"));

                        }
                      else if (error != IFFERR_EOF)
                        error_req (STRING (MSG_OK, "*_OK"), STRING (ERR_TROUNCFILE, "File trouncated"));
                    }
                  else
                    D (printf ("Error StopChunk\n"));
                }
              else
                D (printf ("Error in propchunks\n"));

              FreeSPooled (gd.gd_pool, nd, sizeof (struct URLNode));
            }
        }
    }


  if (error != IFFERR_EOF)
    error_req (STRING (MSG_OK, "*_OK"), STRING (ERR_BADFILE, "Bad file format"));

  return (NULL);
}

///

/// "BOOL saveproj2 (struct IFFHandle * iff, struct URLNode * nd)"

__inline BOOL
writestring2 (struct IFFHandle * iff, STRPTR str, ULONG type1, ULONG type)
{
  ULONG size = s_strlen (str);

  if (size)
    if ((PushChunk (iff, type1, type, size)) == 0)
      {
        if ((WriteChunkBytes (iff, str, size)) > -1)
          {
            PopChunk (iff);
            return (TRUE);
          }
      }

  return (FALSE);
}

BOOL
saveproj2 (struct IFFHandle * iff, struct URLNode * nd)
{

  if ((PushChunk (iff, ID_URLF, ID_FORM, IFFSIZE_UNKNOWN)) == 0)
    {
      writestring2 (iff, nd->url, ID_URLF, ID_URL);

      if ((PushChunk (iff, ID_URLF, ID_URLDATA, sizeof (struct URLData))) == 0)
        {
          if ((WriteChunkBytes (iff, &nd->flags, sizeof (struct URLData))) > 0)
            {
              PopChunk (iff);
            }
        }

      writestring2 (iff, nd->title, ID_URLF, ID_TITLE);
      writestring2 (iff, nd->name, ID_URLF, ID_UNAME);
      writestring2 (iff, nd->password, ID_URLF, ID_PASSWD);
      writestring2 (iff, nd->type, ID_URLF, ID_MIMETYPE);
      writestring2 (iff, nd->etag, ID_URLF, ID_ETAG);
      writestring2 (iff, nd->extensions, ID_URLF, ID_EXTENSIONS);
      writestring2 (iff, nd->types, ID_URLF, ID_TYPES);

      PopChunk (iff);           // PushChunk (iff, ID_URLF, ID_FORM, IFFSIZE_UNKNOWN)

      return (TRUE);
    }

  return (FALSE);
}

///

/// "BOOL *savepprefs (struct IFFHandle * iff, struct proj_prefs *pprefs)"
BOOL
savepprefs (struct IFFHandle * iff, struct proj_prefs * pprefs)
{
  if ((PushChunk (iff, ID_URLF, ID_FORM, IFFSIZE_UNKNOWN)) == 0)
    {
      writestring2 (iff, pprefs->strdowndir, ID_URLF, ID_DOWNDIR);
      writestring2 (iff, pprefs->indexname, ID_URLF, ID_INDEXNAME);

      if ((PushChunk (iff, ID_URLF, ID_PRJD, sizeof (ULONG))) == 0)
        {
          if ((WriteChunkBytes (iff, &pprefs->socknum, sizeof (ULONG))) > 0)
            {
              PopChunk (iff);
              PopChunk (iff);

              return (TRUE);
            }
          PopChunk (iff);
        }
      PopChunk (iff);
    }

  return (FALSE);
}

///

/// "statrread/startwrite"

struct IFFHandle *
startwrite (char *filename, struct proj_prefs *pprefs)
{
  struct IFFHandle *iff;

  if ((iff = AllocIFF ()))
    {
      if ((iff->iff_Stream = Open (filename, MODE_NEWFILE)))
        {
          InitIFFasDOS (iff);

          if ((OpenIFF (iff, IFFF_WRITE)) == 0)
            {
              if (PushChunk (iff, ID_URLF, ID_LIST, IFFSIZE_UNKNOWN) == 0)
                {

                  if (savepprefs (iff, pprefs))
                    {

                      return (iff);
                    }
                }
            }

          Close (iff->iff_Stream);
        }
      FreeIFF (iff);
    }

  return (NULL);
}

struct IFFHandle *
startread (char *filename, struct proj_prefs *pprefs)
{
  struct IFFHandle *iff;
  ULONG error = 0;

  if ((iff = AllocIFF ()))
    {
      if ((iff->iff_Stream = Open (filename, MODE_READWRITE)))
        {
          InitIFFasDOS (iff);

          if ((OpenIFF (iff, IFFF_READ)) == 0)
            {

              if (((StopChunk (iff, ID_URLF, ID_LIST)) == 0))
                {
                  if ((ParseIFF (iff, IFFPARSE_SCAN)) == 0)
                    {
                      loadpprefs (iff, pprefs);

                      return (iff);
                    }
                }

              if (error != IFFERR_EOF)
                error_req (STRING (MSG_OK, "*_OK"), STRING (ERR_BADFILE, "Bad file format"));

              CloseIFF (iff);
            }

          Close (iff->iff_Stream);
        }
      FreeIFF (iff);
    }

  return (NULL);
}

void
endfile (struct IFFHandle *iff)
{

  //POP CAT ID
  PopChunk (iff);

  // Free Resources
  CloseIFF (iff);
  Close (iff->iff_Stream);
  FreeIFF (iff);
}
///
