context: /* 
   * Copyright 2009 Alexander Curtis <alex@logicmill.com>
   * This file is part of GEDmill - A family history website creator
   * 
   * GEDmill 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.
   *
   * GEDmill 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 GEDmill.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  using System;
  using System.Drawing;
  using System.IO;
  using GDModel;
  using GEDmill.MiniTree;
  using GEDmill.Model;
  using GKCore.Interfaces;
  using GKCore.Logging;
  
  namespace GEDmill.HTML
  {
      /// <summary>
      /// This is a single class that has the sole purpose of creating the website by creating and calling the 
      /// various other creators (individuals, sources, front page, index, css).
      /// It also copies site-wide multimedia files, javascript and CD ROM autorun loader.
      /// </summary>
      public class Website
      {
          private static readonly ILogger fLogger = LogManager.GetLogger(GMConfig.LOG_FILE, GMConfig.LOG_LEVEL, typeof(Website).Name);
  
          private readonly ILangMan fLangMan;
          private readonly string fOutputFolder;
  
          // The raw data that we are turning into a website.
          private readonly GDMTree fTree;
  
          // Pointer to the window showing the progress bar, so that web page creation progress can be shown to user.
          private readonly IProgressCallback fProgressWindow;
  
  
          public Website(GDMTree tree, IProgressCallback progress, string outputFolder, ILangMan langMan)
          {
              fTree = tree;
              fProgressWindow = progress;
              fOutputFolder = outputFolder;
              fLangMan = langMan;
          }
  
          // The heart of GEDmill is here.
          public void Create()
          {
              fLogger.WriteInfo("Website::Create()");
  
              // 1 means the process was aborted, for signalling back to calling thread. 2 means file nError.      
              ThreadError threaderror = new ThreadError(1, "No error");
  
              try {
                  // The value to indicate in the progress bar to show how much of the website creation is complete.
                  int progress = 0;
  
                  int[] gfstats = fTree.GetRecordStats();
  
                  // The maximum value of the progress bar, i.e. when website creation is fully complete.
                  int progressMax =
                      1  // Site-wide multimedia files
                    + 1  // Background image
                    + 1  // Style sheet
                    + gfstats[(int)GDMRecordType.rtIndividual]
                    + 1  // Individuals Index
                    + gfstats[(int)GDMRecordType.rtSource]
                    + 1  // Front page
                    + 1  // CD ROM (Doesn't matter here that CD ROM autorun might not be included.)
                    + 1; // Scripts (Doesn't matter here that scripts might not be included.)
  
                  // The paintbox with which to draw the mini tree
                  var paintbox = new Paintbox(GMConfig.Instance);
                  paintbox.SetBackgroundImage(GMConfig.Instance.BackgroundImage);
  
                  // Object to keep count of number of files created etc.
                  var stats = new Stats();
  
                  // Here goes....
  
                  // Start the progress indicator.
                  fProgressWindow.Begin(0, progressMax);
                  if (fProgressWindow.IsAborting) {
                      return;
                  }
                  // Copy the images to use in place of non-pic multimedia files.
                  fProgressWindow.SetText(fLangMan.LS(PLS.LSID_CopyingMultimedia));
                  CopyIcons();
                  if (fProgressWindow.IsAborting) {
                      return;
                  }
                  fProgressWindow.StepTo(++progress);
  
                  // Create the index creator for use by the individuals records creator.
                  var indiIndexCreator = new CreatorIndexIndividuals(fTree, fProgressWindow, fLangMan);
  
                  // Copy the image for the background of the webpages.
                  fProgressWindow.SetText(fLangMan.LS(PLS.LSID_CopyingBackground));
                  string backgroundImageFilename = CopyBackgroundImage();
                  if (fProgressWindow.IsAborting) {
                      return;
                  }
                  fProgressWindow.StepTo(++progress);
  
                  // Create the style sheet
                  fProgressWindow.SetText(fLangMan.LS(PLS.LSID_CreatingStyleSheet));
                  string cssFilename = string.Concat(fOutputFolder, "\\", GMConfig.StylesheetFilename);
                  if (GMConfig.StylesheetFilename.Length > 0) {
                      var csc = new CreatorStylesheet(fTree, fProgressWindow, fLangMan, cssFilename, backgroundImageFilename);
                      csc.Create();
                  }
  
                  if (fProgressWindow.IsAborting) {
                      return;
                  }
  
                  fProgressWindow.StepTo(++progress);
  
                  // Create the pages for the individual records.
                  fProgressWindow.SetText(fLangMan.LS(PLS.LSID_CreatingIndividualPages));
                  var indiList = fTree.GetRecords<GDMIndividualRecord>();
                  foreach (GDMIndividualRecord ir in indiList) {
                      var ipc = new CreatorRecordIndividual(fTree, fProgressWindow, fLangMan, ir, indiIndexCreator, paintbox);
                      if (ipc.Create(stats)) {
                          stats.Individuals++;
                      }
                      if (fProgressWindow.IsAborting) {
                          return;
                      }
  
                      fProgressWindow.StepTo(++progress);
                  }
  
                  // Create the index for the individual records pages.
                  fProgressWindow.SetText(fLangMan.LS(PLS.LSID_CreatingIndividualsIndex));
                  indiIndexCreator.Create();
                  if (fProgressWindow.IsAborting) {
                      return;
                  }
  
                  fProgressWindow.StepTo(++progress);
  
                  // Clear list of copied files, so that source images get copied afresh
                  // and so get resized differently to any indi images based on the same file.
                  Creator.ClearCopiedFilesList();
  
                  // Create the pages for the source records.
                  fProgressWindow.SetText(fLangMan.LS(PLS.LSID_CreatingSourcePages));
                  var sourList = fTree.GetRecords<GDMSourceRecord>();
                  foreach (GDMSourceRecord sr in sourList) {
                      var spc = new CreatorRecordSource(fTree, fProgressWindow, fLangMan, sr);
                      if (spc.Create(stats)) {
                          stats.Sources++;
                      }
  
                      if (fProgressWindow.IsAborting) {
                          return;
                      }
  
                      fProgressWindow.StepTo(++progress);
                  }
  
                  if (fProgressWindow.IsAborting) {
                      return;
                  }
  
                  // Create the front page
                  fProgressWindow.SetText(fLangMan.LS(PLS.LSID_CreatingFrontPage));
                  string front_page_filename = string.Concat(fOutputFolder, "\\", GMConfig.Instance.FrontPageFilename, ".html");
                  if (GMConfig.Instance.FrontPageFilename.Length > 0) {
                      CreatorFrontPage fpc = new CreatorFrontPage(fTree, fProgressWindow, fLangMan, stats);
                      fpc.Create();
                  }
                  fProgressWindow.StepTo(++progress);
                  if (fProgressWindow.IsAborting) {
                      return;
                  }
                  
                  // Copy the CD ROM autorun file
                  fProgressWindow.SetText(fLangMan.LS(PLS.LSID_CreatingCDROMFiles));
                  if (GMConfig.Instance.CreateCDROMFiles) {
                      CreateCDROMFiles();
                  }
                  if (fProgressWindow.IsAborting) {
                      return;
                  }
  
                  fProgressWindow.StepTo(++progress);
  
                  // Copy the Javascript
                  fProgressWindow.SetText(fLangMan.LS(PLS.LSID_CreatingJSFile));
                  // Currently (10Dec08) the only thing that uses javascript is the multiple images feature.
                  if (GMConfig.Instance.AllowMultipleImages) {
                      CreateJavascriptFiles();
                  }
                  if (fProgressWindow.IsAborting) {
                      return;
                  }
  
                  fProgressWindow.StepTo(++progress);
  
                  // Done
                  fLogger.WriteInfo("Website::CreateFinished");
                  fProgressWindow.SetText(fLangMan.LS(PLS.LSID_Done));
                  threaderror.Error = 0;
                  threaderror.Message = "";
              } catch (ArgumentException e) {
                  fLogger.WriteError("Caught Argument Exception : ", e);
                  threaderror.Error = 2; // 2 => abnormal abort.
                  threaderror.Message = "";
              } catch (IOException e) {
                  fLogger.WriteError("Caught IO Exception : ", e);
                  threaderror.Error = 2; // 2 => abnormal abort.
                  threaderror.Message = "";
              } catch (NullReferenceException e) {
                  fLogger.WriteError("Caught NullReference Exception : ", e);
                  threaderror.Error = 2; // 2 => abnormal abort.
                  threaderror.Message = "";
              } catch (HTMLException e) {
                  threaderror.Error = 2; // 2 => abnormal abort.
                  threaderror.Message = e.Message;
              } catch (Exception e) {
                  fLogger.WriteError("Caught Exception : ", e);
                  threaderror.Error = 2; // 2 => abnormal abort.
                  threaderror.Message = "";
              } finally {
                  fLogger.WriteInfo("Thread ending...");
  
gt:                 if (fProgressWindow != null) {