// Copyright (C) Stichting Deltares 2020. All rights reserved.
//
// This file is part of the Layer On Slope Tool.
//
// The Layer On Slope Tool is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
using System.IO;
using Deltares.LayerOnSlopeTool.Data;
using Deltares.LayerOnSlopeTool.Importer;
using Deltares.LayerOnSlopeTool.StiFileCreator;
namespace Deltares.LayerOnSlopeTool.LayerCreator
{
///
public class LayerCreator
{
private List locations = new List();
private List surfaceLines = new List();
private List errors = new List();
private bool errorFound;
private string fullLogFilePath;
public const string LogFile = "LayerOnSlopeTool.log";
/// Initializes a new instance of the class.
/// Name of the input folder.
/// Name of the geometries folder.
/// Name of the output folder.
public LayerCreator(string inputFolderName, string geometriesFolderName, string outputFolderName)
{
InputFolderName = inputFolderName;
GeometriesFolderName = geometriesFolderName;
OutputFolderName = outputFolderName;
fullLogFilePath = Path.Combine(OutputFolderName, LogFile);
}
/// Gets the name of the output folder.
/// The name of the output folder.
public string OutputFolderName { get; }
/// Gets the name of the geometries folder.
/// The name of the geometries folder.
public string GeometriesFolderName { get;}
/// Gets the name of the input folder.
/// The name of the input folder.
public string InputFolderName { get; }
///
/// Executes this instance.
///
public void Execute()
{
PrepareOutputFolder();
errorFound = false;
locations = ReadLocations(InputFolderName);
if (locations != null && locations.Count > 0)
{
surfaceLines = ReadSurfaceLines(InputFolderName);
if (surfaceLines != null && surfaceLines.Count > 0)
{
ProcessLocations();
}
}
if (errorFound)
{
throw new Exception(String.Format("Error(s) found, see log file {0}.", fullLogFilePath));
}
}
private void ProcessLocations()
{
errors.Clear();
var loggedLocations = new List();
foreach (var location in locations)
{
loggedLocations.Clear();
loggedLocations.Add(string.Format("Handling location {0} with surface line {1}", location.LocationId, location.SurfacelineId));
WriteToLog(loggedLocations);
SurfaceLine surfaceLine = FindSurfaceLine(location.SurfacelineId);
var loweredSurfaceLine = DetermineSurfaceLineForGivenLayerData(surfaceLine, location.LayerThickness);
try
{
Execute(true, loweredSurfaceLine, location);
Execute(false, surfaceLine, location);
}
catch (Exception e)
{
errorFound = true;
errors.Add(e.Message);
}
}
if (errors.Count > 0)
{
WriteToLog(errors);
}
}
private void PrepareOutputFolder()
{
if (!Directory.Exists(OutputFolderName))
{
Directory.CreateDirectory(OutputFolderName);
}
else
{
if (File.Exists(fullLogFilePath))
{
File.Delete(fullLogFilePath);
}
}
}
private SurfaceLine FindSurfaceLine(string surfaceLineId)
{
foreach (var surfaceLine in surfaceLines)
{
if (surfaceLine.SurfaceLineId == surfaceLineId)
{
return surfaceLine;
}
}
return null;
}
private List ReadSurfaceLines(string inputFolderName)
{
errors.Clear();
if (CsvImporter.ReadSurfaceLines(inputFolderName, out surfaceLines, out errors))
{
return surfaceLines;
}
WriteToLog(errors);
errorFound = true;
return null;
}
private List ReadLocations(string inputFolderName)
{
errors.Clear();
if (CsvImporter.ReadLocations(inputFolderName, out locations, out errors))
{
return locations;
}
WriteToLog(errors);
errorFound = true;
return null;
}
private void WriteToLog(List linesToAdd)
{
File.AppendAllLines(fullLogFilePath, linesToAdd);
}
private void Execute(bool isForLoweredSurfaceLine, SurfaceLine surfaceLine, Location location)
{
// for the original surface line, use offset = 0. Use the Interim file in output folder as input file. Save as original file in output folder.
var xOffset = 0.0;
var folderName = OutputFolderName;
var inputFileName = "Interim" + location.SoilGeometryName;
var outputFileName = location.SoilGeometryName;
if (isForLoweredSurfaceLine)
{
// for the lowered surface line, use the given offset. Use the original input file from the input folder. Save as Interim file in output folder.
xOffset = location.XOffset;
folderName = InputFolderName;
inputFileName = location.SoilGeometryName;
outputFileName = "Interim" + location.SoilGeometryName;
}
var stiFileCreatorInput = new StiFileCreatorInput
{
// Note that for second generation the offset MUST be 0 as any offset is already taken care of in the first generation.
XOffset = xOffset,
SurfaceLine = surfaceLine,
DikeMaterialName = location.LayerMaterial,
InputFilename = Path.Combine(folderName, inputFileName),
OutputFilename = Path.Combine(OutputFolderName, outputFileName)
};
StiFileCreator.StiFileCreator.ProcessFile(stiFileCreatorInput);
}
private SurfaceLine DetermineSurfaceLineForGivenLayerData(SurfaceLine originalSurfaceLine, double layerThickness)
{
var surfacelineProcessor = new SurfacelineProcessor(originalSurfaceLine);
return surfacelineProcessor.CreateLoweredSurfaceLine(layerThickness);
}
}
}