// Chattr - Twitter client on .NET
//
// Copyright (c) 2007 Katsuhiko Ichinose <ichi@users.sourceforge.jp>
//
// Chattr is Free Software released under GNU General Public License.
//
// $Id: FormMain.cs 262 2011-02-06 10:03:02Z ichi $

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Collections;

using System.Threading;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;

using Newtonsoft.Json;

using System.Diagnostics;


namespace Chattr
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            Debug.WriteLine("DEBUG");
            Debug.WriteLine(System.Reflection.Assembly.GetEntryAssembly().Location);
            Debug.WriteLine(Application.ExecutablePath);
            m_Browser = new FormBrowser(this);
            m_Post = new FormPost(this);
            m_Popup = new FormPopup(this, m_Post);
            //m_Log = new FormLog(this);
            m_MutexStatus = new Mutex(false);
            m_MutexSearch = new Mutex(false);
            m_MutexProfile = new Mutex(false);
            m_MutexTinyUrl = new Mutex(false);
            m_MutexBgWork = new Mutex(false);
            m_QueueProfile = new Queue<bool>();
            m_QueueTnyUrl = new Queue<bool>();
            InitializeComponent();
            CorrectComponent();
            InitializeListBoxSearch();
            InitializeListBoxStatuses();
            SetContextMenu();
            InitializeTransactor();
            m_Prefs = new FormPreferences(this);
            System.Net.ServicePointManager.Expect100Continue = false;
        }

        private CListBox listBoxStatuses = null;
        private CListBox listBoxSearch = null;

        private void CorrectComponent()
        {
            comboBoxLocation.Location = new Point(comboBoxLocation.Location.X, ClientSize.Height - statusStrip.Size.Height - comboBoxLocation.Size.Height - 4);
            labelAvailable.Location = new Point(labelAvailable.Location.X, ClientSize.Height - statusStrip.Size.Height - labelAvailable.Size.Height - 2);
            textBoxStatus.Location = new Point(textBoxStatus.Location.X, ClientSize.Height - statusStrip.Size.Height - comboBoxLocation.Size.Height - textBoxStatus.Size.Height - 4);
        }

        private void InitializeListBoxStatuses()
        {
            this.listBoxStatuses = new CListBox();
            this.listBoxStatuses.SetDoubleBuffered();
            this.SuspendLayout();
            this.listBoxStatuses.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.listBoxStatuses.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
            //this.listBoxStatuses.Font = new System.Drawing.Font("MS UI Gothic", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
            this.listBoxStatuses.Location = new System.Drawing.Point(0, toolStrip.Size.Height + 3);
            this.listBoxStatuses.Name = "listBoxStatuses";
            this.listBoxStatuses.Size = new System.Drawing.Size(ClientSize.Width, ClientSize.Height - (toolStrip.Size.Height + 3) - (statusStrip.Size.Height + comboBoxLocation.Size.Height + textBoxStatus.Size.Height + 4));
            this.listBoxStatuses.TabIndex = 0;
            this.listBoxStatuses.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.listBoxStatuses_DrawItem);
            this.listBoxStatuses.DoubleClick += new System.EventHandler(this.listBoxStatuses_DoubleClick);
            this.listBoxStatuses.SelectedIndexChanged += new System.EventHandler(this.listBoxStatuses_SelectedIndexChanged);
            this.listBoxStatuses.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.listBoxStatuses_MeasureItem);
            this.listBoxStatuses.MouseDown += new System.Windows.Forms.MouseEventHandler(this.listBoxStatuses_MouseDown);
            this.listBoxStatuses.MouseEnter += new System.EventHandler(this.listBoxStatuses_MouseEnter);
            this.listBoxStatuses.MouseLeave += new System.EventHandler(this.listBoxStatuses_MouseLeave);
            this.listBoxStatuses.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listBoxStatuses_KeyDown);
            this.listBoxStatuses.Scroll += new System.EventHandler(this.listBoxStatuses_Scroll);
            this.Controls.Add(this.listBoxStatuses);
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void InitializeListBoxSearch()
        {
            this.listBoxSearch = new CListBox();
            this.listBoxSearch.SetDoubleBuffered();
            this.SuspendLayout();
            this.listBoxSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.listBoxSearch.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
            //this.listBoxSearch.Font = new System.Drawing.Font("MS UI Gothic", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
            this.listBoxSearch.Location = new System.Drawing.Point(0, toolStrip.Size.Height + 3);
            this.listBoxSearch.Name = "listBoxSearch";
            this.listBoxSearch.Size = new System.Drawing.Size(ClientSize.Width, ClientSize.Height - (toolStrip.Size.Height + 3) - (statusStrip.Size.Height + comboBoxLocation.Size.Height + textBoxStatus.Size.Height + 4));
            this.listBoxSearch.TabIndex = 0;
            this.listBoxSearch.TabStop = false;
            this.listBoxSearch.Visible = false;
            this.listBoxSearch.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.listBoxSearch_DrawItem);
            this.listBoxSearch.DoubleClick += new System.EventHandler(this.listBoxSearch_DoubleClick);
            this.listBoxSearch.SelectedIndexChanged += new System.EventHandler(this.listBoxSearch_SelectedIndexChanged);
            this.listBoxSearch.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.listBoxSearch_MeasureItem);
            this.listBoxSearch.MouseDown += new System.Windows.Forms.MouseEventHandler(this.listBoxSearch_MouseDown);
            this.listBoxSearch.MouseEnter += new System.EventHandler(this.listBoxSearch_MouseEnter);
            this.listBoxSearch.MouseLeave += new System.EventHandler(this.listBoxSearch_MouseLeave);
            this.listBoxSearch.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listBoxSearch_KeyDown);
            this.Controls.Add(this.listBoxSearch);
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void SetContextMenu()
        {
            this.listBoxStatuses.ContextMenuStrip = this.contextMenuStripStatuses;
            this.listBoxSearch.ContextMenuStrip = this.contextMenuStripStatuses;
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == Program.MsgID)
            {
                toolStripMenuItemTaskTrayIconOpen.PerformClick();
            }
            else
            {
                base.WndProc(ref m);
            }
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            m_ContextMenuItems = contextMenuStrip.Items.Count;
            m_ContextMenuStatusesItems = contextMenuStripStatuses.Items.Count;
            m_Prefs.SetDialog();
            while ((Properties.Settings.Default.UserName == "") || (m_Prefs.AccessToken == "") || (m_Prefs.AccessTokenSecret == ""))
            {
                if (m_Prefs.ShowDialog(this) == DialogResult.OK)
                {
                    m_Prefs.GetDialog();
                    m_Prefs.Save();
                }
                else
                {
                    this.Hide();
                    Application.Exit();
                    return;
                }
            }
