/*
* 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.Linq;
using System.Collections.Generic;
namespace FooEditEngine
{
///
/// 既定のIDリスト
///
public static class MarkerIDs
{
///
/// デフォルトIDを表す
///
public static int Defalut = 0;
///
/// URLを表す
///
public static int URL = 1;
///
/// IMEの変換候補を表す
///
public static int IME = -1;
}
///
/// マーカーのタイプを表す列挙体
///
public enum HilightType
{
///
/// マーカーとして表示しないことを表す
///
None,
///
/// 選択状態を表す
///
Select,
///
/// URLを表す
///
Url,
///
/// 実線を表す
///
Sold,
///
/// 破線を表す
///
Dash,
///
/// 一点鎖線を表す
///
DashDot,
///
/// 二点鎖線を表す
///
DashDotDot,
///
/// 点線を表す
///
Dot,
///
/// 波線を表す
///
Squiggle,
}
///
/// マーカー自身を表します
///
public struct Marker : IRange, IEqualityComparer
{
#region IRange メンバー
///
/// 開始位置
///
public int start
{
get;
set;
}
///
/// 長さ
///
public int length
{
get;
set;
}
#endregion
///
/// マーカーのタイプ
///
public HilightType hilight;
///
/// 色を指定する
///
public Color color;
///
/// 線を太くするかどうか
///
public bool isBoldLine;
///
/// マーカーを作成します
///
/// 開始インデックス
/// 長さ
/// タイプ
/// マーカー
public static Marker Create(int start, int length, HilightType hilight)
{
return new Marker { start = start, length = length, hilight = hilight, color = new Color(), isBoldLine = false};
}
///
/// マーカーを作成します
///
/// 開始インデックス
/// 長さ
/// タイプ
/// 色
/// 線を太くするかどうか
/// マーカー
public static Marker Create(int start, int length, HilightType hilight,Color color,bool isBoldLine = false)
{
return new Marker { start = start, length = length, hilight = hilight ,color = color , isBoldLine = isBoldLine };
}
///
/// 等しいかどうかを調べます
///
/// 比較されるマーカー
/// 比較するマーカー
/// 等しいなら真。そうでなければ偽
public bool Equals(Marker x, Marker y)
{
return x.hilight == y.hilight && x.length == y.length && x.start == y.start;
}
///
/// ハッシュを得ます
///
/// マーカー
/// ハッシュ
public int GetHashCode(Marker obj)
{
return this.start ^ this.length ^ (int)this.hilight;
}
}
///
/// マーカークラスのコレクションを表します
///
public sealed class MarkerCollection
{
Dictionary> collection = new Dictionary>();
internal MarkerCollection()
{
this.Updated +=new EventHandler((s,e)=>{});
}
///
/// 更新されたことを通知します
///
public event EventHandler Updated;
internal void Add(int id,Marker m)
{
this.AddImpl(id, m);
this.Updated(this, null);
}
void AddImpl(int id, Marker m)
{
RangeCollection markers;
if (this.collection.TryGetValue(id, out markers))
{
markers.Remove(m.start, m.length);
markers.Add(m);
}
else
{
markers = new RangeCollection();
markers.Add(m);
this.collection.Add(id, markers);
}
}
internal void AddRange(int id, IEnumerable collection)
{
foreach (Marker m in collection)
this.AddImpl(id, m);
this.Updated(this, null);
}
internal void RemoveAll(int id)
{
RangeCollection markers;
if (this.collection.TryGetValue(id, out markers))
{
markers.Clear();
}
this.Updated(this, null);
}
internal void RemoveAll(int id,int start, int length)
{
RangeCollection markers;
if (this.collection.TryGetValue(id, out markers))
{
markers.Remove(start, length);
}
this.Updated(this, null);
}
internal void RemoveAll(int id, HilightType type)
{
RangeCollection markers;
if (this.collection.TryGetValue(id, out markers))
{
for (int i = 0; i < markers.Count; i++)
{
if (markers[i].hilight == type)
markers.RemoveAt(i);
}
}
this.Updated(this, null);
}
internal IEnumerable IDs
{
get
{
return this.collection.Keys;
}
}
internal IEnumerable Get(int id)
{
RangeCollection markers;
if (this.collection.TryGetValue(id, out markers))
{
foreach (var m in markers)
yield return m;
}
yield break;
}
internal IEnumerable Get(int id, int index)
{
RangeCollection markers;
if (this.collection.TryGetValue(id, out markers))
{
foreach (var m in markers.Get(index))
yield return m;
}
yield break;
}
internal IEnumerable Get(int id, int index, int length)
{
RangeCollection markers;
if (this.collection.TryGetValue(id, out markers))
{
foreach (var m in markers.Get(index, length))
yield return m;
}
yield break;
}
///
/// マーカーをすべて削除します
///
/// マーカーID
public void Clear(int id)
{
RangeCollection markers;
if (this.collection.TryGetValue(id, out markers))
markers.Clear();
this.Updated(this, null);
}
///
/// マーカーをすべて削除します
///
public void Clear()
{
this.collection.Clear();
this.Updated(this, null);
}
internal void UpdateMarkers(int startIndex,int insertLength,int removeLength)
{
int deltaLength = insertLength - removeLength;
foreach (RangeCollection markers in this.collection.Values)
{
for (int i = 0; i < markers.Count; i++)
{
Marker m = markers[i];
if (m.start + m.length - 1 < startIndex)
{
continue;
}
else
{
m.start += deltaLength;
}
markers[i] = m;
}
}
}
}
}