using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using VBASync.Localization;
namespace VBASync.Model
{
public enum ChangeType
{
AddFile = 0,
MoveFile = 1,
DeleteFile = 2,
AddSub = 3,
DeleteSub = 4,
AddLines = 5,
ChangeLines = 6,
DeleteLines = 7,
ReplaceId = 8,
ChangeFormControls = 9,
DeleteFrx = 10,
ChangeFileType = 11,
WholeFile = 12,
MoveSub = 13,
Project = 14,
Licenses = 15
}
public enum ModuleType
{
Standard = 0,
StaticClass = 1,
Class = 2,
Form = 3,
Ini = 4,
Licenses = 5
}
internal struct Chunk
{
public int NewStartLine { get; set; }
public string NewText { get; set; }
public int OldStartLine { get; set; }
public string OldText { get; set; }
}
internal struct SideBySideArgs
{
public string Name { get; set; }
public string NewText { get; set; }
public ModuleType NewType { get; set; }
public string OldText { get; set; }
public ModuleType OldType { get; set; }
}
public class Patch
{
private readonly List<Chunk> _chunks;
private bool _commit;
private Patch(ModuleType moduleType, string moduleName, ChangeType changeType,
string description = "", bool commit = true, IEnumerable<Chunk> chunks = null,
string sideBySideNewText = "")
{
ModuleType = moduleType;
ModuleName = moduleName;
ChangeType = changeType;
Description = description;
Commit = commit;
_chunks = chunks?.ToList() ?? new List<Chunk>();
SideBySideNewText = sideBySideNewText;
}
public event EventHandler<PropertyChangedEventArgs> CommitChanged;
public ChangeType ChangeType { get; }
public bool Commit
{
get { return _commit; }
set
{
_commit = value;
CommitChanged?.Invoke(null, new PropertyChangedEventArgs(nameof(Commit)));
}
}
public string Description { get; }
public string ModuleName { get; }
public ModuleType ModuleType { get; }
internal string SideBySideNewText { get; }
internal static IEnumerable<Patch> CompareSideBySide(SideBySideArgs args)
{
var lineDiff = CountStringLines(args.NewText) - CountStringLines(args.OldText);
var patches = new List<Patch>();
if (args.OldType == args.NewType)
{
patches.Add(new Patch(args.NewType, args.Name, ChangeType.WholeFile,
string.Format(VBASyncResources.CDWholeFile, lineDiff.ToString("+#;-#;—")),
chunks: new[] { new Chunk { OldStartLine = 1, NewStartLine = 1, OldText = args.OldText, NewText = args.NewText } },
sideBySideNewText: args.NewText));
}
else
{
patches.Add(new Patch(args.NewType, args.Name, ChangeType.ChangeFileType,
string.Format(VBASyncResources.CDChangeFileType, GetModuleTypeName(args.OldType), GetModuleTypeName(args.NewType), lineDiff.ToString("+#;-#;—")),
chunks: new[] { new Chunk { OldStartLine = 1, NewStartLine = 1, OldText = args.OldText, NewText = args.NewText } },
sideBySideNewText: args.NewText));
}
return patches;
}
internal static Patch MakeDeletion(string name, ModuleType type, string module)
=> new Patch(type, name, ChangeType.DeleteFile,
chunks: new[] { new Chunk { OldStartLine = 1, NewStartLine = 1, OldText = module } });
internal static Patch MakeFrxChange(string name) => new Patch(ModuleType.Form, name, ChangeType.ChangeFormControls);
internal static Patch MakeFrxDeletion(string name) => new Patch(ModuleType.Form, name, ChangeType.DeleteFrx);
internal static Patch MakeInsertion(string name, ModuleType type, string module)
=> new Patch(type, name, ChangeType.AddFile,
chunks: new[] { new Chunk { OldStartLine = 1, NewStartLine = 1, NewText = module } });
internal static Patch MakeLicensesChange(byte[] oldBytes, byte[] newBytes)
{
if (oldBytes.SequenceEqual(newBytes))
{
return null;
}
else
{
return new Patch(ModuleType.Licenses, "LicenseKeys", ChangeType.Licenses);
}
}
internal static Patch MakeProjectChange(string oldText, string newText)
{
if (oldText == newText)
{
return null;
}
else
{
var lineDiff = CountStringLines(newText) - CountStringLines(oldText);
return new Patch(ModuleType.Ini, "Project", ChangeType.Project,
string.Format(VBASyncResources.CDWholeFile, lineDiff.ToString("+#;-#;—")));
}
}
private static int CountStringLines(string s)
{
return string.IsNullOrEmpty(s) ? 0 : s.Length - s.Replace("\r", "").Length;
}
private static string GetModuleTypeName(ModuleType mt)
{
switch (mt)
{
case ModuleType.Standard:
return VBASyncResources.MTStandard;
case ModuleType.StaticClass:
return VBASyncResources.MTStaticClass;
case ModuleType.Class:
return VBASyncResources.MTClass;
case ModuleType.Form:
return VBASyncResources.MTForm;
case ModuleType.Ini:
return VBASyncResources.MTIni;
default:
return null;
}
}
}
}