// 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: FormLog.cs 183 2009-02-08 16:02:06Z 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.Threading;

using System.Diagnostics;

namespace Chattr
{
    public partial class FormLog : Form
    {
        private FormMain m_FormMain;
        private int m_ListWidth;
        private Mutex m_Mutex;
        private DataSetChattr.TableStatusDataTable m_Statuses;
        private DataSetChattr.TableProfileImageDataTable m_ProfileImage;
        private LinkedList<DataSetChattr.TableStatusRow> m_List;

        private bool m_Loaded;

        private int m_Page;

        public DataSetChattr.TableProfileImageDataTable ProfileImage
        {
            get
            {
                return m_ProfileImage;
            }
            set
            {
                m_ProfileImage = value;
            }
        }

        public FormLog(FormMain formMain)
        {
            m_FormMain = formMain;
            m_Loaded = false;
            m_Mutex = new Mutex();
            m_Statuses = new DataSetChattr.TableStatusDataTable();
            m_List = new LinkedList<DataSetChattr.TableStatusRow>();
            m_ProfileImage = null;
            InitializeComponent();
            m_ListWidth = listBox.Width;
        }

        private void FormLog_Load(object sender, EventArgs e)
        {
            m_Page = 0;
            m_Loaded = true;
            UpdateListBox();
        }

        private void FormLog_FormClosing(object sender, FormClosingEventArgs e)
        {
            m_Loaded = false;
        }

        private void FormLog_SizeChanged(object sender, EventArgs e)
        {
            if (listBox.Width > 0)
            {
                m_ListWidth = listBox.Width;
            }
        }

        private void toolStripButtonUp_Click(object sender, EventArgs e)
        {
            m_Page++;
            toolStripLabelPage.Text = "Page " + m_Page;
            m_FormMain.GetFollowingTimelineViaPage(m_Page);
        }

        private float m_IconWith = 0;

        private void listBox_MeasureItem(object sender, MeasureItemEventArgs e)
        {
            e.ItemHeight = FormMain.listBox_MeasureItem(listBox, e, m_Statuses, m_Mutex, m_ListWidth, ref m_IconWith);
        }

        private void listBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            FormMain.listBox_DrawItem(listBox, e, m_Statuses, m_Mutex, m_ProfileImage);
        }

        private void UpdateListBox()
        {
            if (m_Loaded)
            {
                try
                {
                    MethodInvoker update = delegate
                    {
                        listBox.BeginUpdate();
                        listBox.Items.Clear();
                        foreach (DataSetChattr.TableStatusRow row in m_Statuses.Rows)
                        {
                            listBox.Items.Add(new IListItemAdd(row.id, 0));
                        }
                        listBox.EndUpdate();
                    };
                    if (this.InvokeRequired)
                    {
                        Invoke(update);
                    }
                    else
                    {
                        update();
                    }
                }
                catch (SystemException ex)
                {
                    Debug.WriteLine("UpdateListBox() Error\n" +
                        ex.Message + "\n" + "Source: " + ex.Source);
                }
            }
        }

        public void ClearTmpStatuses()
        {
            m_Mutex.WaitOne();
            try
            {
                m_List.Clear();
            }
            finally
            {
                m_Mutex.ReleaseMutex();
            }
        }

        public void AddRow(DataSetChattr.TableStatusRow row)
        {
            m_Mutex.WaitOne();
            try
            {
                m_List.AddFirst(row);
            }
            catch (SystemException ex)
            {
                Debug.WriteLine("AddRow() Error\n" +
                    ex.Message + "\n" + "Source: " + ex.Source);
            }
            finally
            {
                m_Mutex.ReleaseMutex();
            }
        }

        public void UpdateStatuses()
        {
            m_Mutex.WaitOne();
            try
            {
                m_Statuses.Rows.Clear();
                LinkedListNode<DataSetChattr.TableStatusRow> node = m_List.First;
                while (node != null)
                {
                    DataSetChattr.TableStatusRow row = m_Statuses.NewRow() as DataSetChattr.TableStatusRow;
                    row.id = node.Value.id;
                    row.created_at = node.Value.created_at;
                    row.text = node.Value.text;
                    row.source = node.Value.source;
                    row.source_url = node.Value.source_url;
                    row.user_id = node.Value.user_id;
                    row.user_screen_name = node.Value.user_screen_name;
                    row.user_name = node.Value.user_name;
                    row.user_location = node.Value.user_location;
                    row.user_profile_image = node.Value.user_profile_image;
                    row.flags = node.Value.flags & ~FormMain.FLAG_NEW;
                    m_Statuses.Rows.Add(row);
                    node = node.Next;
                    Debug.WriteLine(row.created_at + " " + row.user_screen_name + ": " + row.text);
                }
            }
            catch (SystemException ex)
            {
                Debug.WriteLine("UpdateStatuses() Error\n" +
                    ex.Message + "\n" + "Source: " + ex.Source);
            }
            finally
            {
                m_Mutex.ReleaseMutex();
            }
            UpdateListBox();
        }

        public void SetStatusBar(string text)
        {
            MethodInvoker set = delegate
            {
                toolStripStatusLabel.Text = text;
            };
            if (this.InvokeRequired)
            {
                Invoke(set);
            }
            else
            {
                set();
            }
        }
    }
}