// Copyright (C) 2003 Daisuke Arai <darai@users.sourceforge.jp>
// Copyright (C) 2005-2008 panacoran <panacoran@users.sourceforge.jp>
// 
// This program is part of Protra.
//
// Protra is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
// 
// $Id: PriceUpdateDialog.cs,v 1.15 2008-02-07 22:59:04 panacoran Exp $

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using Protra.Lib.Db;
using Protra.Lib.Update;
using Protra.Lib.Dialogs;

namespace Protra.Dialogs
{
	/// <summary>
	/// 株価データを更新するダイアログです。
	/// </summary>
	public class PriceUpdateDialog : System.Windows.Forms.Form
	{
        private PriceDataUpdator updator;
        private Option option;
		private DateTime beginDate;

		private System.Windows.Forms.Label labelInfo;
		private System.Windows.Forms.Button buttonStop;
		private System.Windows.Forms.ProgressBar progressBar;
        private BackgroundWorker backgroundWorkerUpdate;
		/// <summary>
		/// 必要なデザイナ変数です。
		/// </summary>
		private System.ComponentModel.Container components = null;

		/// <summary>
		/// コンストラクタ
		/// </summary>
		/// <param name="option">オプションダイアログで指定された値</param>
		public PriceUpdateDialog(Option option)
		{
			//
			// Windows フォーム デザイナ サポートに必要です。
			//
			InitializeComponent();

            updator = PriceDataUpdator.Create(option);
            this.option = option;
		}

		/// <summary>
		/// 使用されているリソースに後処理を実行します。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
		/// コード エディタで変更しないでください。
		/// </summary>
		private void InitializeComponent()
		{
            this.labelInfo = new System.Windows.Forms.Label();
            this.progressBar = new System.Windows.Forms.ProgressBar();
            this.buttonStop = new System.Windows.Forms.Button();
            this.backgroundWorkerUpdate = new System.ComponentModel.BackgroundWorker();
            this.SuspendLayout();
            // 
            // labelInfo
            // 
            this.labelInfo.Location = new System.Drawing.Point(24, 16);
            this.labelInfo.Name = "labelInfo";
            this.labelInfo.Size = new System.Drawing.Size(352, 16);
            this.labelInfo.TabIndex = 0;
            this.labelInfo.Text = "更新しています";
            // 
            // progressBar
            // 
            this.progressBar.Location = new System.Drawing.Point(24, 40);
            this.progressBar.Name = "progressBar";
            this.progressBar.Size = new System.Drawing.Size(344, 16);
            this.progressBar.TabIndex = 1;
            // 
            // buttonStop
            // 
            this.buttonStop.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.buttonStop.Location = new System.Drawing.Point(296, 64);
            this.buttonStop.Name = "buttonStop";
            this.buttonStop.Size = new System.Drawing.Size(75, 24);
            this.buttonStop.TabIndex = 2;
            this.buttonStop.Text = "中断";
            this.buttonStop.Click += new System.EventHandler(this.buttonStop_Click);
            // 
            // backgroundWorkerUpdate
            // 
            this.backgroundWorkerUpdate.WorkerReportsProgress = true;
            this.backgroundWorkerUpdate.WorkerSupportsCancellation = true;
            this.backgroundWorkerUpdate.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorkerUpdate_DoWork);
            this.backgroundWorkerUpdate.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorkerUpdate_RunWorkerCompleted);
            this.backgroundWorkerUpdate.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorkerUpdate_ProgressChanged);
            // 
            // PriceUpdateDialog
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.CancelButton = this.buttonStop;
            this.ClientSize = new System.Drawing.Size(394, 93);
            this.ControlBox = false;
            this.Controls.Add(this.buttonStop);
            this.Controls.Add(this.progressBar);
            this.Controls.Add(this.labelInfo);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "PriceUpdateDialog";
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "株価データ更新";
            this.Load += new System.EventHandler(this.PriceUpdateDialog_Load);
            this.ResumeLayout(false);

		}
		#endregion

		private void PriceUpdateDialog_Load(object sender, System.EventArgs e)
		{
			// ロードされると同時に更新を開始します
			DateTime maxDate = PriceTable.MaxDate();
			if (maxDate != DateTime.MinValue)
				beginDate = maxDate.AddDays(1);
			else
			{
				// データが存在しない場合には更新開始日時を入力させる。
				InputDateDialog dateDialog = new InputDateDialog();
				dateDialog.Message = "データが存在しません。\n指定した日付以降のデータを取得します。";
                dateDialog.Value = PriceDataUpdator.GetDataSince(option.PriceDataSource);
				dateDialog.ShowDialog(this.Owner); // thisはまだ表示されていない。
				if (dateDialog.DialogResult != DialogResult.OK)
				{
					this.Close();
					return;
				}
				beginDate = dateDialog.Value;
			}
            backgroundWorkerUpdate.RunWorkerAsync((object)beginDate);
		}

        private void backgroundWorkerUpdate_DoWork(object sender, DoWorkEventArgs e)
        {
            updator.Update(sender as BackgroundWorker, e);
        }

        private void backgroundWorkerUpdate_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.labelInfo.Text = "更新しています... " + (string)e.UserState;
            this.progressBar.Value = e.ProgressPercentage;
        }

		private void buttonStop_Click(object sender, System.EventArgs e)
		{
            backgroundWorkerUpdate.CancelAsync();
		}

        private void backgroundWorkerUpdate_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(this, e.Error.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
                labelInfo.Text = "更新中にエラーが発生したため継続できません。";
                buttonStop.Text = "OK";
                return;
            }
            if (!e.Cancelled)
            {
                labelInfo.Text = "更新が完了しました。";
                buttonStop.Text = "OK";
            }
        }
	}
}
