using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace Twiggery
{
public class AutoTipItem
{
private string inputString = null;
/// <summary>
/// Input string
/// </summary>
public string InputString
{
get { return inputString; }
set { inputString = value; }
}
private string resultString = null;
/// <summary>
/// Result string, to be filled into a textbox
/// </summary>
public string ResultString
{
get { return resultString; }
set { resultString = value; }
}
private string describtionString = null;
/// <summary>
/// Description
/// </summary>
public string DescribtionString
{
get { return describtionString; }
set { describtionString = value; }
}
public AutoTipItem(string _input, string _result, string _desc)
{
inputString = _input.ToLower();
resultString = _result;
describtionString = _desc;
}
public static bool operator <(AutoTipItem i1, AutoTipItem i2)
{
return i1.inputString.CompareTo(i2.inputString) == -1;
}
public static bool operator >(AutoTipItem i1, AutoTipItem i2)
{
return i1.inputString.CompareTo(i2.inputString) == 1;
}
public override string ToString()
{
return resultString;
}
}
public class ScriptAutoTipBox : ListBox
{
private Dictionary<string, List<AutoTipItem>> autoWords = null;
private TextBoxBase outerTextBox = null;
private ToolTip toolTip = null;
public ScriptAutoTipBox()
{
autoWords = new Dictionary<string, List<AutoTipItem>>();
toolTip = new ToolTip();
}
public void AddTip(AutoTipItem tip)
{
string head = tip.InputString.Substring(0, 1);
if (!autoWords.ContainsKey(head))
{
autoWords.Add(head, new List<AutoTipItem>());
}
autoWords[head].Add(tip);
this.Items.Add(tip);
this.Sort();
}
protected override void Sort()
{
if (this.Items.Count > 1)
{
bool swapped;
do
{
int counter = this.Items.Count - 1;
swapped = false;
while (counter > 0)
{
// Compare the items' length
//if (this.Items[counter].ToString().Length
// < this.Items[counter - 1].ToString().Length)
if ((AutoTipItem)this.Items[counter] < (AutoTipItem)this.Items[counter - 1])
{
// Swap the items
object temp = this.Items[counter];
this.Items[counter] = this.Items[counter - 1];
this.Items[counter - 1] = temp;
swapped = true;
}
// Decrement the counter
counter -= 1;
}
}
while ((swapped == true));
}
}
public void Clear()
{
autoWords.Clear();
}
public void InitializeTwiggeryAutoTip(Form container, TextBoxBase textBox)
{
outerTextBox = textBox;
container.Controls.Add(this);
this.Width = 200;
this.Visible = false;
AddTip(new AutoTipItem("function", "function", "A 'function' is a most outer twig"));
AddTip(new AutoTipItem("if", "if", "Condition logic"));
AddTip(new AutoTipItem("elseif", "elseif", "Condition logic, related with 'if' block"));
AddTip(new AutoTipItem("else", "else", "Condition logic, related to 'if' block (maybe to 'elseif' also)"));
AddTip(new AutoTipItem("for", "for", "Fixed loop"));
AddTip(new AutoTipItem("to", "to", "Fixed loop end condition"));
AddTip(new AutoTipItem("step", "step", "Fixed loop step, default as 1"));
AddTip(new AutoTipItem("while", "while", "Variable loop"));
AddTip(new AutoTipItem("do", "do", "Variable loop"));
AddTip(new AutoTipItem("break", "break", "Break out a loop and skip twig follow"));
AddTip(new AutoTipItem("continue", "continue", "Continue doing a loop and skip twig follow"));
AddTip(new AutoTipItem("return", "return", "Exit a 'function'"));
AddTip(new AutoTipItem("and", "and", "'And' boolean logic"));
AddTip(new AutoTipItem("or", "or", "'Or' boolean logic"));
AddTip(new AutoTipItem("not", "not", "'Not' boolean logic"));
AddTip(new AutoTipItem("true", "true", "Boolean value 'True'"));
AddTip(new AutoTipItem("false", "false", "Boolean value 'False'"));
}
public bool Advice(string part)
{
string _part = part.ToLower();
bool result = false;
this.Visible = false;
if (!string.IsNullOrEmpty(_part))
{
string head = _part.Substring(0, 1);
if (autoWords.ContainsKey(head))
{
foreach (AutoTipItem item in autoWords[head])
{
if (item.InputString.StartsWith(_part))
{
if (item.InputString.Length != _part.Length)
{
Point point = outerTextBox.GetPositionFromCharIndex(outerTextBox.SelectionStart + outerTextBox.SelectionLength);
point.Y += outerTextBox.Location.Y + (int)Math.Ceiling(outerTextBox.Font.GetHeight()) + 32;
point.X += outerTextBox.Location.X + 4; // for Courier, may need a better method
this.Location = point;
this.BringToFront();
this.SelectedItem = item;
this.Visible = true;
showTip(item.DescribtionString);
result = true;
}
else
{
this.Visible = false;
}
break;
}
}
}
}
return result;
}
private void showTip(string tip)
{
toolTip.Show(tip, this, this.Width + 5, 0, 2000);
}
public void MoveUp()
{
if (0 != this.Items.Count)
{
int si = this.SelectedIndex;
si--;
if (si >= 0)
{
this.SelectedIndex = si;
AutoTipItem item = (AutoTipItem)this.SelectedItem;
showTip(item.DescribtionString);
}
}
}
public void MoveDown()
{
if (0 != this.Items.Count)
{
int si = this.SelectedIndex;
si++;
if (si < this.Items.Count)
{
this.SelectedIndex = si;
AutoTipItem item = (AutoTipItem)this.SelectedItem;
showTip(item.DescribtionString);
}
}
}
public void BeSure(string foreCut)
{
string selStr = this.SelectedItem.ToString();
if (selStr.StartsWith(foreCut))
{
outerTextBox.SelectedText = selStr.Substring(foreCut.Length);
}
else
{
outerTextBox.Select(outerTextBox.SelectionStart - foreCut.Length, foreCut.Length);
outerTextBox.SelectedText = selStr;
}
}
}
}