/*--------------------------------------------------------------
   POPFILE.C -- Fonctions du menu Fichier de l’éditeur de textes
  --------------------------------------------------------------*/

#include "x/version.h"
#include "x/scolplugin.h"


#include <commdlg.h>
#include <stdlib.h>
#include <stdio.h>
#include <process.h>



#include "objstr.h"

#include "popfile.h"

int OBJTYPDIAL;
int OBJTYPFILE;
/* reflexes type DIALOG */
#define RFLDIAL_NB      1
#define RFLDIAL_END     0

int WM_OPENFILENAME;
int WM_SAVEFILENAME;
int WM_MBOX;

/* reflexes type FILE */
#define RFLFILE_NB      0


static OPENFILENAME ofn ;

OFNArg * GArg=NULL;
MBOXArg * BArg=NULL;

void ThreadOpenFileName (PVOID pvoid);
void ThreadSaveFileName (PVOID pvoid);
void ThreadMessageBox (PVOID pvoid);

void PopFileInitialize (HWND hwnd)
{
  static char szFilter[] = "Fichiers texte (*.TXT)\0*.txt\0"  \
                          "Fichiers ASCII (*.ASC)\0*.asc\0" \
                          "Tous les fichiers (*.*)\0*.*\0\0" ;

  ofn.lStructSize       = sizeof (OPENFILENAME) ;
  ofn.hwndOwner         = hwnd ;
  ofn.hInstance         = NULL ;
  ofn.lpstrFilter       = szFilter ;
  ofn.lpstrCustomFilter = NULL ;
  ofn.nMaxCustFilter    = 0 ;
  ofn.nFilterIndex      = 0 ;
  ofn.lpstrFile         = NULL ; // défini dans les fonctions Ouvrir et Fermer
  ofn.nMaxFile          = _MAX_PATH ;
  ofn.lpstrFileTitle    = NULL ; // défini dans les fonctions Ouvrir et Fermer
  ofn.nMaxFileTitle     = _MAX_FNAME + _MAX_EXT ;
  ofn.lpstrInitialDir   = NULL ;
  ofn.lpstrTitle        = NULL ;
  ofn.Flags             = 0 ; // défini dans les fonctions Ouvrir et Fermer
  ofn.nFileOffset       = 0 ;
  ofn.nFileExtension    = 0 ;
  ofn.lpstrDefExt       = "txt" ;
  ofn.lCustData         = 0L ;
  ofn.lpfnHook          = NULL ;
  ofn.lpTemplateName    = NULL ;
}

BOOL PopFileOpenDlg (HWND hwnd, PSTR pstrFileName, PSTR pstrTitleName)
{
  ofn.hwndOwner         = hwnd ;
  ofn.lpstrFile         = pstrFileName ;
  ofn.lpstrFileTitle    = pstrTitleName ;
  ofn.Flags             = OFN_HIDEREADONLY | OFN_CREATEPROMPT ;

  return GetOpenFileName (&ofn) ;
}

BOOL PopFileSaveDlg (HWND hwnd, PSTR pstrFileName, PSTR pstrTitleName)
{
  ofn.hwndOwner         = hwnd ;
  ofn.lpstrFile         = pstrFileName ;
  ofn.lpstrFileTitle    = pstrTitleName ;
  ofn.Flags             = OFN_OVERWRITEPROMPT ;

  return GetSaveFileName (&ofn) ;
}

int DLGslashtoback(char *p)
{
	while(*p)
	{
		if ((*p)=='/') *p='\\';
		p++;
	}
	return 0;
}

int DLDialog=1;

