// Copyright (C) 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: SimulateBuiltins.cs 321 2010-03-29 11:37:51Z panacoran $

using System;
using Protra.Lib.Data;

namespace Protra.Lib.Lang
{
    /// <summary>
    /// テキストを出力するデリゲート
    /// </summary>
    /// <param name="msg">出力するテキスト</param>
    public delegate void AppendTextDelegate(string msg);

    /// <summary>
    /// シミュレーション関連の組み込み関数を処理するクラス。
    /// </summary>
    public class SimulateBuiltins : BasicBuiltins
    {
        /// <summary>
        /// システムのファイル名を取得または設定する。
        /// </summary>
        public string System { get; set; }

        /// <summary>
        /// システムの実行モードを取得または設定する。
        /// </summary>
        public int Mode { get; set; }

        /// <summary>
        /// テキストを出力するデリゲートを取得または設定する。
        /// </summary>
        public AppendTextDelegate AppendText { get; set;}

        /// <summary>
        /// 組み込み関数を実行する。
        /// </summary>
        /// <param name="name">名前</param>
        /// <param name="args">引数</param>
        /// <param name="at">atパラメータ</param>
        /// <returns></returns>
        public override Value Invoke(string name, Value[] args, int at)
        {
            if (args.Length == 1)
            {
                string msg;
                switch (name)
                {
                case "Print":
                    msg = (args[0] == null) ? "null" : args[0].InnerValue.ToString();
                    break;
                case "PrintLog":
                    msg = (args[0] == null) ? "null" : args[0].InnerValue.ToString();
                    msg = string.Format(
                        "{0} {1} {2} {3}",
                        Brand.Code, Brand.Name,
                        Prices[Index + at].Date.ToString("yy/MM/dd"), msg);
                    break;
                default:
                    return base.Invoke(name, args, at);
                }
                AppendText(msg + "\r\n");
                return null;
            }
            else if (args.Length == 2)
            {
                string msg;
                var log = new Log();
                log.Date = Prices[Index + at].Date;
                log.Code = Brand.Code;
                log.Price = (int)args[0].InnerValue;
                log.Quantity = (int)args[1].InnerValue;
                msg = string.Format("{0} {1} {2} {3}円 {4}株 ",
                        Brand.Code, Brand.Name,
                        log.Date.ToString("yy/MM/dd"),
                        log.Price, log.Quantity);
                switch (name)
                {
                case "Buy":
                    log.Order = Order.Buy;
                    LogData.Add(System, Mode, log);
                    msg += "買\r\n";
                    break;
                case "Sell":
                    log.Order = Order.Sell;
                    LogData.Add(System, Mode, log);
                    msg += "売\r\n";
                    break;
                default:
                    return base.Invoke(name, args, at);
                }
                AppendText(msg);
                return null;
            }
            else
                return base.Invoke(name, args, at);
        }
    }
}
