/*
* Copyright (C) 2013 FooProject
* * 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 .
*/
using System;
using System.Text;
using System.Text.RegularExpressions;
using Slusser.Collections.Generic;
namespace FooEditEngine
{
struct TextRange
{
public int start;
public int length;
public TextRange(int start, int length)
{
this.start = start;
this.length = length;
}
}
sealed class ReplaceCommand : ICommand
{
StringBuffer Buffer;
TextRange ReplacementRange, ReplacedRange;
GapBuffer replacement, replaced; //置き換え後の文字列、置き換え前の文字列
public ReplaceCommand(StringBuffer buf, int start, int length, string str)
{
this.Buffer = buf;
this.ReplacementRange = new TextRange(start,str.Length);
this.replacement = new GapBuffer();
this.replacement.AddRange(Util.GetEnumrator(str),str.Length);
this.ReplacedRange = new TextRange(start,length);
this.replaced = new GapBuffer();
this.replaced.AddRange(this.Buffer.GetEnumerator(start, length));
}
#region ICommand メンバー
public void undo()
{
this.Buffer.Replace(this.ReplacementRange.start, this.replacement.Count,this.replaced,this.replaced.Count);
}
public void redo()
{
this.Buffer.Replace(this.ReplacedRange.start, this.replaced.Count, this.replacement, this.replacement.Count);
}
public bool marge(ICommand a)
{
ReplaceCommand cmd = a as ReplaceCommand;
if (cmd == null)
return false;
if (this.ReplacedRange.length == 0 &&
cmd.ReplacementRange.start >= this.ReplacementRange.start &&
cmd.ReplacementRange.start + cmd.ReplacementRange.length <= this.ReplacementRange.start + this.ReplacementRange.length)
{
int bufferIndex = cmd.ReplacedRange.start - this.ReplacementRange.start;
this.replacement.RemoveRange(bufferIndex, cmd.ReplacedRange.length);
this.replacement.InsertRange(bufferIndex, cmd.replacement, cmd.replacement.Count);
return true;
}
if (this.ReplacedRange.start + this.ReplacementRange.length == cmd.ReplacedRange.start &&
this.ReplacedRange.start == this.ReplacementRange.start)
{
this.replaced.AddRange(cmd.replaced,cmd.replaced.Count);
this.replacement.AddRange(cmd.replacement,cmd.replacement.Count);
this.ReplacedRange.length += cmd.ReplacedRange.length;
this.ReplacementRange.length += cmd.ReplacementRange.length;
return true;
}
return false;
}
public bool isempty()
{
return this.replaced.Count == 0 && this.replacement.Count == 0;
}
#endregion
}
sealed class ReplaceAllCommand : ICommand
{
StringBuffer buffer;
Regex regex;
StringBuffer oldBuffer;
string replacePattern;
bool groupReplace;
public ReplaceAllCommand(StringBuffer buffer, Regex regex, string replacePattern,bool groupReplace)
{
this.buffer = buffer;
this.regex = regex;
this.replacePattern = replacePattern;
this.groupReplace = groupReplace;
}
public void undo()
{
this.buffer.Clear();
this.buffer.Replace(0, 0, this.oldBuffer,this.oldBuffer.Length);
}
public void redo()
{
this.oldBuffer = new StringBuffer(this.buffer);
GapBuffer result = new GapBuffer();
foreach (string line in this.buffer.GetLines(0, this.buffer.Length - 1))
{
string output = this.regex.Replace(line, (m) =>{
if (this.groupReplace)
return m.Result(this.replacePattern);
else
return this.replacePattern;
});
result.AddRange(Util.GetEnumrator(output),output.Length);
}
this.buffer.Clear();
this.buffer.Replace(0, 0, result,result.Count);
}
public bool marge(ICommand a)
{
return false;
}
public bool isempty()
{
return false;
}
}
}