/* fun [Chn ObjWin S S S] Dialog */
int DLGOpenFile2 (mmachine m,int multi)
{
  const char nilstring[]="\0";
  const char deffilter[]="All Files (*.*)\0*.*\0\0";
  char *filename;
  char *szFilter;
  char *Defaultdir;

  int filter;
  int defaultdir;
  int defaultfname;
  int win;
  PtrObjVoid p;
  OFNArg * Mofn;

  ofn.Flags= OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_EXPLORER;
  if (multi) ofn.Flags|=OFN_ALLOWMULTISELECT;

  filter=MMpull(m)>>1;
  defaultfname=MMpull(m)>>1;
  defaultdir=MMpull(m)>>1;
  win=MMpull(m)>>1;
  
  if (MMget(m,0)==NIL) return 0;

  if (filter!=NIL)
  {
    szFilter=(char*)malloc(MMsizestr(m,filter)+1);
    if (szFilter==NULL) 
    {
	  MMset(m,0,NIL);
      return 0;
    }
    memcpy(szFilter,MMstartstr(m,filter),MMsizestr(m,filter)+1);
  }
  else
  {
    szFilter=(char*)malloc(24);
    if (szFilter==NULL) 
    {
	  MMset(m,0,NIL);
      return 0;
    }
    memcpy(szFilter,deffilter,24);
  }


  filename=(char*)malloc(_MAX_PATH+1);
  if (filename==NULL) 
  {
    free(szFilter);
    MMset(m,0,NIL);
    return 0;
  }
  filename[0]=0;
  filename[_MAX_PATH]=0;
  
  if ((defaultfname!=NIL)&&(MMsizestr(m,defaultfname)<_MAX_PATH))
	  memcpy(filename,MMstartstr(m,defaultfname),MMsizestr(m,defaultfname)+1);

  if ((packdir)SCgetExtra("FirstPack")==NULL) Defaultdir=NULL;
  else
  {
	  if (defaultdir==NIL)
		Defaultdir=(char*)malloc(strlen(((packdir)SCgetExtra("FirstPack"))->path)+1);
	  else
		Defaultdir=(char*)malloc(strlen(((packdir)SCgetExtra("FirstPack"))->path)+1+MMsizestr(m,defaultdir));
	  if (Defaultdir==NULL)
	  {
		  free(szFilter);
          free(filename);
	      MMset(m,0,NIL);
          return 0;
      }
	  if (defaultdir==NIL)
		  sprintf(Defaultdir,"%s",((packdir)SCgetExtra("FirstPack"))->path);
	  else
		  sprintf(Defaultdir,"%s%s",((packdir)SCgetExtra("FirstPack"))->path,MMstartstr(m,defaultdir));
	  DLGslashtoback(Defaultdir);
  }

  if (win==NIL) ofn.hwndOwner=NULL;
  else
  {
	  p=(PtrObjVoid)MMstart(m,win);
	  ofn.hwndOwner=((PtrObjWindow)MMstart(m,p->Buffer>>1))->WHandler;
  }

  ofn.lStructSize       = sizeof (OPENFILENAME) ;
//  ofn.hwndOwner         = NULL ;
  ofn.hInstance         = NULL ;
  ofn.lpstrFilter       = szFilter ;
  ofn.lpstrCustomFilter = NULL ;
  ofn.nMaxCustFilter    = 0 ;
  ofn.nFilterIndex      = 0 ;
  ofn.lpstrFile         = filename ; 
  ofn.nMaxFile          = _MAX_PATH ;
  ofn.lpstrFileTitle    = NULL ; 
  ofn.nMaxFileTitle     = _MAX_FNAME + _MAX_EXT ;
  ofn.lpstrInitialDir   = Defaultdir ;
  ofn.lpstrTitle        = NULL ;
  ofn.nFileOffset       = 0 ;
  ofn.nFileExtension    = 0 ;
  ofn.lpstrDefExt       = NULL ;
  ofn.lCustData         = 0L ;
  ofn.lpfnHook          = NULL ;
  ofn.lpTemplateName    = NULL ;

  Mofn=(OFNArg *)malloc(sizeof (OFNArg));
  if (Mofn==NULL)
  {
    free(szFilter);
    free(filename);
    free(Defaultdir);
    MMset(m,0,NIL);
    return 0;
  }

  memcpy(&(Mofn->ofn),&ofn,sizeof (OPENFILENAME));
//  Mofn->hwnd=hscol;
  Mofn->id=DLDialog;
  Mofn->err=FALSE;

  if (_beginthread (ThreadOpenFileName,0,Mofn)==-1)
  {
	  MMset(m,0,NIL);
      return 0;
  }
  if (MMpush(m,DLDialog*2)) return MERRMEM;

  DLDialog++;
  return OBJcreate(m,OBJTYPDIAL,DLDialog-1,OBJTYPWINDOW,(int)Mofn->hwnd);
}

