// 
// Hiero
// Copyright (c) 2015  Barry Block 
// 
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later
// version. 
// 
// This program is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
// PARTICULAR PURPOSE.  See the GNU General Public License for more details. 
// 
// You should have received a copy of the GNU General Public License along with
// this program.  If not, see <http://www.gnu.org/licenses/>. 
//

using System;
using System.IO;
using Gtk;

namespace Hiero
{
   // Manages an outline's command log. 
   //
   // Note that the logic below distinguishes between two different types of outlines:
   // 
   //    New  
   //       A new outline is one that has not yet been saved to disk. New outlines
   //       ALWAYS have an associated log because, by definition, a new outline is
   //       one that has unsaved changes and because the log file itself is used
   //       to represent the new outline in the application's session object.
   //
   //    Open 
   //       An open outline is one that has been saved to disk. Open outlines only
   //       have a command log when there are changes made to the outline that are
   //       unsaved.
   //
   public class Log
   {
      private const string logExt = ".log~";
         // A log file's extension. Note that for the log file to be hidden
         // on most Linux systems, its name should end with a "~" (tilde).
      private string newOutlinesFolder;
         // Folder where all "new" outlines reside (as log files).
      private string path = String.Empty;
         // The file stored on disk. Is empty if no actual
         // file is associated with this log object.
      private Document Outline { get; set; }
         // The outline document instance.

      public Log(Document outline, string newOutlinesFolder)
      {
         Outline = outline;
         this.newOutlinesFolder = newOutlinesFolder;
      }
 
      // Returns true if the log is associated with a 
      // "new" outline (as opposed to an "open" one).
      public bool IsNew
      {
         get
         {
            return (Path.IndexOf(newOutlinesFolder) == 0);
         }
      }

      // Returns true if the log file exists.
      public bool Exists
      {
         get
         {
            return System.IO.File.Exists(Path);
         }
      }

      // Gets or sets the log's path.
      public string Path
      {
         get { return path; }

         set 
         { 
            path = value;
         }
      }

      // Returns the log file given its outline file (.hro).
      public static string GetLogFromPath(string path)
      {
         return System.IO.Path.Combine(System.IO.Path.GetDirectoryName(path), 
         System.IO.Path.GetFileNameWithoutExtension(path)) + logExt;
      }
      
      // Assigns a log file.
      public void Assign(string docPath)
      {
         string tempPath;
   
         if (docPath == String.Empty)
         {
            // Creating a log for a "new" outline. First, create 
            // the "new" logs folder if it doesn't already exist:
   
            if (!System.IO.Directory.Exists(newOutlinesFolder)) 
            {
               // Create the folder:
   
               System.IO.Directory.CreateDirectory(newOutlinesFolder);
            }
   
            // Generate the "new" log's file name:
   
            do
            {
               tempPath = System.IO.Path.Combine(newOutlinesFolder, 
               System.IO.Path.GetFileNameWithoutExtension(System.IO.Path.GetRandomFileName()) + logExt); 
            } 
            while (System.IO.File.Exists(tempPath));
         }
         else
         {
            // Generate the "open" log's file name:

            tempPath = GetLogFromPath(docPath);
         }
   
         Path = tempPath;
      }
      
      // Deletes the log file associated with this outline.
      public void Delete()
      {
         if (System.IO.File.Exists(Path)) 
         {
            // Delete it:

            System.IO.File.Delete(Path);
         }
      }

      // Writes the given command to the log.
      public void Write(string text)
      {
         File.AppendAllText(Path, text);
      }
   }
}

