using Server.Mobiles;
using Server.Network;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Server.Gumps
{
public abstract class BaseGump : Gump, IDisposable
{
public static int CenterLoc = 1114513; //
~1_val~
public static int AlignRightLoc = 1114514; // ~1_TOKEN~
private Gump _Parent;
public PlayerMobile User { get; }
public bool Open { get; set; }
public virtual bool CloseOnMapChange => false;
public Gump Parent
{
get { return _Parent; }
set
{
_Parent = value;
if (_Parent != null)
{
if (_Parent is BaseGump)
{
var bGump = (BaseGump)_Parent;
if (!bGump.Children.Contains(this))
{
bGump.Children.Add(this);
}
else
{
bGump.Children.Remove(this);
}
}
}
}
}
public List Children { get; set; }
public BaseGump(PlayerMobile user, int x = 50, int y = 50, BaseGump parent = null)
: base(x, y)
{
if (user == null)
return;
Children = new List();
User = user;
Parent = parent;
}
~BaseGump()
{
Dispose();
}
public static BaseGump SendGump(BaseGump gump)
{
if (gump == null)
return null;
BaseGump g = gump.User.FindGump(gump.GetType()) as BaseGump;
if (g == gump)
gump.Refresh();
else
gump.SendGump();
return gump;
}
public virtual void SendGump()
{
AddGumpLayout();
Open = true;
User.SendGump(this, false);
}
public void Dispose()
{
ColUtility.ForEach(Children.AsEnumerable(), child => Children.Remove(child));
Children = null;
Children = null;
Parent = null;
foreach (KeyValuePair kvp in _TextTooltips)
{
kvp.Value.Free();
}
foreach (KeyValuePair, Spoof> kvp in _ClilocTooltips)
{
kvp.Value.Free();
}
_ClilocTooltips.Clear();
_TextTooltips.Clear();
OnDispose();
}
public virtual void OnDispose()
{
}
public abstract void AddGumpLayout();
public virtual void Refresh(bool recompile = true, bool close = true)
{
OnBeforeRefresh();
if (User == null || User.NetState == null)
return;
if (close)
{
User.NetState.Send(new CloseGump(TypeID, 0));
User.NetState.RemoveGump(this);
}
else
{
User.NetState.RemoveGump(this);
}
if (recompile)
{
Entries.Clear();
AddGumpLayout();
}
/*Children.ForEach(child =>
{
if(child.Open)
child.Refresh(recompile, close);
});*/
User.SendGump(this);
OnAfterRefresh();
}
public void RefreshParent(bool resend = false)
{
if (Parent is BaseGump)
((BaseGump)Parent).Refresh();
if (resend)
Refresh();
}
public virtual void OnBeforeRefresh()
{
}
public virtual void OnAfterRefresh()
{
}
public virtual void OnClosed()
{
Children.ForEach(child => child.Close());
Children.Clear();
Open = false;
if (Parent != null)
{
if (Parent is BaseGump)
((BaseGump)Parent).OnChildClosed(this);
Parent = null;
}
}
public virtual void OnChildClosed(BaseGump gump)
{
}
public sealed override void OnResponse(NetState state, RelayInfo info)
{
OnResponse(info);
if (info.ButtonID == 0)
OnClosed();
}
public virtual void OnResponse(RelayInfo info)
{
}
public virtual void OnServerClosed(NetState state)
{
OnClosed();
}
public virtual void Close()
{
if (User == null || User.NetState == null)
return;
OnServerClose(User.NetState);
User.Send(new CloseGump(TypeID, 0));
User.NetState.RemoveGump(this);
}
public static T GetGump(PlayerMobile pm, Func predicate) where T : Gump
{
return EnumerateGumps(pm).FirstOrDefault(x => predicate == null || predicate(x));
}
public static IEnumerable EnumerateGumps(PlayerMobile pm, Func predicate = null) where T : Gump
{
NetState ns = pm.NetState;
if (ns == null)
yield break;
foreach (BaseGump gump in ns.Gumps.OfType().Where(g => g.GetType() == typeof(T) &&
(predicate == null || predicate(g as T))))
{
yield return gump as T;
}
}
public static List GetGumps(PlayerMobile pm) where T : Gump
{
NetState ns = pm.NetState;
List list = new List();
if (ns == null)
return list;
foreach (BaseGump gump in ns.Gumps.OfType().Where(g => g.GetType() == typeof(T)))
{
list.Add(gump as T);
}
return list;
}
public static List GetGumps(PlayerMobile pm, bool checkOpen = false)
{
NetState ns = pm.NetState;
List list = new List();
if (ns == null)
return list;
foreach (BaseGump gump in ns.Gumps.OfType().Where(g => (!checkOpen || g.Open)))
{
list.Add(gump);
}
return list;
}
public static void CheckCloseGumps(PlayerMobile pm, bool checkOpen = false)
{
NetState ns = pm.NetState;
if (ns != null)
{
List gumps = GetGumps(pm, checkOpen);
foreach (BaseGump gump in gumps.Where(g => g.CloseOnMapChange))
{
pm.CloseGump(gump.GetType());
}
ColUtility.Free(gumps);
}
}
public new void AddItemProperty(Item item)
{
item.SendPropertiesTo(User);
base.AddItemProperty(item);
}
public void AddMobileProperty(Mobile mob)
{
mob.SendPropertiesTo(User);
AddItemProperty(mob.Serial.Value);
}
public void AddProperties(Spoof spoof)
{
User.Send(spoof.PropertyList);
AddItemProperty(spoof.Serial.Value);
}
#region Formatting
public static int C16232(int c16)
{
c16 &= 0x7FFF;
int r = (((c16 >> 10) & 0x1F) << 3);
int g = (((c16 >> 05) & 0x1F) << 3);
int b = (((c16 >> 00) & 0x1F) << 3);
return (r << 16) | (g << 8) | (b << 0);
}
public static int C16216(int c16)
{
return c16 & 0x7FFF;
}
public static int C32216(int c32)
{
c32 &= 0xFFFFFF;
int r = (((c32 >> 16) & 0xFF) >> 3);
int g = (((c32 >> 08) & 0xFF) >> 3);
int b = (((c32 >> 00) & 0xFF) >> 3);
return (r << 10) | (g << 5) | (b << 0);
}
protected string Color(string color, string str)
{
return string.Format("{1}", color, str);
}
protected string Color(int color, string str)
{
return string.Format("{1}", color, str);
}
protected string ColorAndCenter(string color, string str)
{
return string.Format("{1}", color, str);
}
protected string ColorAndSize(string color, int size, string str)
{
return string.Format("{2}", color, size.ToString(), str);
}
protected string ColorAndCenterAndSize(string color, int size, string str)
{
return string.Format("{2}", color, size.ToString(), str);
}
protected string ColorAndCenter(int color, string str)
{
return string.Format("{1}", color, str);
}
protected string Center(string str)
{
return string.Format("{0}", str);
}
protected string ColorAndAlignRight(int color, string str)
{
return string.Format("{1}
", color, str);
}
protected string ColorAndAlignRight(string color, string str)
{
return string.Format("{1}
", color, str);
}
protected string AlignRight(string str)
{
return string.Format("{0}
", str);
}
public void AddHtmlTextDefinition(int x, int y, int length, int height, TextDefinition text, bool background, bool scrollbar)
{
if (text.Number > 0)
{
AddHtmlLocalized(x, y, length, height, text.Number, false, false);
}
else if (!string.IsNullOrEmpty(text.String))
{
AddHtml(x, y, length, height, text.String, background, scrollbar);
}
}
public void AddHtmlTextDefinition(int x, int y, int length, int height, TextDefinition text, int hue, bool background, bool scrollbar)
{
if (text.Number > 0)
{
AddHtmlLocalized(x, y, length, height, text.Number, hue, false, false);
}
else if (!string.IsNullOrEmpty(text.String))
{
AddHtml(x, y, length, height, Color(hue, text.String), background, scrollbar);
}
}
public void AddHtmlLocalizedCentered(int x, int y, int length, int height, int localization, bool background, bool scrollbar)
{
AddHtmlLocalized(x, y, length, height, 1113302, string.Format("#{0}", localization), 0, background, scrollbar);
}
public void AddHtmlLocalizedCentered(int x, int y, int length, int height, int localization, int hue, bool background, bool scrollbar)
{
AddHtmlLocalized(x, y, length, height, 1113302, string.Format("#{0}", localization), hue, background, scrollbar);
}
public void AddHtmlLocalizedAlignRight(int x, int y, int length, int height, int localization, bool background, bool scrollbar)
{
AddHtmlLocalized(x, y, length, height, 1114514, string.Format("#{0}", localization), 0, background, scrollbar);
}
public void AddHtmlLocalizedAlignRight(int x, int y, int length, int height, int localization, int hue, bool background, bool scrollbar)
{
AddHtmlLocalized(x, y, length, height, 1114514, string.Format("#{0}", localization), hue, background, scrollbar);
}
#endregion
#region Tooltips
private readonly Dictionary _TextTooltips = new Dictionary();
private readonly Dictionary, Spoof> _ClilocTooltips = new Dictionary, Spoof>();
public void AddTooltipTextDefinition(TextDefinition text)
{
if (text.Number > 0)
{
AddTooltip(text.Number);
}
else if (!string.IsNullOrEmpty(text.String))
{
AddTooltip(text.String);
}
}
public void AddTooltip(string text, System.Drawing.Color color)
{
AddTooltip(string.Empty, text, System.Drawing.Color.Empty, color);
}
public void AddTooltip(string title, string text)
{
AddTooltip(title, text, System.Drawing.Color.Empty, System.Drawing.Color.Empty);
}
public void AddTooltip(int cliloc, string format, params string[] args)
{
base.AddTooltip(cliloc, string.Format(format, args));
}
public void AddTooltip(int[] clilocs)
{
AddTooltip(clilocs, new string[clilocs.Length]);
}
public void AddTooltip(string[] args)
{
int[] clilocs = new int[Math.Min(Spoof.EmptyClilocs.Length, args.Length)];
for (int i = 0; i < args.Length; i++)
{
if (i >= Spoof.EmptyClilocs.Length)
break;
clilocs[i] = Spoof.EmptyClilocs[i];
}
AddTooltip(clilocs, args);
}
public void AddTooltip(int[] clilocs, string[] args)
{
Dictionary dictionary = new Dictionary();
int emptyIndex = 0;
for (int i = 0; i < clilocs.Length; i++)
{
string str = string.Empty;
if (i < args.Length)
{
str = args[i] ?? string.Empty;
}
int cliloc = clilocs[i];
if (cliloc <= 0)
{
if (emptyIndex <= Spoof.EmptyClilocs.Length)
{
cliloc = Spoof.EmptyClilocs[emptyIndex];
emptyIndex++;
}
}
if (cliloc > 0)
{
dictionary[cliloc] = str;
}
}
Spoof spoof;
if (!_ClilocTooltips.TryGetValue(dictionary, out spoof) || spoof == null || spoof.Deleted)
{
spoof = Spoof.Acquire();
}
spoof.ClilocTable = dictionary;
_ClilocTooltips[dictionary] = spoof;
AddProperties(spoof);
}
public void AddTooltip(string title, string text, System.Drawing.Color titleColor, System.Drawing.Color textColor)
{
title = title ?? string.Empty;
text = text ?? string.Empty;
if (titleColor.IsEmpty || titleColor == System.Drawing.Color.Transparent)
{
titleColor = System.Drawing.Color.White;
}
if (textColor.IsEmpty || textColor == System.Drawing.Color.Transparent)
{
textColor = System.Drawing.Color.White;
}
Spoof spoof;
if (!_TextTooltips.TryGetValue(text, out spoof) || spoof == null || spoof.Deleted)
{
spoof = Spoof.Acquire();
}
if (!string.IsNullOrWhiteSpace(title))
{
spoof.Text = string.Concat(string.Format("{1}", titleColor.ToArgb(), title),
'\n',
string.Format("{1}", textColor.ToArgb(), text));
}
else
{
spoof.Text = string.Format("{1}", textColor.ToArgb(), text); // text.WrapUOHtmlColor(textColor, false);
}
_TextTooltips[text] = spoof;
AddProperties(spoof);
}
public sealed class Spoof : Entity
{
private static readonly char[] _Split = { '\n' };
private static int _UID = -1;
private static int NewUID
{
get
{
if (_UID == int.MinValue)
{
_UID = -1;
}
return --_UID;
}
}
public static int[] EmptyClilocs =
{
1042971, 1070722, // ~1_NOTHING~
1114057, 1114778, 1114779, // ~1_val~
1150541, // ~1_TOKEN~
1153153, // ~1_year~
};
private static readonly List _SpoofPool = new List();
public static Spoof Acquire()
{
if (_SpoofPool.Count == 0)
{
return new Spoof();
}
else
{
Spoof spoof = _SpoofPool[0];
_SpoofPool.Remove(spoof);
return spoof;
}
}
public void Free()
{
Packet.Release(ref _PropertyList);
_Text = string.Empty;
_ClilocTable = null;
_SpoofPool.Add(this);
}
private ObjectPropertyList _PropertyList;
public ObjectPropertyList PropertyList
{
get
{
if (_PropertyList == null)
{
_PropertyList = new ObjectPropertyList(this);
if (!string.IsNullOrEmpty(Text))
{
string text = StripHtmlBreaks(Text, true);
if (text.IndexOf('\n') >= 0)
{
string[] lines = text.Split(_Split);
foreach (string str in lines)
{
_PropertyList.Add(str);
}
}
else
{
_PropertyList.Add(text);
}
}
else if (_ClilocTable != null)
{
foreach (KeyValuePair kvp in _ClilocTable)
{
int cliloc = kvp.Key;
string args = kvp.Value;
if (cliloc <= 0 && !string.IsNullOrEmpty(args))
{
_PropertyList.Add(args);
}
else if (string.IsNullOrEmpty(args))
{
_PropertyList.Add(cliloc);
}
else
{
_PropertyList.Add(cliloc, args);
}
}
}
_PropertyList.Terminate();
_PropertyList.SetStatic();
}
return _PropertyList;
}
}
private string _Text = string.Empty;
public string Text
{
get { return _Text ?? string.Empty; }
set
{
if (_Text != value)
{
_Text = value;
Packet.Release(ref _PropertyList);
}
}
}
private Dictionary _ClilocTable;
public Dictionary ClilocTable
{
get { return _ClilocTable; }
set
{
if (_ClilocTable != value)
{
_ClilocTable = value;
Packet.Release(ref _PropertyList);
}
}
}
public Spoof()
: base(NewUID, Point3D.Zero, Map.Internal)
{ }
}
public static string StripHtmlBreaks(string str, bool preserve)
{
return Regex.Replace(str, @"
]?>", preserve ? "\n" : " ", RegexOptions.IgnoreCase);
}
#endregion
}
}