#if false
            // 入力フォームの位置を常に設定
            Point locStatusBar = statusStrip.Location;
            Point location = textBoxStatus.Location;
            location.Y = (locStatusBar.Y - (719 - 676));
            textBoxStatus.Location = location;
            textBoxStatus.Size = new Size(550, 23);
            location = labelAvailable.Location;
            location.Y = (locStatusBar.Y - (719 - 703));
            labelAvailable.Location = location;
            labelAvailable.Size = new Size(155, 15);
            location = comboBoxLocation.Location;
            location.Y = (locStatusBar.Y - (719 - 699));
            comboBoxLocation.Location = location;
            comboBoxLocation.Size = new Size(144, 23);
            location = listBoxStatuses.Location;
            // リストボックスのサイズを調整
            Size sizeListBox = listBoxStatuses.Size;
            sizeListBox.Height = locStatusBar.Y - (719 - 676) - location.Y;
            listBoxStatuses.Size = sizeListBox;
            listBoxSearch.Size = sizeListBox;
#endif
            // マルチライン入力フォームの設定
            if (Properties.Settings.Default.MultiLineForm)
            {
                Size size = listBoxStatuses.Size;
                size.Height -= 29;
                listBoxStatuses.Size = size;
                listBoxSearch.Size = size;
                textBoxStatus.Multiline = true;
                Point location = textBoxStatus.Location;
                location.Y -= 29;
                textBoxStatus.Location = location;
                size = textBoxStatus.Size;
                size.Height += 32;
                textBoxStatus.Size = size;
            }
            SetLocation();
            toolStripButtonRefresh.Enabled = false;
            toolStripButtonOffline.Enabled = false;
            toolStripTextBoxSearch.Enabled = false;
            toolStripSplitButtonSearch.Enabled = false;
            textBoxStatus.Enabled = false;
            comboBoxLocation.Enabled = false;
            toolStripLabelStatuses.Text = "";
            toolStripStatusLabel.Text = "";
            SetWindowSize();
            SetWindowTitle();
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            m_ListWidth = listBoxStatuses.Width;
            NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
            RequestBackGround(BG_FILL);
        }

        private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            if (this.InvokeRequired)
            {
                System.Net.NetworkInformation.NetworkAvailabilityChangedEventHandler dlgt =
                    new System.Net.NetworkInformation.NetworkAvailabilityChangedEventHandler(
                        NetworkChange_NetworkAvailabilityChanged);
                this.Invoke(dlgt, new object[] { sender, e });
            }
            else
            {
                if (e.IsAvailable)
                {
                    Debug.WriteLine("ネットワーク接続が有効になりました。");
                }
                else
                {
                    Debug.WriteLine("ネットワーク接続が無効になりました。");
                }
            }
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (m_fBgBusy || (m_RunGetProfileImage > 0) || (m_RunGetTinyUrl > 0))
            {
                e.Cancel = true;
                backgroundWorker.CancelAsync();
                if (m_RunGetProfileImage > 0)
                {
                    m_QueueProfile.Enqueue(true);
                    Debug.WriteLine("Runing GetProfileImage");
                }
                if (m_RunGetTinyUrl > 0)
                {
                    m_QueueTnyUrl.Enqueue(true);
                    Debug.WriteLine("Runing GetTinyUrl");
                }
                RequestDummy();
            }
            else
            {
                Quit();
            }
        }

        private void FormMain_SizeChanged(object sender, EventArgs e)
        {
            if (listBoxStatuses.Width > 0)
            {
                m_ListWidth = listBoxStatuses.Width;
            }
            if (this.WindowState == FormWindowState.Minimized)
            {
                if (Properties.Settings.Default.TaskTrayIcon)
                {
                    notifyIcon.Visible = true;
                    this.Hide();
                }
            }
            else if (this.WindowState == FormWindowState.Normal)
            {
                SaveWindowSize();
            }
        }

        private void FormMain_Move(object sender, EventArgs e)
        {
            SaveWindowPosition();
        }

        private void listBoxStatuses_MeasureItem(object sender, MeasureItemEventArgs e)
        {
            e.ItemHeight = listBox_MeasureItem(listBoxStatuses, e, dataSetChattr.TableStatus, m_MutexStatus, m_ListWidth, ref m_IconWith);
        }

        private void listBoxStatuses_DrawItem(object sender, DrawItemEventArgs e)
        {
            listBox_DrawItem(listBoxStatuses, e, dataSetChattr.TableStatus, m_MutexStatus, dataSetChattr.TableProfileImage);
        }

        private void listBoxStatuses_KeyDown(object sender, KeyEventArgs e)
        {
            listBox_KeyDown(listBoxStatuses, e, dataSetChattr.TableStatus, m_MutexStatus);
        }

        private void listBoxStatuses_DoubleClick(object sender, EventArgs e)
        {
            listBox_DoubleClick(listBoxStatuses, e, dataSetChattr.TableStatus, m_MutexStatus);
        }

        private void listBoxStatuses_SelectedIndexChanged(object sender, EventArgs e)
        {
            Debug.WriteLine("listBoxStatuses_SelectedIndexChanged: " + DateTime.Now);
            if (!contextMenuStripStatuses.Visible)
            {
                int idx = ListBox.NoMatches;
                listBox_SelectedIndexChanged(listBoxStatuses, e, dataSetChattr.TableStatus, m_MutexStatus, ref idx);
                if ((idx != ListBox.NoMatches) && ((listBoxStatuses.Items.Count - idx) < MARGIN_LOAD))
                {
                    RequestLoading();
                }
            }
        }

        private void listBoxStatuses_MouseDown(object sender, MouseEventArgs e)
        {
            listBox_MouseDown(listBoxStatuses, e, dataSetChattr.TableStatus, m_MutexStatus);
        }

        private void listBoxStatuses_MouseEnter(object sender, EventArgs e)
        {
            Debug.WriteLine("listBoxStatuses_MouseEnter");
            m_MouseHoverStatuses = true;
        }

        private void listBoxStatuses_MouseLeave(object sender, EventArgs e)
        {
            Debug.WriteLine("listBoxStatuses_MouseLeave");
            m_MouseHoverStatuses = false;
        }

        private void listBoxStatuses_Scroll(object sender, EventArgs e)
        {
            if ((listBoxStatuses.Items.Count - listBoxStatuses.TopIndex) < MARGIN_LOAD)
            {
                RequestLoading();
            }
        }

        private void listBoxSearch_MeasureItem(object sender, MeasureItemEventArgs e)
        {
            e.ItemHeight = listBox_MeasureItem(listBoxSearch, e, m_TblSearch, m_MutexSearch, m_ListWidth, ref m_IconWith);
        }

        private void listBoxSearch_DrawItem(object sender, DrawItemEventArgs e)
        {
            listBox_DrawItem(listBoxSearch, e, m_TblSearch, m_MutexSearch, dataSetChattr.TableProfileImage);
        }

        private void listBoxSearch_KeyDown(object sender, KeyEventArgs e)
        {
            listBox_KeyDown(listBoxSearch, e, m_TblSearch, m_MutexSearch);
        }

        private void listBoxSearch_DoubleClick(object sender, EventArgs e)
        {
            listBox_DoubleClick(listBoxSearch, e, m_TblSearch, m_MutexSearch);
        }

        private void listBoxSearch_SelectedIndexChanged(object sender, EventArgs e)
        {
            int idx = ListBox.NoMatches;
            bool change = listBox_SelectedIndexChanged(listBoxSearch, e, m_TblSearch, m_MutexSearch, ref idx);
            if (change)
            {
                m_MutexSearch.WaitOne();
                try
                {
                    if ((idx >= 0) && (idx < m_TblSearch.Rows.Count))
                    {
                        DataSetChattr.TableStatusRow row = m_TblSearch.Rows[idx] as DataSetChattr.TableStatusRow;
                        RequestSetFlag(row.id, row.flags);
                    }
                }
                finally
                {
                    m_MutexSearch.ReleaseMutex();
                }
            }
        }

        private void listBoxSearch_MouseDown(object sender, MouseEventArgs e)
        {
            listBox_MouseDown(listBoxSearch, e, m_TblSearch, m_MutexSearch);
        }

        private void listBoxSearch_MouseEnter(object sender, EventArgs e)
        {
            Debug.WriteLine("listBoxSearch_MouseEnter");
            m_MouseHoverSearch = true;
        }

        private void listBoxSearch_MouseLeave(object sender, EventArgs e)
        {
            Debug.WriteLine("listBoxSearch_MouseLeave");
            m_MouseHoverSearch = false;
        }

        private void textBoxStatus_Enter(object sender, EventArgs e)
        {
            if (textBoxStatus.ForeColor == Color.FromKnownColor(KnownColor.GrayText))
            {
                textBoxStatus.ForeColor = Color.FromKnownColor(KnownColor.WindowText);
                textBoxStatus.Text = "";
            }
        }

        private void textBoxStatus_Leave(object sender, EventArgs e)
        {
            if (textBoxStatus.Text == "")
            {
                textBoxStatus.ForeColor = Color.FromKnownColor(KnownColor.GrayText);
                textBoxStatus.Text = "What are you doing?";
            }
        }

        private void textBoxStatus_EnabledChanged(object sender, EventArgs e)
        {
            if (!textBoxStatus.Enabled)
            {
                if (listBoxStatuses.Visible)
                {
                    listBoxStatuses.Focus();
                }
                else
                {
                    listBoxSearch.Focus();
                }
            }
        }

        private void textBoxStatus_TextChanged(object sender, EventArgs e)
        {
            labelAvailable_Update();
        }

        private void labelAvailable_Update()
        {
            int length = 0;
            if (textBoxStatus.ForeColor != Color.FromKnownColor(KnownColor.GrayText))
            {
                length = textBoxStatus.Text.Length;
                if (Properties.Settings.Default.UseSignature && (Properties.Settings.Default.Signature != ""))
                {
                    length += Properties.Settings.Default.Signature.Length + 1;
                }
                if ((comboBoxLocation.ForeColor != Color.FromKnownColor(KnownColor.GrayText)) && (comboBoxLocation.Text != ""))
                {
                    length += comboBoxLocation.Text.Length + " L:".Length;
                }
            }
            if (m_ReplyTo == 0)
            {
                labelAvailable.Text = LABEL_AVAILABLE + (140 - length);
            }
            else
            {
                labelAvailable.Text = LABEL_AVAILABLE + (140 - length) + " (Reply to: " + m_ReplyUser + ")";
            }
        }

        private void textBoxStatus_KeyDown(object sender, KeyEventArgs e)
        {
            CListBox listBox = listBoxStatuses;
            if (m_TblSearch != null)
            {
                listBox = listBoxSearch;
            }
            switch (e.KeyData)
            {
                case Keys.Home | Keys.Control:
                    if (!Properties.Settings.Default.MultiLineForm)
                    {
                        listBox.SelectedIndex = 0;
                        e.Handled = true;
                    }
                    break;
                case Keys.End | Keys.Control:
                    if (!Properties.Settings.Default.MultiLineForm)
                    {
                        listBox.SelectedIndex = listBox.Items.Count - 1;
                        e.Handled = true;
                    }
                    break;
                case Keys.Down:
                    if (!Properties.Settings.Default.MultiLineForm)
                    {
                        if (listBox.SelectedIndex < listBox.Items.Count - 1)
                        {
                            listBox.SelectedIndex += 1;
                        }
                        e.Handled = true;
                    }
                    break;
                case Keys.Up:
                    if (!Properties.Settings.Default.MultiLineForm)
                    {
                        if (listBox.SelectedIndex > 0)
                        {
                            listBox.SelectedIndex -= 1;
                        }
                        e.Handled = true;
                    }
                    break;
                case Keys.Home | Keys.Control | Keys.Alt:
                    listBox.SelectedIndex = 0;
                    e.Handled = true;
                    break;
                case Keys.End | Keys.Control | Keys.Alt:
                    listBox.SelectedIndex = listBox.Items.Count - 1;
                    e.Handled = true;
                    break;
                case Keys.Down | Keys.Alt:
                    if (listBox.SelectedIndex < listBox.Items.Count - 1)
                    {
                        listBox.SelectedIndex += 1;
                    }
                    e.Handled = true;
                    break;
                case Keys.Up | Keys.Alt:
                    if (listBox.SelectedIndex > 0)
                    {
                        listBox.SelectedIndex -= 1;
                    }
                    e.Handled = true;
                    break;
                case Keys.PageDown:
                    listBox.RaiseKey(Keys.PageDown);
                    Debug.WriteLine("textBoxStatus_KeyDown: PageDown");
                    break;
                case Keys.PageUp:
                    listBox.RaiseKey(Keys.PageUp);
                    Debug.WriteLine("textBoxStatus_KeyDown: PageUp");
                    break;
                case Keys.Back:
                    if (textBoxStatus.Text == "")
                    {
                        m_ReplyTo = 0;
                        labelAvailable_Update();
                    }
                    break;
                case Keys.Delete:
                    if (textBoxStatus.Text == "")
                    {
                        m_ReplyTo = 0;
                        labelAvailable_Update();
                    }
                    break;
            }
        }

        private void textBoxStatus_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r')
            {
                if (textBoxStatus.Text != "")
                {
                    string text = MakeStatusText(textBoxStatus.Text);
                    textBoxStatus.Enabled = false;
                    UpdateStatus(text);
                }
                else
                {
                    toolStripButtonRefresh_Click(sender, e);
                }
                e.Handled = true;
            }
        }

        private void comboBoxLocation_Enter(object sender, EventArgs e)
        {
            if (comboBoxLocation.ForeColor == Color.FromKnownColor(KnownColor.GrayText))
            {
                comboBoxLocation.ForeColor = Color.FromKnownColor(KnownColor.WindowText);
                comboBoxLocation.Text = "";
            }
        }

        private void comboBoxLocation_Leave(object sender, EventArgs e)
        {
            if (comboBoxLocation.Text == "")
            {
                comboBoxLocation.ForeColor = Color.FromKnownColor(KnownColor.GrayText);
                comboBoxLocation.Text = "Location";
            }
        }

        private void toolStripButtonPreferences_Click(object sender, EventArgs e)
        {
            if (m_Prefs.ShowDialog(this) == DialogResult.OK)
            {
                m_Prefs.GetDialog();
                listBoxSearch.BeginUpdate();
                listBoxSearch.EndUpdate();
                listBoxStatuses.BeginUpdate();
                listBoxStatuses.EndUpdate();
                SetWindowTitle();
            }
            else
            {
                m_Prefs.SetDialog();
            }
        }

        private void toolStripButtonRefresh_Click(object sender, EventArgs e)
        {
            if ((ModifierKeys & (Keys.Control | Keys.Shift)) == (Keys.Control | Keys.Shift))
            {
                GetDirectMessage();
            }
            else if ((ModifierKeys & Keys.Shift) != 0)
            {
                GetReplies();
            }
            else if ((ModifierKeys & Keys.Control) != 0)
            {
                GetUserTimeline();
            }
            else
            {
                GetFollowingTimeline();
                if (Properties.Settings.Default.RefreshWithReplies)
                {
                    GetReplies();
                }
            }
        }

        private void toolStripButtonOffline_Click(object sender, EventArgs e)
        {
            if (toolStripButtonOffline.CheckState == CheckState.Unchecked)
            {
                toolStripButtonOffline.CheckState = CheckState.Checked;
                toolStripButtonOffline.ToolTipText = "オンライン(O)";
                m_TimeOfflineIn = DateTime.Now;
            }
            else
            {
                toolStripButtonOffline.CheckState = CheckState.Unchecked;
                toolStripButtonOffline.ToolTipText = "オフライン(O)";
                DateTime now = DateTime.Now;
                m_SpanOfflineFollowing += now - m_TimeOfflineIn;
                m_SpanOfflineReplies += now - m_TimeOfflineIn;
                Debug.WriteLine("Offline following: " + m_SpanOfflineFollowing);
                Debug.WriteLine("Offline replies: " + m_SpanOfflineReplies);
            }
        }

        //private void toolStripButtonLog_Click(object sender, EventArgs e)
        //{
        //    bool online = toolStripButtonOffline.CheckState == CheckState.Unchecked;
        //    if (online)
        //    {
        //        toolStripButtonOffline.PerformClick();
        //    }
        //    m_Log.ShowDialog();
        //    if (online)
        //    {
        //        toolStripButtonOffline.PerformClick();
        //    }
        //}

        private void toolStripMenuItemStatusesReply_Click(object sender, EventArgs e)
        {
            ListBox listBox = listBoxStatuses;
            DataSetChattr.TableStatusDataTable table = dataSetChattr.TableStatus;
            Mutex mutex = m_MutexStatus;
            if (m_TblSearch != null)
            {
                listBox = listBoxSearch;
                table = m_TblSearch;
                mutex = m_MutexSearch;
            }
            EntryReply(listBox, e, table, mutex);
        }

        private void toolStripMenuItemStatusesDirect_Click(object sender, EventArgs e)
        {
            ListBox listBox = listBoxStatuses;
            DataSetChattr.TableStatusDataTable table = dataSetChattr.TableStatus;
            Mutex mutex = m_MutexStatus;
            if (m_TblSearch != null)
            {
                listBox = listBoxSearch;
                table = m_TblSearch;
                mutex = m_MutexSearch;
            }
            EntryDirectMessage(listBox, e, table, mutex);
        }

        private void toolStripMenuItemStatusesFavorite_Click(object sender, EventArgs e)
        {
            ListBox listBox = listBoxStatuses;
            DataSetChattr.TableStatusDataTable table = dataSetChattr.TableStatus;
            Mutex mutex = m_MutexStatus;
            if (m_TblSearch != null)
            {
                listBox = listBoxSearch;
                table = m_TblSearch;
                mutex = m_MutexSearch;
            }
            Favorite(listBox, e, table, mutex);
        }

        private void toolStripMenuItemStatusesReblog_Click(object sender, EventArgs e)
        {
            ListBox listBox = listBoxStatuses;
            DataSetChattr.TableStatusDataTable table = dataSetChattr.TableStatus;
            Mutex mutex = m_MutexStatus;
            if (m_TblSearch != null)
            {
                listBox = listBoxSearch;
                table = m_TblSearch;
                mutex = m_MutexSearch;
            }
            Reblog(listBox, e, table, mutex);
        }

        private void toolStripMenuItemStatusesReTweet_Click(object sender, EventArgs e)
        {
            ListBox listBox = listBoxStatuses;
            DataSetChattr.TableStatusDataTable table = dataSetChattr.TableStatus;
            Mutex mutex = m_MutexStatus;
            if (m_TblSearch != null)
            {
                listBox = listBoxSearch;
                table = m_TblSearch;
                mutex = m_MutexSearch;
            }
            ReTweet(listBox, e, table, mutex);
        }

        private void toolStripMenuItemStatusesReTweetViaAPI_Click(object sender, EventArgs e)
        {
            ListBox listBox = listBoxStatuses;
            DataSetChattr.TableStatusDataTable table = dataSetChattr.TableStatus;
            Mutex mutex = m_MutexStatus;
            if (m_TblSearch != null)
            {
                listBox = listBoxSearch;
                table = m_TblSearch;
                mutex = m_MutexSearch;
            }
            ReTweetViaAPI(listBox, e, table, mutex);
        }

        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                BackgroundWorker worker = sender as BackgroundWorker;
                if (e.Argument.GetType() == typeof(IBackGroundString))
                {
                    e.Result = DoBackGround_String(e.Argument as IBackGroundString, worker);
                }
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                }
            }
            catch (SystemException ex)
            {
                Debug.WriteLine("backgroundWorker_DoWork() Error\n" +
                    ex.Message + "\n" + "Source: " + ex.Source);
            }
        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            try
            {
                switch ((ProgressOp)e.ProgressPercentage)
                {
                    case ProgressOp.BG_FLAG:
                        if (e.UserState.GetType() == typeof(bool))
                        {
                            m_fBgFlag = (bool)e.UserState;
                        }
                        break;
                    case ProgressOp.STATUS_BAR:
                        if (e.UserState.GetType() == typeof(String))
                        {
                            SetToolStripStatusLabelText((String)e.UserState);
                        }
                        break;
                    case ProgressOp.LABEL_STATUS:
                        if (e.UserState.GetType() == typeof(String))
                        {
                            toolStripLabelStatuses.Text = (String)e.UserState;
                        }
                        break;
                    case ProgressOp.NUM_STATUS:
                        toolStripLabelStatuses.Text = NumStatus();
                        break;
                    case ProgressOp.LIST_ENABLE:
                        listBoxSearch.TabStop = false;
                        listBoxSearch.Visible = false;
                        listBoxStatuses.TabStop = true;
                        listBoxStatuses.Visible = true;
                        break;
                    case ProgressOp.LIST_BEGIN_UPDATE:
                        listBoxStatuses.BeginUpdate();
                        break;
                    case ProgressOp.LIST_END_UPDATE:
                        listBoxStatuses.EndUpdate();
                        break;
                    case ProgressOp.LIST_UPDATE:
                        listBoxStatuses.Update();
                        break;
                    case ProgressOp.LIST_ADD:
                        if (e.UserState.GetType() == typeof(IListItem))
                        {
                            listBoxStatuses.Items.Add(e.UserState);
                        }
                        break;
                    case ProgressOp.LIST_INSERT:
                        if (e.UserState.GetType() == typeof(IListItem))
                        {
                            IListItem item = e.UserState as IListItem;
                            listBoxStatuses.Items.Insert(item.Index, item);
                        }
                        break;
                    case ProgressOp.LIST_REPLACE:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            int idx = (int)e.UserState;
                            IListItem item = listBoxStatuses.Items[idx] as IListItem;
                            item.Value++;
                            listBoxStatuses.Items[idx] = new IListItem(item);
                            Rectangle rect = listBoxStatuses.GetItemRectangle(idx);
                            if (m_IconWith > 0)
                            {
                                rect.Width = (int)m_IconWith;
                            }
                            listBoxStatuses.Invalidate(rect);
                        }
                        break;
                    case ProgressOp.LIST_DELETE:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            IListItem item = listBoxStatuses.Items[(int)e.UserState] as IListItem;
                            item.Delete = true;
                        }
                        break;
                    case ProgressOp.LIST_REMOVE:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            listBoxStatuses.Items.RemoveAt((int)e.UserState);
                        }
                        break;
                    case ProgressOp.LIST_REMOVES:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            int count = (int)e.UserState;
                            for (int i = 0; i < count; i++)
                            {
                                for (int idx = 0; idx < listBoxStatuses.Items.Count; idx++)
                                {
                                    IListItem item = listBoxStatuses.Items[idx] as IListItem;
                                    if (item.Delete)
                                    {
                                        listBoxStatuses.Items.RemoveAt(idx);
                                        break;
                                    }
                                }
                            }
                        }
                        break;
                    case ProgressOp.LIST_SELECT:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            int index = (int)e.UserState;
                            if (index >= listBoxStatuses.Items.Count)
                            {
                                index = -1;
                            }
                            listBoxStatuses.SelectedIndex = index;
                        }
                        break;
                    case ProgressOp.LIST_CLEAR:
                        listBoxStatuses.Items.Clear();
                        break;
                    case ProgressOp.LIST_TOP_INDEX:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            int index = (int)e.UserState;
                            if (index < listBoxStatuses.Items.Count)
                            {
                                listBoxStatuses.TopIndex = index;
                            }
                        }
                        break;
                    case ProgressOp.LIST_SEARCH_BEGIN_UPDATE:
                        listBoxSearch.BeginUpdate();
                        break;
                    case ProgressOp.LIST_SEARCH_END_UPDATE:
                        listBoxSearch.EndUpdate();
                        break;
                    case ProgressOp.LIST_SEARCH_ADD:
                        if (e.UserState.GetType() == typeof(IListItem))
                        {
                            listBoxSearch.Items.Add(e.UserState);
                        }
                        break;
                    case ProgressOp.LIST_SEARCH_INSERT:
                        if (e.UserState.GetType() == typeof(IListItem))
                        {
                            IListItem item = e.UserState as IListItem;
                            listBoxSearch.Items.Insert(item.Index, item);
                        }
                        break;
                    case ProgressOp.LIST_SEARCH_REPLACE:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            int idx = (int)e.UserState;
                            IListItem item = listBoxSearch.Items[idx] as IListItem;
                            item.Value++;
                            listBoxSearch.Items[idx] = new IListItem(item);
                        }
                        break;
                    case ProgressOp.LIST_SEARCH_DELETE:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            IListItem item = listBoxSearch.Items[(int)e.UserState] as IListItem;
                            item.Delete = true;
                        }
                        break;
                    case ProgressOp.LIST_SEARCH_REMOVE:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            listBoxSearch.Items.RemoveAt((int)e.UserState);
                        }
                        break;
                    case ProgressOp.LIST_SEARCH_REMOVES:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            int count = (int)e.UserState;
                            for (int i = 0; i < count; i++)
                            {
                                for (int idx = 0; idx < listBoxSearch.Items.Count; idx++)
                                {
                                    IListItem item = listBoxSearch.Items[idx] as IListItem;
                                    if (item.Delete)
                                    {
                                        listBoxSearch.Items.RemoveAt(idx);
                                        break;
                                    }
                                }
                            }
                        }
                        break;
                    case ProgressOp.LIST_SEARCH_SELECT:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            int index = (int)e.UserState;
                            if (index >= listBoxSearch.Items.Count)
                            {
                                index = -1;
                            }
                            listBoxSearch.SelectedIndex = index;
                        }
                        break;
                    case ProgressOp.LIST_SEARCH_CLEAR:
                        listBoxSearch.Items.Clear();
                        break;
                    case ProgressOp.LIST_SEARCH_TOP_INDEX:
                        if (e.UserState.GetType() == typeof(int))
                        {
                            int index = (int)e.UserState;
                            if (index < listBoxSearch.Items.Count)
                            {
                                listBoxSearch.SelectedIndex = index;
                            }
                        }
                        break;
                }
            }
            catch (SystemException ex)
            {
                Debug.WriteLine("backgroundWorker_ProgressChanged() Error\n" +
                    "ProgressPercentage: " + e.ProgressPercentage + "\n" +
                    "UserState: " + e.UserState + "\n" +
                    ex.Message + "\n" + "Source: " + ex.Source);
            }
        }

        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                if (e.Cancelled)
                {
                    m_fBgBusy = false;
                    Close();
                }
                else
                {
                    if (e.Result != null)
                    {
                        if (e.Result.GetType() == typeof(IResuleGetDirectMessage))
                        {
                            IResuleGetDirectMessage result = e.Result as IResuleGetDirectMessage;
                            StartDirectMessageTimer(DateTime.Now);
                            NotifyFlash(result);
                        }
                        else if (e.Result.GetType() == typeof(IResultGetReplies))
                        {
                            IResultGetReplies result = e.Result as IResultGetReplies;
                            StartRepliesTimer(DateTime.Now);
                            NotifyFlash(result);
                        }
                        else if (e.Result.GetType() == typeof(IResultGetFollowing))
                        {
                            IResultGetFollowing result = e.Result as IResultGetFollowing;
                            StartFollowingTimer(DateTime.Now);
                            NotifyFlash(result);
                        }
                        else if (e.Result.GetType() == typeof(IResultUpdate))
                        {
                            IResultUpdate result = e.Result as IResultUpdate;
                            if (notifyIcon.Visible)
                            {
                                if (result.Success)
                                {
                                    m_Post.ClearText();
                                    m_Post.EnableText();
                                    m_Post.Hide();
                                }
                                else
                                {
                                    m_Post.EnableText();
                                }
                            }
                            else
                            {
                                if (result.Success)
                                {
                                    m_ReplyTo = 0;
                                    textBoxStatus.Text = "";
                                    textBoxStatus.Enabled = true;
                                    textBoxStatus_Leave(textBoxStatus, new EventArgs());
                                }
                                else
                                {
                                    textBoxStatus.Enabled = true;
                                }
                            }
                        }
                        else if (e.Result.GetType() == typeof(IResultInit))
                        {
                            if (Properties.Settings.Default.RetrieveStartup)
                            {
                                GetFollowingTimeline();
                                GetReplies();
                                StartTimer();
                            }
                            else
                            {
                                StartTimelineTimer();
                            }
                            toolStripButtonRefresh.Enabled = true;
                            toolStripButtonOffline.Enabled = true;
                            toolStripTextBoxSearch.Enabled = true;
                            toolStripSplitButtonSearch.Enabled = true;
                            textBoxStatus.Enabled = true;
                            comboBoxLocation.Enabled = true;
                        }
                    }
                    if (m_Loading < m_Load)
                    {
                        RequestLoad();
                    }
                    if (m_BgWork.Count != 0)
                    {
                        m_BgWork.RemoveFirst();
                    }
                    if (m_BgWork.Count != 0)
                    {
                        try
                        {
                            backgroundWorker.RunWorkerAsync(m_BgWork.First.Value);
                        }
                        catch (SystemException ex)
                        {
                            m_fBgBusy = false;
                            Debug.WriteLine("backgroundWorker_RunWorkerCompleted() Error\n" +
                                ex.Message + "\n" + "Source: " + ex.Source);
                        }
                    }
                    else
                    {
                        m_fBgBusy = false;
                    }
                }
            }
            catch (SystemException ex)
            {
                Debug.WriteLine("backgroundWorker_RunWorkerCompleted() Error\n" +
                    ex.Message + "\n" + "Source: " + ex.Source);
            }
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            if (!toolStripButtonOffline.Checked)
            {
                DateTime now = DateTime.Now;
                TimeSpan span = now - m_TimeFollowing - m_SpanOfflineFollowing;
                if (m_fEnableFollowing && (Properties.Settings.Default.IntervalFriends > 0))
                {
                    if (span.TotalMinutes >= Properties.Settings.Default.IntervalFriends)
                    {
                        GetFollowingTimeline();
                    }
                    else
                    {
                        TimeSpan interval = new TimeSpan((long)Properties.Settings.Default.IntervalFriends * 10000000 * 60);
                        span = (m_TimeFollowing + interval) - now + m_SpanOfflineFollowing;
                        if ((span.TotalMinutes >= 1) && (span.Seconds == 0) && (span.TotalMinutes != m_SpanFollowing.TotalMinutes))
                        {
                            m_SpanFollowing = span;
                            SetToolStripStatusLabelText("Following タイムライン取得まで、あと " + span.Minutes + " 分");
                        }
                        else if ((span.TotalMinutes < 1) && (span.TotalSeconds != m_SpanFollowing.TotalSeconds))
                        {
                            m_SpanFollowing = span;
                            if ((span.Seconds == 29) ||
                                (span.Seconds == 19) ||
                                (span.Seconds == 14) ||
                                (span.Seconds < 10))
                                SetToolStripStatusLabelText("Following タイムライン取得まで、あと  " + (span.Seconds + 1) + " 秒");
                        }
                    }
                }
                span = now - m_TimeReplies - m_SpanOfflineReplies;
                if (m_fEnableReplies &&
                    (Properties.Settings.Default.IntervalReplies > 0) &&
                    (span.TotalMinutes >= Properties.Settings.Default.IntervalReplies))
                {
                    GetReplies();
                }
                span = now - m_TimeDM - m_SpanOfflineDM;
                if (m_fEnableDM &&
                    (Properties.Settings.Default.IntervalDM > 0) &&
                    (span.TotalMinutes >= Properties.Settings.Default.IntervalDM))
                {
                    GetDirectMessage();
                }
            }
            StartUserStreamThread();
            CheckUserStream();
        }

        private void toolStripTextBoxSearch_Enter(object sender, EventArgs e)
        {
            if (toolStripTextBoxSearch.ForeColor == Color.FromKnownColor(KnownColor.GrayText))
            {
                toolStripTextBoxSearch.ForeColor = Color.FromKnownColor(KnownColor.WindowText);
                toolStripTextBoxSearch.Text = "";
                toolStripTextBoxSearch.TextBoxTextAlign = HorizontalAlignment.Left;
            }
        }

        private void toolStripTextBoxSearch_Leave(object sender, EventArgs e)
        {
            if (toolStripTextBoxSearch.Text == "")
            {
                toolStripTextBoxSearch.ForeColor = Color.FromKnownColor(KnownColor.GrayText);
                toolStripTextBoxSearch.Text = toolStripTextBoxSearchKind();
                toolStripTextBoxSearch.TextBoxTextAlign = HorizontalAlignment.Right;
            }
        }

        private string toolStripTextBoxSearchKind()
        {
            if (toolStripMenuItemUser.Checked)
            {
                return "ユーザ";
            }
            else if (toolStripMenuItemStatus.Checked)
            {
                return "ステータス";
            }
            else if (toolStripMenuItemLocation.Checked)
            {
                return "場所";
            }
            else if (toolStripMenuItemSource.Checked)
            {
                return "from source";
            }
            else if (toolStripMenuItemSearchReply.Checked)
            {
                return "@Reply";
            }
            else if (toolStripMenuItemSearchDM.Checked)
            {
                return "Direct Message";
            }
            return "全て";
        }

        private void SetToolStripTextBoxSearchKind()
        {
            if (toolStripTextBoxSearch.ForeColor == Color.FromKnownColor(KnownColor.GrayText))
            {
                toolStripTextBoxSearch.Text = toolStripTextBoxSearchKind();
            }
        }

        private void toolStripTextBoxSearch_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r')
            {
                e.Handled = true;
                toolStripSplitButtonSearch.PerformButtonClick();
            }
        }

        private void toolStripSplitButtonSearch_ButtonClick(object sender, EventArgs e)
        {
            DataSetChattr.TableStatusDataTable changes = null;
            m_MutexStatus.WaitOne();
            try
            {
                changes = dataSetChattr.TableStatus.GetChanges() as DataSetChattr.TableStatusDataTable;
                dataSetChattr.AcceptChanges();
            }
            catch (SystemException ex)
            {
                Debug.WriteLine("dataSetChattr.TableStatus.GetChanges() Error\n" +
                    "in toolStripSplitButtonSearch_ButtonClick()" +
                    ex.Message + "\n" + "Source: " + ex.Source);
            }
            finally
            {
                m_MutexStatus.ReleaseMutex();
            }
            if ((changes != null) && (changes.Rows.Count > 0))
            {
                using (changes)
                {
                    CommitTableStatus(changes);
                }
            }
            m_MutexSearch.WaitOne();
            try
            {
                if ((!toolStripMenuItemSearchReply.Checked && !toolStripMenuItemSearchDM.Checked) && ((toolStripTextBoxSearch.Text == "") || (toolStripTextBoxSearch.ForeColor == Color.FromKnownColor(KnownColor.GrayText))))
                {
                    if (m_TblSearch != null)
                    {
                        m_TblSearch = null;
                    }
                }
                else
                {
                    if ((toolStripTextBoxSearch.Text == "") || (toolStripTextBoxSearch.ForeColor == Color.FromKnownColor(KnownColor.GrayText)))
                    {
                        m_Search = "%";
                    }
                    else if (toolStripMenuItemLocation.Checked)
                    {
                        m_Search = "%L:" + toolStripTextBoxSearch.Text + "%";
                    }
                    else
                    {
                        m_Search = "%" + toolStripTextBoxSearch.Text + "%";
                    }
                    m_TblSearch = SearchStatus(m_Search);
                    if (m_TblSearch != null)
                    {
                        listBoxSearch.BeginUpdate();
                        listBoxSearch.Items.Clear();
                        foreach (DataSetChattr.TableStatusRow row in m_TblSearch.Rows)
                        {
                            listBoxSearch.Items.Add(new IListItem(row.id, 0));
                        }
                        listBoxSearch.EndUpdate();
                        if (m_TblSearch.Rows.Count > 0)
                        {
                            listBoxSearch.SelectedIndex = 0;
                        }
                    }
                }
                if (m_TblSearch != null)
                {
                    listBoxStatuses.TabStop = false;
                    listBoxStatuses.Visible = false;
                    listBoxSearch.TabStop = true;
                    listBoxSearch.Visible = true;
                }
                else
                {
                    listBoxSearch.TabStop = false;
                    listBoxSearch.Visible = false;
                    listBoxStatuses.TabStop = true;
                    listBoxStatuses.Visible = true;
                }
                toolStripLabelStatuses.Text = NumStatus();
            }
            catch (SystemException ex)
            {
                Debug.WriteLine("toolStripSplitButtonSearch_ButtonClick() Error\n" +
                    ex.Message + "\n" + "Source: " + ex.Source);
            }
            finally
            {
                m_MutexSearch.ReleaseMutex();
            }
        }

        private bool toolStripMenuItemReplyDM()
        {
            return toolStripMenuItemSearchReply.Checked || toolStripMenuItemSearchDM.Checked;
        }

        private void toolStripMenuItemAll_Click(object sender, EventArgs e)
        {
            bool check = toolStripMenuItemReplyDM();
            toolStripMenuItemUser.Checked = false;
            toolStripMenuItemStatus.Checked = false;
            toolStripMenuItemLocation.Checked = false;
            toolStripMenuItemSource.Checked = false;
            toolStripMenuItemSearchReply.Checked = false;
            toolStripMenuItemSearchDM.Checked = false;
            toolStripMenuItemAll.Checked = true;
            toolStripMenuItemAll.CheckState = CheckState.Indeterminate;
            SetToolStripTextBoxSearchKind();
            if (check)
            {
                toolStripSplitButtonSearch.PerformButtonClick();
            }
        }

        private void toolStripMenuItemUser_Click(object sender, EventArgs e)
        {
            bool check = toolStripMenuItemReplyDM();
            toolStripMenuItemAll.Checked = false;
            toolStripMenuItemStatus.Checked = false;
            toolStripMenuItemLocation.Checked = false;
            toolStripMenuItemSource.Checked = false;
            toolStripMenuItemSearchReply.Checked = false;
            toolStripMenuItemSearchDM.Checked = false;
            toolStripMenuItemUser.Checked = true;
            toolStripMenuItemUser.CheckState = CheckState.Indeterminate;
            SetToolStripTextBoxSearchKind();
            if (check)
            {
                toolStripSplitButtonSearch.PerformButtonClick();
            }
        }

        private void toolStripMenuItemStatus_Click(object sender, EventArgs e)
        {
            bool check = toolStripMenuItemReplyDM();
            toolStripMenuItemAll.Checked = false;
            toolStripMenuItemUser.Checked = false;
            toolStripMenuItemLocation.Checked = false;
            toolStripMenuItemSource.Checked = false;
            toolStripMenuItemSearchReply.Checked = false;
            toolStripMenuItemSearchDM.Checked = false;
            toolStripMenuItemStatus.Checked = true;
            toolStripMenuItemStatus.CheckState = CheckState.Indeterminate;
            SetToolStripTextBoxSearchKind();
            if (check)
            {
                toolStripSplitButtonSearch.PerformButtonClick();
            }
        }

        private void toolStripMenuItemLocation_Click(object sender, EventArgs e)
        {
            bool check = toolStripMenuItemReplyDM();
            toolStripMenuItemAll.Checked = false;
            toolStripMenuItemUser.Checked = false;
            toolStripMenuItemStatus.Checked = false;
            toolStripMenuItemSource.Checked = false;
            toolStripMenuItemSearchReply.Checked = false;
            toolStripMenuItemSearchDM.Checked = false;
            toolStripMenuItemLocation.Checked = true;
            toolStripMenuItemLocation.CheckState = CheckState.Indeterminate;
            SetToolStripTextBoxSearchKind();
            if (check)
            {
                toolStripSplitButtonSearch.PerformButtonClick();
            }
        }

        private void toolStripMenuItemSource_Click(object sender, EventArgs e)
        {
            bool check = toolStripMenuItemReplyDM();
            toolStripMenuItemAll.Checked = false;
            toolStripMenuItemUser.Checked = false;
            toolStripMenuItemStatus.Checked = false;
            toolStripMenuItemLocation.Checked = false;
            toolStripMenuItemSearchReply.Checked = false;
            toolStripMenuItemSearchDM.Checked = false;
            toolStripMenuItemSource.Checked = true;
            toolStripMenuItemSource.CheckState = CheckState.Indeterminate;
            SetToolStripTextBoxSearchKind();
            if (check)
            {
                toolStripSplitButtonSearch.PerformButtonClick();
            }
        }

        private void toolStripMenuItemSearchReply_Click(object sender, EventArgs e)
        {
            toolStripMenuItemAll.Checked = false;
            toolStripMenuItemUser.Checked = false;
            toolStripMenuItemStatus.Checked = false;
            toolStripMenuItemLocation.Checked = false;
            toolStripMenuItemSource.Checked = false;
            toolStripMenuItemSearchDM.Checked = false;
            toolStripMenuItemSearchReply.Checked = true;
            toolStripMenuItemSearchReply.CheckState = CheckState.Indeterminate;
            SetToolStripTextBoxSearchKind();
            toolStripSplitButtonSearch.PerformButtonClick();
        }

        private void toolStripMenuItemSearchDM_Click(object sender, EventArgs e)
        {
            toolStripMenuItemAll.Checked = false;
            toolStripMenuItemUser.Checked = false;
            toolStripMenuItemStatus.Checked = false;
            toolStripMenuItemLocation.Checked = false;
            toolStripMenuItemSource.Checked = false;
            toolStripMenuItemSearchReply.Checked = false;
            toolStripMenuItemSearchDM.Checked = true;
            toolStripMenuItemSearchDM.CheckState = CheckState.Indeterminate;
            SetToolStripTextBoxSearchKind();
            toolStripSplitButtonSearch.PerformButtonClick();
        }

        private void toolStripMenuItemLocationAdd_Click(object sender, EventArgs e)
        {
            if ((comboBoxLocation.ForeColor != Color.FromKnownColor(KnownColor.GrayText)) && (comboBoxLocation.Text != ""))
            {
                bool add = true;
                foreach (string location in comboBoxLocation.Items)
                {
                    if (location == comboBoxLocation.Text)
                    {
                        add = false;
                        break;
                    }
                }
                if (add)
                {
                    comboBoxLocation.Items.Add(comboBoxLocation.Text);
                }
            }
        }

        private void toolStripMenuItemLocationDelete_Click(object sender, EventArgs e)
        {
            if (comboBoxLocation.ForeColor != Color.FromKnownColor(KnownColor.GrayText))
            {
                foreach (string location in comboBoxLocation.Items)
                {
                    if (location == comboBoxLocation.Text)
                    {
                        comboBoxLocation.Items.Remove(comboBoxLocation.Text);
                        break;
                    }
                }
            }
        }

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            toolStripMenuItemTaskTrayIconOpen.PerformClick();
        }

        private void toolStripMenuItemTaskTrayIconOpen_Click(object sender, EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
            this.Activate();
            notifyIcon.Visible = false;
        }

        private void toolStripMenuItemTaskTrayIconPreferences_Click(object sender, EventArgs e)
        {
            toolStripButtonPreferences.PerformClick();
        }

        private void toolStripMenuItemTaskTrayIconRefresh_Click(object sender, EventArgs e)
        {
            toolStripButtonRefresh.PerformClick();
        }

        private void toolStripMenuItemTaskTrayIconOffline_Click(object sender, EventArgs e)
        {
            toolStripButtonOffline.PerformClick();
        }

        private void toolStripMenuItemTaskTrayIconPost_Click(object sender, EventArgs e)
        {
            m_Post.Show();
        }

        private void toolStripMenuItemTaskTrayIconQuit_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void contextMenuStripStatuses_Opening(object sender, CancelEventArgs e)
        {
            ListBox listBox = listBoxStatuses;
            DataSetChattr.TableStatusDataTable table = dataSetChattr.TableStatus;
            Mutex mutex = m_MutexStatus;
            if (m_TblSearch != null)
            {
                listBox = listBoxSearch;
                table = m_TblSearch;
                mutex = m_MutexSearch;
            }
            int idx = listBox.SelectedIndex;
            if ((idx >= 0) && (idx < listBox.Items.Count))
            {
                mutex.WaitOne();
                try
                {
                    DataSetChattr.TableStatusRow row = table.Rows[idx] as DataSetChattr.TableStatusRow;
                    if (row.RowState != DataRowState.Deleted)
                    {
                        StatusParser parser = new StatusParser(row.text);
                        contextMenuStripStatusesMake(contextMenuStripStatuses, row, parser, true);
                    }
                }
                catch (SystemException ex)
                {
                    Debug.WriteLine("contextMenuStripStatuses_Opening() Error\n" +
                        ex.Message + "\n" + "Source: " + ex.Source);
                }
                finally
                {
                    mutex.ReleaseMutex();
                }
            }
        }

        private void toolStripMenuItemButtonPreferences_Click(object sender, EventArgs e)
        {
            toolStripButtonPreferences.PerformClick();
        }

        private void toolStripMenuItemButtonTimeline_Click(object sender, EventArgs e)
        {
            toolStripButtonRefresh.PerformClick();
        }

        private void toolStripMenuItemButtonReplies_Click(object sender, EventArgs e)
        {
            toolStripButtonRefresh.PerformClick();
        }

        private void toolStripMenuItemButtonUser_Click(object sender, EventArgs e)
        {
            toolStripButtonRefresh.PerformClick();
        }

        private void toolStripMenuItemButtonDirect_Click(object sender, EventArgs e)
        {
            toolStripButtonRefresh.PerformClick();
        }

        private void toolStripMenuItemButtonOffline_Click(object sender, EventArgs e)
        {
            toolStripButtonOffline.PerformClick();
        }

        private void toolStripMenuItemButtonExecQuery_Click(object sender, EventArgs e)
        {
            toolStripSplitButtonSearch.PerformButtonClick();
        }

        private void toolStripMenuItemButtonQueryMenu_Click(object sender, EventArgs e)
        {
            toolStripSplitButtonSearch.ShowDropDown();
        }

        private void toolStripMenuItemFocusStatuses_Click(object sender, EventArgs e)
        {
            ListBox listBox = listBoxStatuses;
            if (m_TblSearch != null)
            {
                listBox = listBoxSearch;
            }
            listBox.Focus();
        }

        private void toolStripMenuItemFocusWhatAreYouDoing_Click(object sender, EventArgs e)
        {
            textBoxStatus.Focus();
        }

        private void toolStripMenuItemFocusLocation_Click(object sender, EventArgs e)
        {
            comboBoxLocation.Focus();
        }

        private void toolStripMenuItemFocusSearch_Click(object sender, EventArgs e)
        {
            toolStripTextBoxSearch.Focus();
        }

        private void toolStripMenuItemContextMenu_Click(object sender, EventArgs e)
        {
            ListBox listBox = listBoxStatuses;
            Mutex mutex = m_MutexStatus;
            if (m_TblSearch != null)
            {
                listBox = listBoxSearch;
                mutex = m_MutexSearch;
            }
            if (!listBox.ContextMenuStrip.Visible)
            {
                mutex.WaitOne();
                try
                {
                    Rectangle rect = listBox.RectangleToScreen(listBox.GetItemRectangle(listBox.SelectedIndex));
                    contextMenuStripStatuses.Show(rect.X, rect.Y + rect.Height);
                }
                finally
                {
                    mutex.ReleaseMutex();
                }
            }
        }

        private void contextMenuStrip_Opening(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
        }
    }
}