// Copyright (C) 2003 Daisuke Arai <darai@users.sourceforge.jp>
// Copyright (C) 2004-2006 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: SystemLog.cs 306 2010-03-19 13:21:22Z panacoran $

using System;
using System.Collections;

namespace Protra.Lib.Db
{
	/// <summary>
	/// 注文の種類を表す。
	/// </summary>
	public enum Order
	{
		/// <summary>
		/// 売り。
		/// </summary>
		Buy,
		/// <summary>
		/// 買い。
		/// </summary>
		Sell
	}

	/// <summary>
	/// SystemLogテーブルのレコードを表す。
	/// </summary>
	public class SystemLog: IRecord
	{
		private int systemId;
		private int brandId;
		private DateTime date;
		private int price;
		private int number;
		private Order order;

		/// <summary>
		/// 既定のコンストラクタ
		/// </summary>
		public SystemLog() {}

		/// <summary>
		/// コンストラクタ
		/// </summary>
		public SystemLog(int systemId, int brandId, DateTime date,
						 int price, int number, Order order)
		{
			this.systemId = systemId;
			this.brandId = brandId;
			this.date = date;
			this.price = price;
			this.number = number;
			this.order = order;
		}

		/// <summary>
		/// システムIdを取得する。
		/// </summary>
		public int SystemId
		{
			get { return systemId; }
		}

		/// <summary>
		/// システムIDに対応するSystemオブジェクトを取得する。
		/// </summary>
		public TradingSystem System
		{
			get { return SystemTable.GetRecord(systemId); }
		}

		/// <summary>
		/// 銘柄IDを取得する。
		/// </summary>
		public int BrandId
		{
			get { return brandId; }
		}

		/// <summary>
		/// 銘柄IDに対応するBrandオブジェクトを取得する。
		/// </summary>
		public Brand Brand
		{
			get { return BrandTable.GetRecord(brandId); }
		}

		/// <summary>
		/// Dateを取得する。
		/// </summary>
		public DateTime Date
		{
			get { return date; }
		}

		/// <summary>
		/// 価格を取得する。
		/// </summary>
		public int Price
		{
			get { return price; }
		}

		/// <summary>
		/// 数量を取得する。
		/// </summary>
		public int Number
		{
			get { return number; }
		}

		/// <summary>
		/// Orderを取得します。
		/// </summary>
		public Order Order
		{
			get { return order; }
		}

		/// <summary>
		/// データベースのレコードをオブジェクトに変換する。
		/// </summary>
		/// <param name="values">ネイティブ形式の値の配列</param>
		/// <returns>変換後のSystemLogオブジェクトを返す。</returns>
		public Object ToObject(Object[] values)
		{
			return new SystemLog((int)values[0], // @SystemId
								 (int)values[1], // @BrandId
								 (DateTime)values[2], // @Date
								 (int)values[3], // @Price
								 (int)values[4], // @Number
								 (Order)values[5]); // @Order
		}

		/// <summary>
		/// インスタンスを文字列表現に変換する。
		/// </summary>
		/// <returns>文字列表現</returns>
		public override string ToString()
		{
			return string.Format(
				"SystemLog[SystemId={0}, BrandId={1}, {2}, " +
				"Price={3}, Number={4}, Order={5}]",
				systemId, brandId, date, price, number, order);
		}
	}

	/// <summary>
	/// SystemLogテーブルを操作する。
	/// </summary>
	public class SystemLogTable
	{
		private static Connection conn;
		private static Connection Conn
		{
			get 
			{
				if (conn != null)
					return conn;
				conn = new Connection("protra");
				return conn;
			}
		}

		/// <summary>
		/// 指定されたシステムIDと銘柄IDのログを取得する。
		/// </summary>
		/// <param name="systemId">システムID</param>
		/// <param name="brandId">銘柄ID</param>
		/// <returns>日付順にソートされたSystemLogオブジェクトの配列。</returns>
		public static SystemLog[] GetRecords(int systemId, int brandId)
		{
			string sql = string.Format(
				"SELECT * FROM SystemLog " +
				"WHERE @SystemId={0} AND @BrandId={1} ORDER BY @Date",
				systemId, brandId);
			ArrayList result = Conn.Query(sql, new SystemLog());
			return (SystemLog[])result.ToArray(typeof(SystemLog));
		}

		/// <summary>
		/// 指定されたシステムIDと指定期間のログを取得する。
		/// </summary>
		/// <param name="systemId">システムID</param>
		/// <param name="minDate">日付の最小値</param>
		/// <param name="maxDate">日付の最大値</param>
		/// <returns>日付の降順にソートされたSystemLogオブジェクトの配列。</returns>
		public static SystemLog[] GetRecords(
			int systemId, DateTime minDate, DateTime maxDate)
		{
			string sql = string.Format(
				"SELECT * FROM SystemLog " +
				"WHERE @SystemId={0} AND @Date>=#{1}# AND @Date<=#{2}# " +
				"ORDER BY @Date DESC, @BrandId", systemId,
				minDate.ToString("d"),
				maxDate.ToString("d"));
			ArrayList result = Conn.Query(sql, new SystemLog());
			return (SystemLog[])result.ToArray(typeof(SystemLog));
		}

		/// <summary>
		/// レコードを追加する。
		/// </summary>
		/// <param name="systemId">システムID</param>
		/// <param name="brandId">銘柄ID</param>
		/// <param name="date">日付</param>
		/// <param name="price">価格</param>
		/// <param name="number">数量</param>
		/// <param name="order">注文</param>
		public static SystemLog Add(
			int systemId, int brandId, DateTime date, int price, int number, Order order)
		{
			string sql = string.Format(
				"INSERT INTO SystemLog VALUES({0}, {1}, #{2}#, {3}, {4}, {5})",
				systemId, brandId, date.ToString("d"),
				price, number, (int)order);
			Conn.Execute(sql);
			return new SystemLog(systemId, brandId, date,
								 price, number, order);
		}

		/// <summary>
		/// 指定されたシステムIDのログを削除する。
		/// </summary>
		/// <param name="systemId">システムID</param>
		public static void Delete(int systemId)
		{
			string sql = string.Format(
				"DELETE FROM SystemLog WHERE @SystemId={0}", systemId);
			Conn.Execute(sql);
		}

		/// <summary>
		/// 指定されたシステムIDと銘柄IDのログを削除する
		/// </summary>
		/// <param name="systemId">システムID</param>
		/// <param name="brandId">銘柄ID</param>
		public static void Delete(int systemId, int brandId)
		{
			string sql = string.Format(
				"DELETE FROM SystemLog WHERE @SystemId={0} AND @BrandId={1}",
				systemId, brandId);
			Conn.Execute(sql);
		}

		/// <summary>
		/// 全データを削除する。
		/// </summary>
		public static void Delete()
		{
			string sql = "DELETE FROM SystemLog";
			Conn.Execute(sql);
		}
	}
}
