//*****************************************************************************
//* Copyright 2002 - 2006 by GalaSoft Laurent Bugnion
//*****************************************************************************
//* Project Name           : CExplorer
//* Target Hardware        : PC
//* Target                 : Netscape 4+, Internet explorer 4+, Mozilla
//* Language/Compiler      : JavaScript 1.2
//* Author                 : Laurent Bugnion
//*****************************************************************************
//* This is an extract of my CExplorer object, which helps me with I/O operations
//* like reading files, writing files, checking file existence, etc...
//*
//* Code is provided without guarantees. It has been tested in the following conditions:
//*
//* - Netscape 4.7 on Windows XP
//* - IE6 on Windows XP
//* - Firefox 1.5.0.4 on Windows XP
//*
//* Due to security, the user is asked by the browser and by antivirus softwares
//* to confirm the action.
//* Other platforms were not tested. Code might not work on other platforms
//* This demo only allows saving txt files.
//*
//* The reader is allowed to use this code and modify it if needed. The original code
//* is posted under www.galasoft.ch/myjavascript/CExplorer/CExplorer.extracts.txt
//*
//* A reference to www.galasoft.ch is appreciated, but not compulsory.
//*****************************************************************************

if ( !window.gslb )
{
  window.gslb = new Object();
}

//*****************************************************************************

gslb.CExplorer = function()
{
  this.m_ePlatform == gslb.CExplorer.EPlatform.eNone;
  
  if ( window )
  {
    if ( window.ActiveXObject )
    {
      this.m_ePlatform = gslb.CExplorer.EPlatform.eActiveX;
    }
    else
    {
      if ( window.Components )
      {
        this.m_ePlatform = gslb.CExplorer.EPlatform.eComponents;
      }
      else
      {
        if ( window.java )
        {
          this.m_ePlatform = gslb.CExplorer.EPlatform.eJava;
        }
      }
    }
  }

  if ( this.m_ePlatform == gslb.CExplorer.EPlatform.eNone )
  {
    throw gslb.CExplorer.ALERT002;
  }
}

//*****************************************************************************

// Define a few alerts for the code
gslb.CExplorer.ALERT001 = "The file already exists, overwrite?";
gslb.CExplorer.ALERT002 = "No suitable platform found";
gslb.CExplorer.ALERT003 = "No method found for this platform";

//*****************************************************************************

// Define an "enum" to specify which platform the application runs on
gslb.CExplorer.EPlatform = new Object();
gslb.CExplorer.EPlatform.eNone = -1;
gslb.CExplorer.EPlatform.eActiveX = 0;    // IE and other ActiveX enabled browsers
gslb.CExplorer.EPlatform.eComponents = 1; // SpiderMonkey based browsers
gslb.CExplorer.EPlatform.eJava = 2;       // Java based browsers (Netscape 4)

//*****************************************************************************

// Define containers for the platforms' methods
gslb.CExplorer.s_aafnMethods = new Array();
gslb.CExplorer.s_aafnMethods[ gslb.CExplorer.EPlatform.eActiveX ] = new Array();
gslb.CExplorer.s_aafnMethods[ gslb.CExplorer.EPlatform.eComponents ] = new Array();
gslb.CExplorer.s_aafnMethods[ gslb.CExplorer.EPlatform.eJava ] = new Array();

//*****************************************************************************

// Define an entry point for the method saveTextFile. This selects the
// appropriate method corresponding to the platform.

gslb.CExplorer.prototype.saveTextFile = function( strFullPath, strContent, bOverwrite )
{
  if ( strFullPath.toLowerCase().indexOf( ".txt" ) != strFullPath.length - ( ".txt" ).length )
  {
    alert( "This demo only allows saving files ending with the extension '.txt'" );
    return false;
  }

  var fnSaveTextFile = gslb.CExplorer.s_aafnMethods[ this.m_ePlatform ][ "saveTextFile" ];

  if ( fnSaveTextFile )
  {
    return fnSaveTextFile( strFullPath, strContent, bOverwrite );
  }

  throw gslb.CExplorer.ALERT003;
}

//*****************************************************************************

// Defines one method for each supported platform

// ActiveX --------------------------------------------------------------------

gslb.CExplorer.s_aafnMethods[ gslb.CExplorer.EPlatform.eActiveX ][ "saveTextFile" ] = function( strFullPath, strContent, bOverwrite )
{
  var fso = new ActiveXObject( "Scripting.FileSystemObject" );

  if ( bOverwrite
    || !fso.FileExists( strFullPath )
    || confirm( gslb.CExplorer.ALERT001 ) )
  {
    var flOutput = fso.CreateTextFile( strFullPath, true );
    flOutput.Write( strContent );
    flOutput.Close();
    return true;
  }
  else
  {
    return false;
  }
}

// Components (Spidermonkey, Mozilla, Firefox) --------------------------------

/// <summary>
/// First parameter of the create method.
/// <para>The type of file system object to be made.</para>
/// <para>The only two types at this time are file and directory/folder.</para>
/// </summary>
gslb.CExplorer.ECreateType = new Object();
/// <summary>
/// Create a file.
/// </summary>
gslb.CExplorer.ECreateType.eFile = 0x00;
/// <summary>
/// Create a folder.
/// </summary>
gslb.CExplorer.ECreateType.eDirectory = 0x01;