int DLGOpenFile (mmachine m)
{
	return DLGOpenFile2(m,0);
}

int DLGOpenFileMulti (mmachine m)
{
	return DLGOpenFile2(m,1);
}

void ThreadOpenFileName (PVOID pvoid)
{
  OFNArg * Mofn;

  Mofn=(OFNArg*)pvoid;

  if (Mofn==NULL) 
  {
    Mofn->err=-1;
    PostMessage ((HWND)SCgetExtra("hscol"),WM_OPENFILENAME,(WPARAM)Mofn->id,(LPARAM)Mofn);
    _endthread();
    return;
  }

  if (!GetOpenFileName (&(Mofn->ofn)))
  {
    Mofn->err=-1;
  }

  PostMessage ((HWND)SCgetExtra("hscol"),WM_OPENFILENAME,(WPARAM)Mofn->id,(LPARAM)Mofn);

  _endthread();
}
 

int DLGGetOpenFileName (mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{ 
	OFNArg * Mofn=(OFNArg*)param;
  int k,i,i0,j,n;
  char buf[_MAX_PATH];

  if (Mofn==NULL) return 0;

  k=OBJbeginreflex(m,OBJTYPDIAL,id,RFLDIAL_END);
  if (k==0)
	{
// 		MMechostr(MSKDEBUG,"dialog %d %d %s\n",id,Mofn->err,Mofn->ofn.lpstrFile);
		if (Mofn->err==0)
		{
			if ((Mofn->ofn.Flags&OFN_ALLOWMULTISELECT)==OFN_ALLOWMULTISELECT)
			{
				i=Mofn->ofn.nFileOffset;
				i0=i-1;
				memcpy(buf,Mofn->ofn.lpstrFile,i0);
				sprintf(buf+i0,"\\%s",Mofn->ofn.lpstrFile+i);
				MMechostr(MSKDEBUG,"file :%s\n",buf);
				if (Mpushstrbloc(m,buf)) return MERRMEM;
				n=1;
				j=i+strlen(Mofn->ofn.lpstrFile+i)+1;
				while((Mofn->ofn.lpstrFile[i-1]==0)&&(Mofn->ofn.lpstrFile[j]))
				{
					i=j;
					sprintf(buf+i0,"\\%s",Mofn->ofn.lpstrFile+i);
					MMechostr(MSKDEBUG,"file :%s\n",buf);
					if (Mpushstrbloc(m,buf)) return MERRMEM;
					n++;
					j=i+strlen(Mofn->ofn.lpstrFile+i)+1;
				}
				if (MMpush(m,NIL)) return MERRMEM;
				for(i=0;i<n;i++)
				{
					if (MMpush(m,2*2)) return MERRMEM;
					if (k=MBdeftab(m)) return k;
				}
			}
			else if (Mpushstrbloc(m,Mofn->ofn.lpstrFile)) return MERRMEM;
		}
		else if (MMpush(m,NIL)) return MERRMEM;
		if (k=OBJcallreflex(m,1)) return k;
	}
  if(Mofn->ofn.lpstrFile) free((void*)Mofn->ofn.lpstrFile);
  if(Mofn->ofn.lpstrFilter) free((void*)Mofn->ofn.lpstrFilter);
  if(Mofn->ofn.lpstrInitialDir) free((void*)Mofn->ofn.lpstrInitialDir);
  free((void*)Mofn);
  OBJdelTH(m,OBJTYPDIAL,id);
  return 0;
}


/* fun [Chn ObjWin S S S] Dialog */
int DLGSaveFile (mmachine m)
{
  const char nilstring[]="\0";
  const char deffilter[]="All Files (*.*)\0*.*\0\0";
  char *filename;
  char *szFilter;
  char *Defaultdir;

  int filter;
  int defaultdir;
  int defaultfname;
  int win;
  PtrObjVoid p;
  OFNArg * Mofn;

  ofn.Flags             = OFN_HIDEREADONLY | OFN_CREATEPROMPT | OFN_EXPLORER;

  filter=MMpull(m)>>1;
  defaultfname=MMpull(m)>>1;
  defaultdir=MMpull(m)>>1;
  win=MMpull(m)>>1;
  
  if (MMget(m,0)==NIL) return 0;

  if (filter!=NIL)
  {
    szFilter=(char*)malloc(MMsizestr(m,filter)+1);
    if (szFilter==NULL) 
    {
	  MMset(m,0,NIL);
      return 0;
    }
    memcpy(szFilter,MMstartstr(m,filter),MMsizestr(m,filter)+1);
  }
  else
  {
    szFilter=(char*)malloc(24);
    if (szFilter==NULL) 
    {
	  MMset(m,0,NIL);
      return 0;
    }
    memcpy(szFilter,deffilter,24);
  }


  filename=(char*)malloc(_MAX_PATH+1);
  if (filename==NULL) 
  {
    free(szFilter);
    MMset(m,0,NIL);
    return 0;
  }
  filename[0]=0;
  filename[_MAX_PATH]=0;
  
  if ((defaultfname!=NIL)&&(MMsizestr(m,defaultfname)<_MAX_PATH))
	  memcpy(filename,MMstartstr(m,defaultfname),MMsizestr(m,defaultfname)+1);

  if (((packdir)SCgetExtra("FirstPack"))==NULL) Defaultdir=NULL;
  else
  {
	  if (defaultdir==NIL)
		Defaultdir=(char*)malloc(strlen(((packdir)SCgetExtra("FirstPack"))->path)+1);
	  else
		Defaultdir=(char*)malloc(strlen(((packdir)SCgetExtra("FirstPack"))->path)+1+MMsizestr(m,defaultdir));
	  if (Defaultdir==NULL)
	  {
		  free(szFilter);
          free(filename);
	      MMset(m,0,NIL);
          return 0;
      }
	  if (defaultdir==NIL)
		  sprintf(Defaultdir,"%s",((packdir)SCgetExtra("FirstPack"))->path);
	  else
		  sprintf(Defaultdir,"%s%s",((packdir)SCgetExtra("FirstPack"))->path,MMstartstr(m,defaultdir));
	  DLGslashtoback(Defaultdir);
  }

  if (win==NIL) ofn.hwndOwner=NULL;
  else
  {
	  p=(PtrObjVoid)MMstart(m,win);
	  ofn.hwndOwner=((PtrObjWindow)MMstart(m,p->Buffer>>1))->WHandler;
  }
  ofn.lStructSize       = sizeof (OPENFILENAME) ;
//  ofn.hwndOwner         = NULL ;
  ofn.hInstance         = NULL ;
  ofn.lpstrFilter       = szFilter ;
  ofn.lpstrCustomFilter = NULL ;
  ofn.nMaxCustFilter    = 0 ;
  ofn.nFilterIndex      = 0 ;
  ofn.lpstrFile         = filename ; 
  ofn.nMaxFile          = _MAX_PATH ;
  ofn.lpstrFileTitle    = NULL ; 
  ofn.nMaxFileTitle     = _MAX_FNAME + _MAX_EXT ;
  ofn.lpstrInitialDir   = Defaultdir ;
  ofn.lpstrTitle        = NULL ;
  ofn.nFileOffset       = 0 ;
  ofn.nFileExtension    = 0 ;
  ofn.lpstrDefExt       = NULL ;
  ofn.lCustData         = 0L ;
  ofn.lpfnHook          = NULL ;
  ofn.lpTemplateName    = NULL ;

  Mofn=(OFNArg *)malloc(sizeof (OFNArg));
  if (Mofn==NULL)
  {
    free(szFilter);
    free(filename);
    free(Defaultdir);
    MMset(m,0,NIL);
    return 0;
  }

  memcpy(&(Mofn->ofn),&ofn,sizeof (OPENFILENAME));
//  Mofn->hwnd=hscol;
  Mofn->id=DLDialog;
  Mofn->err=0;
  
  if (_beginthread (ThreadSaveFileName,0,Mofn)==-1)
  {
	  MMset(m,0,NIL);
	  return 0;
  }
  if (MMpush(m,DLDialog*2)) return MERRMEM;

  DLDialog++;
  return OBJcreate(m,OBJTYPDIAL,DLDialog-1,OBJTYPWINDOW,(int)Mofn->hwnd);
}

void ThreadSaveFileName (PVOID pvoid)
{
  OFNArg * Mofn;

  Mofn=(OFNArg*)pvoid;

  if (Mofn==NULL) 
  {
    Mofn->err=-1;
    PostMessage ((HWND)SCgetExtra("hscol"),WM_SAVEFILENAME,(WPARAM)Mofn->id,(LPARAM)Mofn);
    _endthread();
    return;
  }

  if (!GetSaveFileName (&(Mofn->ofn)))
  {
    Mofn->err=-1;
  }

  PostMessage ((HWND)SCgetExtra("hscol"),WM_SAVEFILENAME,(WPARAM)Mofn->id,(LPARAM)Mofn);

  _endthread();
}
 
int DLGGetSaveFileName (mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{ 
	OFNArg * Mofn=(OFNArg*)param;
  int k;

  if (Mofn==NULL) return 0;

  k=OBJbeginreflex(m,OBJTYPDIAL,id,RFLDIAL_END);
  if (k==0)
	{
// 		MMechostr(MSKDEBUG,"dialog %d\n",id);
		if (Mofn->err==0)
		{
			if (Mpushstrbloc(m,Mofn->ofn.lpstrFile)) return MERRMEM;
		}
		else if (MMpush(m,NIL)) return MERRMEM;
		if (k=OBJcallreflex(m,1)) return k;
	}

  if(Mofn->ofn.lpstrFile) free((void*)Mofn->ofn.lpstrFile);
  if(Mofn->ofn.lpstrFilter) free((void*)Mofn->ofn.lpstrFilter);
  if(Mofn->ofn.lpstrInitialDir) free((void*)Mofn->ofn.lpstrInitialDir);
  free((void*)Mofn);
  OBJdelTH(m,OBJTYPDIAL,id);
  return 0;
}


////////////////////////////////////////////////////////////////
/* fun [Chn ObjWin S S I] Dialog */
int DLGMessageBox (mmachine m)
{
  int i;
  int title;
  int string;
  MBOXArg *pmbox;
  MBOXArg mbox;
  int win;
  PtrObjVoid p;

  mbox.id=DLDialog;
  i=MMpull(m)>>1;
  if (i==1) mbox.flags= MB_OKCANCEL;
  else if (i==2) mbox.flags= MB_YESNO;
  else mbox.flags= MB_OK;
  string=MMpull(m)>>1;
  title=MMpull(m)>>1;
  win=MMpull(m)>>1;

  if (MMget(m,0)==NIL) return 0;

  if (title==NIL)
  {
    MMset(m,0,NIL);
    return 0;
  }

  else
  {
    mbox.title=(char*)malloc(MMsizestr(m,title)+1);
    if (mbox.title==NULL) 
	{
		MMset(m,0,NIL);
        return 0;
    }
    memcpy(mbox.title,MMstartstr(m,title),MMsizestr(m,title));
    mbox.title[MMsizestr(m,title)]=0;
  }
  
  if (string!=NIL)
  {
    mbox.string=(char*)malloc(MMsizestr(m,string)+1);
    if (mbox.string==NULL) 
    { 
      free(mbox.title);
      MMset(m,0,NIL);
      return 0;
    }
    memcpy(mbox.string,MMstartstr(m,string),MMsizestr(m,string));
    mbox.string[MMsizestr(m,string)]=0;
  }
  else
  {
    free(mbox.title);
	MMset(m,0,NIL);
    return 0;
  }

  if (win==NIL) mbox.hwnd=NULL;
  else
  {
	  p=(PtrObjVoid)MMstart(m,win);
	  mbox.hwnd=((PtrObjWindow)MMstart(m,p->Buffer>>1))->WHandler;
  }
  mbox.err=0;
  pmbox=(MBOXArg *)malloc(sizeof (MBOXArg));
  if (pmbox==NULL)
  {
    MMset(m,0,NIL);
    return 0;
  }
  memcpy(pmbox,&mbox,sizeof(MBOXArg));

  if (_beginthread (ThreadMessageBox,0,pmbox)==-1)
  {
	  MMset(m,0,NIL);
	  return 0;
  }
  if (MMpush(m,DLDialog*2)) return MERRMEM;

  DLDialog++;
  return OBJcreate(m,OBJTYPDIAL,DLDialog-1,OBJTYPWINDOW,(int)mbox.hwnd);
}


void ThreadMessageBox (PVOID pvoid)
{
  MBOXArg * pmbox;

  pmbox=(MBOXArg*)pvoid;

  if (pmbox==NULL)
  {
    pmbox->err=-1;
    PostMessage ((HWND)SCgetExtra("hscol"),WM_MBOX,(WPARAM)pmbox->id,(LPARAM)pmbox);
    _endthread();
    return;
  }
  if (pmbox->hwnd) SetForegroundWindow(pmbox->hwnd);
  if (strlen(pmbox->string)>1023) pmbox->string[1023]=0;
  if (strlen(pmbox->title)>255) pmbox->title[255]=0;

  pmbox->err=MessageBox(pmbox->hwnd,pmbox->string,pmbox->title,pmbox->flags);
  if (pmbox->err==6) pmbox->err=1;
  if (pmbox->err==7) pmbox->err=0;
  if (pmbox->err==2) pmbox->err=0;

  PostMessage ((HWND)SCgetExtra("hscol"),WM_MBOX,(WPARAM)pmbox->id,(LPARAM)pmbox);

  _endthread();
}
 

int DLGGetMessageBox (mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{ 
	MBOXArg * pmbox=(MBOXArg*)param;
  int k;

  if (pmbox==NULL) return 0;

  k=OBJbeginreflex(m,OBJTYPDIAL,id,RFLDIAL_END);
  if (k==0)
	{
// 		MMechostr(MSKDEBUG,"dialog %d\n",id);
		if (MMpush(m,pmbox->err<<1)) return MERRMEM;
		if (k=OBJcallreflex(m,1)) return k;
	}

  if(pmbox->title) free(pmbox->title);
  if(pmbox->string) free(pmbox->string);
  free(pmbox);
  OBJdelTH(m,OBJTYPDIAL,id);
  return 0;
}

int DLGrfldialog(mmachine m)
{
	return OBJaddreflex(m,OBJTYPDIAL,RFLDIAL_END);
}


/**************************************************************************/

/* File fun [Chn channel P filename] */
int FILEOpen(mmachine m)
{
  int s;
  int filename;
  HANDLE f;

  filename=MMpull(m);

  if ((MMget(m,0)==NIL)||(filename==NIL))
  {
	  MMset(m,0,NIL);
	  return 0;
  }
  
  f=CreateFile(MMstartstr(m,filename>>1),GENERIC_READ,FILE_SHARE_READ,NULL,
	  OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  MMechostr(MSKDEBUG,"\nOpening the file %s : %d\n\n",
	  MMstartstr(m,filename>>1),f);
  if (f==INVALID_HANDLE_VALUE)
  {
	  MMset(m,0,NIL);
	  return 0;
  }

  s=MMmalloc(m,2,TYPEBUF); if (s==NIL) return MERRMEM;
  *(HANDLE*)MMstart(m,s)=f;
  if (MMpush(m,s+s+1)) return MERRMEM;

  return OBJcreate(m,OBJTYPFILE,(int)f,-1,0);
}

int FILEdelete2(mmachine m,int handsys,int objm)
{
	HANDLE f;
    if (objm==NIL) return 0;
    f=*(HANDLE*)MMstart(m,objm>>1);
    CloseHandle(f);
    *(HANDLE*)MMstart(m,objm>>1)=NULL;
    return 0;
}

int FILEClose (mmachine m)
{
  int p;
  HANDLE file;

  p=MMget(m,0)>>1;
  if (p==NIL) return 0;
  file=*(HANDLE*)MMstart(m,p);

  MMset(m,0,NIL);
  if (file==NULL) return 0;
  OBJdelTH(m,OBJTYPFILE,(int)file);
  MMset(m,0,0);
  return 0;
}

/* I fun [File f, I pos, I from] */
int FILESeek (mmachine m)
{
  int p;
  HANDLE file;
  int pos;
  int from;
  int res;

  from=MMpull(m)>>1;
  pos=MMpull(m)>>1;
  p=MMget(m,0)>>1;
  if (p==NIL) return 0;
  file=*(HANDLE*)MMstart(m,p);

  MMset(m,0,NIL);
  if (file==NULL) return 0;
  if (from==0) from=FILE_BEGIN;
  else if (from==1) from=FILE_CURRENT;
  else from=FILE_END;

  res=SetFilePointer(file,pos,NULL,from);
  MMset(m,0,res<<1);

  return 0;
}

int FILETell (mmachine m)
{
  int p;
  HANDLE file;
  int res;

  p=MMget(m,0)>>1;
  if (p==NIL) return 0;
  file=*(HANDLE*)MMstart(m,p);

  MMset(m,0,NIL);
  if (file==NULL) return 0;
  res=SetFilePointer(file,0,NULL,FILE_CURRENT);
  MMset(m,0,res<<1);

  return 0;
}

int FILESize (mmachine m)
{
  int p;
  HANDLE file;
  int temp;
  int res;

  p=MMget(m,0)>>1;
  if (p==NIL) return 0;
  file=*(HANDLE*)MMstart(m,p);

  MMset(m,0,NIL);
  if (file==NULL) return 0;
  temp=SetFilePointer(file,0,NULL,FILE_CURRENT);
  SetFilePointer(file,0,NULL,FILE_END);
  res=SetFilePointer(file,0,NULL,FILE_CURRENT);
  SetFilePointer(file,temp,NULL,FILE_BEGIN);
  MMset(m,0,res<<1);

  return 0;
}


/* S fun [File f,I size] */
int FILERead (mmachine m)
{
  int p;
  HANDLE file;
  int s;
  int size;
  int res;

  size=MMpull(m)>>1;
  p=MMget(m,0)>>1;
  if (p==NIL) return 0;
  file=*(HANDLE*)MMstart(m,p);

  MMset(m,0,NIL);

  if (size<0) return 0;
  if (file==NULL) return 0;

  s=MMmalloc(m,((size+5)>>2)+1,TYPEBUF);
  if (s==NIL) return MERRMEM;
  ReadFile(file,MMstartstr(m,s),size,&res,NULL);
  MMstore(m,s,0,res);
  ((char*)MMstartstr(m,s))[size]=0;
  MMset(m,0,(s<<1)|1);

  return 0;
}

int GetFileNameFromP (mmachine m)
{
  int filename;
  int len;
  int rlen;
  char * S;
  char buf[256];

  filename=MMpull(m)>>1;

  if (filename==NIL) 
  {
    MMpush(m,NIL);
    return 0;
  }

  rlen=MMsizestr(m,filename);
  len=rlen;
  S=MMstartstr(m,filename);

  while ((len>=0) && (S[len]!='/') && (S[len]!='\\')) len--; 
  strcpy(buf,S+len+1);
  return Mpushstrbloc(m,buf);
}

int PtoScol(mmachine m)
{ 
  packdir p;
  int q,i,l,k;
  char *s;
  char buf[1024];
  char file[1024];

  q=MMpull(m)>>1;
  if (q==NIL) return MMpush(m,NIL);
  s=MMstartstr(m,q);
  l=strlen(s);
  if (l>=1023) return MMpush(m,NIL);

  strcpy(file,s);

  for(i=0;i<l;i++) if (file[i]=='\\') file[i]='/';
  else if ((file[i]>='a')&&(file[i]<='z')) file[i]+='A'-'a';

  p=((packdir)SCgetExtra("FirstPack"));
  while(p)
    {
	  strcpy(buf,p->path);
	  k=strlen(buf);
      for(i=0;i<k;i++) if (buf[i]=='\\') buf[i]='/';
      else if ((buf[i]>='a')&&(buf[i]<='z')) buf[i]+='A'-'a';
	  if (!strncmp(buf,file,k))
	  {
		  strcpy(file,s);
          for(i=0;i<l;i++) if (file[i]=='\\') file[i]='/';
		  return Mpushstrbloc(m,file+k);
	  }
      p=p->next;
	}
  return MMpush(m,NIL);
}


#define NDLGPKG 22
char* dlgname[NDLGPKG]=
  {"OpenBox",
   "OpenBoxMulti",
   "SaveBox",
   "MessageBox",
   "_DLGOpenFile",
   "_DLGOpenFileMulti",
   "_DLGSaveFile",
   "_DLGMessageBox",
   "_DLGrflopen",
   "_DLGrflopenMulti",
   "_DLGrflsave",
   "_DLGrflmessage",
   "_FILEOpen"  ,
   "_FILEClose" ,
   "_FILESeek"  ,
   "_FILETell"  ,
   "_FILESize"  ,
   "_FILERead"  ,
   "_GetFileNameFromP",
   "_GetFileNameFromW",
   "_PtoScol",
   "File"};
int (*dlgfun[NDLGPKG])(mmachine m)=
  {NULL,
   NULL,
   NULL,
   NULL,
   DLGOpenFile,
   DLGOpenFileMulti,
   DLGSaveFile,
   DLGMessageBox,
   DLGrfldialog,
   DLGrfldialog,
   DLGrfldialog,
   DLGrfldialog,
   FILEOpen  ,
   FILEClose ,
   FILESeek  ,
   FILETell  ,
   FILESize  ,
   FILERead,
   GetFileNameFromP,
   GetFileNameFromP,
   PtoScol,
   NULL  };
int dlgnarg[NDLGPKG]=
  {TYPTYPE,TYPTYPE,TYPTYPE,TYPTYPE,
   5,5,5,5,
   3,3,3,3,
   2,1,3,1,
   1,2,1,1,
   1,TYPTYPE};
char * dlgtype[NDLGPKG]=
  {NULL,
   NULL,
   NULL,
   NULL,
   "fun [Chn ObjWin S S S] OpenBox",
   "fun [Chn ObjWin S S S] OpenBoxMulti",
   "fun [Chn ObjWin S S S] SaveBox",
   "fun [Chn ObjWin S S I] MessageBox",
   "fun [OpenBox fun [OpenBox u0 P] u1 u0] OpenBox",
   "fun [OpenBoxMulti fun [OpenBoxMulti u0 [P r1]] u1 u0] OpenBoxMulti",
   "fun [SaveBox fun [SaveBox u0 W] u1 u0] SaveBox",
   "fun [MessageBox fun [MessageBox u0 I] u1 u0] MessageBox",

   "fun [Chn P] File",
   "fun [File] I",
   "fun [File I I] I",
   "fun [File] I",
   "fun [File] I",
   "fun [File I] S",
   "fun [P] S",
   "fun [W] S",
   "fun [P] S",
   NULL};

int SCOLloadDialog(mmachine m)
{
	OBJTYPDIAL=OBJregister(RFLDIAL_NB,0,NULL,"OBJTYPDIAL");
	WM_OPENFILENAME=OBJgetUserEvent();
	WM_SAVEFILENAME=OBJgetUserEvent();
	WM_MBOX=OBJgetUserEvent();
	OBJdefEvent(WM_MBOX,DLGGetMessageBox);
	OBJdefEvent(WM_OPENFILENAME,DLGGetOpenFileName);
	OBJdefEvent(WM_SAVEFILENAME,DLGGetSaveFileName);

	OBJTYPFILE=OBJregister(RFLFILE_NB,0,FILEdelete2,"OBJTYPFILE");

	return PKhardpak(m,"DLG.pkg",NDLGPKG,dlgname,dlgfun
                ,dlgnarg,dlgtype);
}
