using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CommonUtils;
using System.Xml;
namespace Calculator
{
/// <summary>
/// Interaction logic for Calculator.xaml
/// </summary>
public partial class CalculatorCtrl : UserControl
{
CalcConfig m_config;
public CalcConfig Config
{
get { return m_config;}
set
{
m_config = value;
m_input.History = m_config.InputHistory;
m_variables.History = m_config.VariablesHistory;
DataContext = Config;
}
}
public CalculatorCtrl()
{
InitializeComponent();
Config = new CalcConfig();
Loaded += OnLoaded;
}
void OnLoaded(object sender, RoutedEventArgs e)
{
m_input.Focus();
ScrollToBottom();
}
private void OnListboxPreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
e.Handled = true;
EquationParser parser = m_stackView.SelectedItem as EquationParser;
if (parser != null)
m_input.Text += parser.ValueAsString;
m_input.Focus();
m_input.CaretIndex = m_input.Text.Length;
e.Handled = true;
return;
}
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
if (m_variables.IsFocused)
{
CalFromVariables();
return;
}
OnEnter(null, null);
//e.Handled = true;
return;
}
if (e.Key == Key.Escape)
{
m_input.Focus();
return;
}
if (e.SystemKey == Key.D1 && e.KeyboardDevice.Modifiers == ModifierKeys.Alt)
{
// have to set focus to the item, not the listbox
ListBoxItem item = m_stackView.ItemContainerGenerator.ContainerFromItem(m_stackView.SelectedItem) as ListBoxItem;
if (item != null)
item.Focus();
e.Handled = true;
return;
}
if (e.SystemKey == Key.D2 && e.KeyboardDevice.Modifiers == ModifierKeys.Alt)
{
m_input.Focus();
e.Handled = true;
return;
}
if (e.SystemKey == Key.D3 && e.KeyboardDevice.Modifiers == ModifierKeys.Alt)
{
m_variables.Focus();
e.Handled = true;
return;
}
base.OnPreviewKeyDown(e);
}
private void OnEnter(object sender, RoutedEventArgs e)
{
if (m_input.IsFocused == false)
return;
DoCalculate(true);
}
void CalFromVariables()
{
DoCalculate(false);
}
private void OnCalculate(object sender, RoutedEventArgs e)
{
DoCalculate(true);
}
FunctionListPopup m_functionPopup;
private void OnInsertFunction(object sender, RoutedEventArgs e)
{
if (m_functionPopup == null)
{
m_functionPopup = new FunctionListPopup();
m_functionPopup.PlacementTarget = m_funcButton;
m_functionPopup.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
m_functionPopup.Closed += new EventHandler(FunctionPopupClosed);
}
m_functionPopup.Open(string.Empty);
}
void FunctionPopupClosed(object sender, EventArgs e)
{
FunctionListPopup lb = sender as FunctionListPopup;
if (lb == null || lb.PopupResult == false)
return;
m_input.Text += lb.SelectedItem;
m_input.CaretIndex = m_input.Text.Length-1;
m_input.Focus();
}
void ScrollToBottom()
{
if (Config.Stack.Count > 0)
{
m_stackView.SelectedItem = Config.Stack[Config.Stack.Count-1];
m_stackView.ScrollToBottom();
}
}
void DoCalculate(bool clearInput)
{
if (m_input.Text.Length == 0)
return;
EquationParser p = new EquationParser();
try
{
if (Config.Stack.Count > 0)
p.SetLastAnswer(Config.Stack[Config.Stack.Count-1].Value);
p.Calculate(m_input.Text, m_variables.Text);
Config.Stack.Add(p);
m_input.AddToHistory(m_input.Text, clearInput);
m_variables.AddToHistory(m_variables.Text, false);
ScrollToBottom();
}
catch (Exception error)
{
MessageBox.Show(error.Message);
}
}
private void OnInputKeyDown(object sender, KeyEventArgs e)
{
if (m_input.Text.Trim().Length > 0)
{
if (m_input.SelectionLength != m_input.Text.Length)
return;
}
if (e.Key==Key.RightShift)
return;
KeyMapItem[] operators = new KeyMapItem[]
{
new KeyMapItem('+', Key.Add, false),
new KeyMapItem('-', Key.Subtract, false),
new KeyMapItem('*', Key.Multiply, false),
new KeyMapItem('/', Key.Divide, false),
new KeyMapItem('^', Key.D6, true),
};
KeyMapItem map = Array.Find(operators, a => a.Match(e));
if (map != null)
{
m_input.Text = "ans" + map.Char;
m_input.CaretIndex = m_input.Text.Length;
e.Handled = true;
}
}
class KeyMapItem
{
public char Char {get; private set;}
public Key Key {get; private set;}
public bool IsShift {get; private set;}
public KeyMapItem(char ch, Key key, bool isShift)
{
Char = ch;
Key = key;
IsShift = isShift;
}
public bool Match(KeyEventArgs arg)
{
if (arg.Key != Key)
return false;
if (IsShift && arg.KeyboardDevice.Modifiers != ModifierKeys.Shift)
return false;
return true;
}
}
}
}