//
// Copyright (C) 1999-2002 Toshikaz Hirabayashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// TOSHIKAZ HIRABAYASHI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// Except as contained in this notice, the name of Toshikaz Hirabayashi shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization from
// Toshikaz Hirabayashi.

#include <WScom.h>
#include <WSClocaleSet.h>
#include <win/WSDwinFile.h>
#include <stdio.h>
#include <fcntl.h>
//#include <WShttp.h>

WSMFclassInit(WSDwinFile,WSDfile);

WSDfile* _win_file_chandler(){
  return new WSDwinFile;
}

void WSGFinitializeWinFile(){
static long _init = 0;
  if (_init != 0){
    return;
  }
  _init = 1;
  WSDfile::setCreateInstanceHandler((void*)_win_file_chandler);
}

class _win_file_init {
  public: _win_file_init(){
    WSDfile::setCreateInstanceHandler((void*)_win_file_chandler);
  };
};
_win_file_init  _win_file_init_execute;

WSDwinFile::WSDwinFile(){
  _file = NULL;
  _mfile = NULL;
}

WSDwinFile::~WSDwinFile(){
  close();
}

long WSDwinFile::open(char* name,char* mode){
  _file_name.setString(name);
  _file_name.delHeadSpace();
#if 0 //DEVELOP...
  char* fn = _file_name.getString();
  if (!strncmp("http://",fn,7)){
    char*  pbuf = NULL;
    char*  ctype = NULL;
    long  size = 0;
    long  ishtml = 0;
    WSGFloadRemoteFile(fn,&pbuf,&ctype,&size,&ishtml,1);
    if (pbuf != NULL){
      if (_mfile == NULL){
        _mfile = new WSCmfile();
      }
      _mfile->open(pbuf,size);
      delete pbuf;
      return WS_NO_ERR;
    }
    return WS_ERR;
  }
#endif
  _file = fopen(
             _file_name.getString(WSGIappLocaleSet()->getSystemLocaleEncoding()),
             mode);
  if (_file == NULL){
    WSCstring fname2(_file_name);
    fname2.to_upper();
    _file = fopen(
             fname2.getString(WSGIappLocaleSet()->getSystemLocaleEncoding()),
             mode);
  }
  if (_file != NULL){
    return WS_NO_ERR;
  }else{
    if (!strcmp("r+",mode)){
      _file = fopen(
             _file_name.getString(WSGIappLocaleSet()->getSystemLocaleEncoding()),
             "a");
      if (_file != NULL){
        return WS_NO_ERR;
      }else{
        WSCstring fname2(_file_name);
        fname2.to_upper();
        _file = fopen(
             fname2.getString(WSGIappLocaleSet()->getSystemLocaleEncoding()),
             "a");
        if (_file != NULL){
          return WS_NO_ERR;
        }
      }
    }
    return WS_ERR;
  }
}

long WSDwinFile::close(){
  if (_file != NULL){
    fclose(_file);
    _file = NULL;
  }
  if (_mfile != NULL){
    delete _mfile;
    _mfile = NULL;
  }
  return WS_NO_ERR;
}
long WSDwinFile::read(void* buf,long len){
  if (_mfile != NULL){
    return _mfile->read(buf,len);
  }
  if (_file == NULL){
    return 0;
  }
  return fread(buf,1,len,_file);
}
long WSDwinFile::write(void* buf,long len){
  if (_mfile != NULL){
    return _mfile->write(buf,len);
  }
  if (_file == NULL){
    return 0;
  }
  return fwrite(buf,1,len,_file);
}
WSCbool WSDwinFile::eof(){
  if (_mfile != NULL){
    return _mfile->eof();
  }
  if (_file == NULL){
    return 0;
  }
  if (feof(_file) != False){
    return True;
  }
  return False;
}

long WSDwinFile::seekSet(){
  return seek(0);
}
long WSDwinFile::seekEnd(){
  if (_mfile != NULL){
    _mfile->seekEnd();
    return WS_NO_ERR;
  }
  if (_file == NULL){
    return 0;
  }
  fseek(_file,0,SEEK_END);
  return WS_NO_ERR;
}
long WSDwinFile::seek(long addr){
  if (_mfile != NULL){
    return _mfile->seek(addr);
  }
  if (_file == NULL){
WSMFtrace("WSDwinFDB::_seek error file=NULL\n");
    return 0;
  }
  fseek(_file,addr,SEEK_SET);
  return WS_NO_ERR;
}
long WSDwinFile::getSize(){
  if (_mfile != NULL){
    return _mfile->getSize();
  }
  if (_file == NULL){
WSMFtrace("WSDwinFDB::_tell error file=NULL\n");
    return 0;
  }
  long pos = ftell(_file);
  fseek(_file,0,SEEK_END);
  long ret = ftell(_file);
  fseek(_file,pos,SEEK_SET);
  return ret;
}
long WSDwinFile::tell(){
  if (_mfile != NULL){
    return _mfile->tell();
  }
  if (_file == NULL){
WSMFtrace("WSDwinFDB::_tell error file=NULL\n");
    return 0;
  }
  return ftell(_file);
}