/// <summary>
/// Use this constant as second parameter of the create method.
/// <para>The unix style octal permissions. This may be ignored on
/// systems that do not need to do permissions. In general, permissions are
/// based on three octal numbers. The first specifies the access for the
/// user, the second for the group and the last for others.</para>
/// <para>0 - No permission to read, write or execute.</para>
/// <para>1 - Execute permission only.</para>
/// <para>2 - Write permission only.</para>
/// <para>3 - Execute and write permission.</para>
/// <para>4 - Read permission only.</para>
/// <para>5 - Execute and read permission.</para>
/// <para>6 - Write and read permission.</para>
/// <para>7 - Execute, write and read permission.</para>
/// </summary>
gslb.CExplorer.FILE_CREATE_WRITE_READ_READ = 0644;

/// <summary>
/// Second parameter of the init method.
/// <para>Type of opening.</para>
/// <para>It is a bitwise OR of the following bit flags
/// (only one of the first three flags below may be used):</para>
/// </summary>
gslb.CExplorer.EInitFlags = new Object();
/// <summary>
/// Open for reading only.
/// </summary>
gslb.CExplorer.EInitFlags.eOpenReadOnly = 0x01;
/// <summary>
/// Open for writing only.
/// </summary>
gslb.CExplorer.EInitFlags.eOpenWriteOnly = 0x02;
/// <summary>
/// Open for reading and writing.
/// </summary>
gslb.CExplorer.EInitFlags.eOpenReadWrite = 0x04;
/// <summary>
/// If the file does not exist, the file is created. If the file exists,
/// this flag has no effect.
/// </summary>
gslb.CExplorer.EInitFlags.eCreateBeforeWrite = 0x08;
/// <summary>
/// If set, each write will wait for both the file data and file
/// status to be physically updated.
/// </summary>
gslb.CExplorer.EInitFlags.eWaitForUpdate = 0x10;
/// <summary>
/// The file pointer is set to the end of the file prior to each write.
/// </summary>
gslb.CExplorer.EInitFlags.eAppendToFile = 0x20;
/// <summary>
/// If the file exists, its length is truncated to 0.
/// </summary>
gslb.CExplorer.EInitFlags.eTruncateToZero = 0x40;

/// <summary>
/// Use this constant as third parameter of the init method.
/// <para>The access permission bits of the file 'mode'.</para>
/// <para>CAVEAT: 'mode' is currently only applicable on UNIX platforms. The
/// 'mode' argument may be ignored on other platforms.</para>
/// <para>00400 - Read by owner.</para>
/// <para>00200 - Write by owner.</para>
/// <para>00100 - Execute (search if a directory) by owner.</para>
/// <para>00040 - Read by group.</para>
/// <para>00020 - Write by group.</para>
/// <para>00010 - Execute by group.</para>
/// <para>00004 - Read by others.</para>
/// <para>00002 - Write by others</para>
/// <para>00001 - Execute by others.</para>
/// </summary>
gslb.CExplorer.FILE_INIT_ACCESS_PERMISSION = 00004;

gslb.CExplorer.s_aafnMethods[ gslb.CExplorer.EPlatform.eComponents ][ "saveTextFile" ] = function( strFullPath, strContent, bOverwrite )
{
  try
  {
    netscape.security.PrivilegeManager.enablePrivilege( "UniversalXPConnect" );

    var flOutput = Components.classes["@mozilla.org/file/local;1"].createInstance(
      Components.interfaces.nsILocalFile );
    flOutput.initWithPath( strFullPath );

    if ( flOutput.exists() )
    {
      if ( !bOverwrite
        && !confirm( gslb.CExplorer.ALERT001 ) )
      {
        return false;
      }
      flOutput.remove( false );
    }

    flOutput.create( gslb.CExplorer.ECreateType.eFile, gslb.CExplorer.FILE_CREATE_WRITE_READ_READ );

		var fsOutput = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(
      Components.interfaces.nsIFileOutputStream );

    fsOutput.init( flOutput,
      gslb.CExplorer.EInitFlags.eOpenWriteOnly,
      gslb.CExplorer.FILE_INIT_ACCESS_PERMISSION,
      null );

    fsOutput.write( strContent, strContent.length );
    fsOutput.flush();
    fsOutput.close();
    return true;
  }
  catch ( ex )
  {
    alert( ex.toString() );
    return false;
  }
}

// Java (Netscape 4) ----------------------------------------------------------

// This code is provided for historical reasons only. However, the use of
// "try", "catch", "throw" and other advanced JavaScript programming method
// prevent the use of this demo of Netscape 4 plaftorm. This is why this code
// is commented out.

/*
gslb.CExplorer.s_aafnMethods[ gslb.CExplorer.EPlatform.eJava ][ "saveTextFile" ] = function( strFullPath, strContent, bOverwrite )
{
  var bFileExists = false;

  if ( !bOverwrite )
  {
    netscape.security.PrivilegeManager.enablePrivilege( "UniversalFileRead" );

    var flCheck = new java.io.File( strFullPath );
    bFileExists = flCheck.exists();
  }

  if ( !bFileExists
    || confirm( gslb.CExplorer.ALERT001 ) )
  {
    netscape.security.PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
    var fsOutput = new java.io.FileOutputStream( strFullPath );
    var flOutput = new java.io.DataOutputStream( fsOutput );

    flOutput.writeBytes( strContent );

    flOutput.flush();
    fsOutput.close();
    return true;
  }
}
*/