using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using log4net;
using log4net.Config;
using MasterLinkFutures.utils;
using MasterLinkFutures.Data;
namespace MasterLinkFutures
{
    public partial class Form1 : Form
    {
        public static Form1 instance;
        private static readonly ILog log = LogManager.GetLogger(typeof(Form1));
        private static bool connTag = false;
        private static bool loginFail = false;
        BindingSource bsCur = new BindingSource();
        BindingSource bsDeal = new BindingSource();
        BindingSource bsOrder = new BindingSource();
        BindingList<QuoteData> curList = new BindingList<QuoteData>();
        BindingList<QuoteData> dealList = new BindingList<QuoteData>();
        BindingList<QuoteData> orderList = new BindingList<QuoteData>();

        public Form1()
        {
            InitializeComponent();
            XmlConfigurator.Configure(new System.IO.FileInfo(@"configs\log4net.xml"));
            log.Info("program begin");
            this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
            gTrade1.LoginReady += new AxICE_GTRADELib._DICE_gTradeEvents_LoginReadyEventHandler(gTrade1_LoginReady);
            gTrade1.LoginFail += new AxICE_GTRADELib._DICE_gTradeEvents_LoginFailEventHandler(gTrade1_LoginFail);
            gTrade1.ConnectionLost += new AxICE_GTRADELib._DICE_gTradeEvents_ConnectionLostEventHandler(gTrade1_ConnectionLost);
            gTrade1.OrderStatus += new AxICE_GTRADELib._DICE_gTradeEvents_OrderStatusEventHandler(gTrade1_OrderStatus);
            gTrade1.Log += new AxICE_GTRADELib._DICE_gTradeEvents_LogEventHandler(gTrade1_Log);
            btnDel.Click += new EventHandler(btnDel_Click);
            instance = this;
            init();
        }

        void btnDel_Click(object sender, EventArgs e)
        {
            var cc = (from c in curList
                     where c.del == true
                     select c).ToList<QuoteData>();
            foreach (QuoteData q in cc)
            {
                if (!q.del) continue;
                OrderData o = new OrderData();
                o.orderCategory = "R";  //0:委託類別
                o.account = q.account;//1:帳號
                o.symbolID = q.symbolID;//2:商品ID
                o.orderType = q.orderType;//3:委託別
                o.buySell = q.buySell;//4:買賣
                o.priceFlag = q.priceFlag;//5:價格別
                o.price = q.price;//6:委託價格
                o.qty = q.qty;//7:委託數量
                o.marketType = "";//8:市場別(證券)
                o.marketAP = "";//9:盤別(證券)
                o.dayTrade = q.dayTrade;//10:當沖 Y/N
                o.userKey = q.userKey;//11 UserKey
                o.marketNo = "";//12交易所代碼
                //o.commYM = q.;//13商品年月
                o.stopPrice = 0;//14:停損價格
                o.openClose = q.openClose;//15:倉別
                o.orderno = q.orderno;
                Form1.instance.Order(o);
            }
        }
        private void init()
        {
            //bs.DataSource = qList;
            //dGVCur.DataSource = bs;
            iniData.instance.init();
            DataTableInit();
        }
        private void DataTableInit()
        {
            dGVCur.AutoGenerateColumns = false;
            dGVCur.AllowUserToAddRows=false;
            dGVCur.RowHeadersVisible = false;
            dGVCur.Invalidate();
            bsCur.DataSource = curList;
            bsCur.ResumeBinding();
            dGVCur.DataSource = bsCur;
            dGVOrder.AutoGenerateColumns = false;
            dGVOrder.AllowUserToAddRows = false;
            dGVOrder.RowHeadersVisible = false;
            dGVOrder.Invalidate();
            bsOrder.DataSource = orderList;
            bsOrder.ResumeBinding();
            dGVOrder.DataSource = bsOrder;
            dGVDeals.AutoGenerateColumns = false;
            dGVDeals.AllowUserToAddRows = false;
            dGVDeals.RowHeadersVisible = false;
            dGVDeals.Invalidate();
            bsDeal.DataSource = dealList;
            bsDeal.ResumeBinding();
            dGVDeals.DataSource = bsDeal;

        }
        void gTrade1_Log(object sender, AxICE_GTRADELib._DICE_gTradeEvents_LogEvent e)
        {
            //log.Info(e.strLog.ToString());
        }

        void gTrade1_OrderStatus(object sender, AxICE_GTRADELib._DICE_gTradeEvents_OrderStatusEvent e)
        {
            try
            {
                QuoteData qd = new QuoteData();
                int nIndex = e.nIndex;
                qd.account = gTrade1.GetOrderString(nIndex, 0);//0帳號
                qd.orderno = gTrade1.GetOrderString(nIndex, 1);//1委託書號
                qd.symbolID = gTrade1.GetOrderString(nIndex, 2);//2商品ID
                qd.orderCategory = gTrade1.GetOrderString(nIndex, 3);//3類別
                qd.orderType = gTrade1.GetOrderString(nIndex, 4);//4委託類別
                qd.priceFlag = gTrade1.GetOrderString(nIndex, 5);//5價格別
                qd.buySell = gTrade1.GetOrderString(nIndex, 6);//6買賣
                qd.dayTrade = gTrade1.GetOrderString(nIndex, 7);//7當沖
                qd.price = gTrade1.GetOrderValue(nIndex, 7);//7(數值)委託價格
                qd.qty = (int)gTrade1.GetOrderValue(nIndex, 8);//8(數值)有效委託
                Console.WriteLine("第" + nIndex + "筆, 有效委託數量:" + gTrade1.GetOrderValue(nIndex, 8));
                qd.dealQty = (int)gTrade1.GetOrderValue(nIndex, 9);//9(數值)已成交數量
                qd.udateTime = gTrade1.GetOrderString(e.nIndex, 12);//12更新時間
                qd.status = gTrade1.GetOrderString(e.nIndex, 11);//12狀態
                qd.source = gTrade1.GetOrderString(e.nIndex, 13);//13來源別
                qd.userKey = gTrade1.GetOrderString(e.nIndex, 14);//14userKey
                qd.canData = gTrade1.GetOrderString(e.nIndex, 20);//20可見資料
                qd.memo = gTrade1.GetOrderString(e.nIndex, 24);//24備註
                string ss = gTrade1.GetOrderString(e.nIndex, 31);
                qd.gQuoteID = (gTrade1.GetOrderString(e.nIndex, 25).Length>8)?gTrade1.GetOrderString(e.nIndex, 25).Substring(8):"";//25gQuoteID
                qd.symbolID2 = gTrade1.GetOrderString(e.nIndex, 29);////29商品名稱2
                qd.buySell2 = gTrade1.GetOrderString(e.nIndex, 30);//30買賣2
                qd.gQuoteID2 = (gTrade1.GetOrderString(e.nIndex, 31).Length > 13) ? gTrade1.GetOrderString(e.nIndex, 31).Substring(8) : "";//31gQuoteID2
                //curList.Add(qd);
                Console.WriteLine(qd.toString());
                compList(qd);
            }
            catch (Exception ex) { }
        }
        private void compList(QuoteData qd)
        {
            var order = from odr in orderList
                        where odr.userKey == qd.userKey
                        select odr;
            if (order.Count() == 0) orderList.Add(qd);
            else order.ToList<QuoteData>()[0].update(qd);
            if (qd.dealQty > 0)
            {
                var deals = from deal in dealList
                            where deal.userKey == qd.userKey
                            select deal;
                if (deals.Count() == 0) dealList.Add(qd);
            }
            if (qd.qty == 0)
            {
                var curr = from cur in curList
                           where cur.userKey == qd.userKey
                           select cur;
                if (curr.Count() > 0)
                {
                    curList.Remove(curr.ToList<QuoteData>()[0]);
                }
            }
            else if (qd.qty > 0)
            {
                var curr = from cur in curList
                            where cur.userKey == qd.userKey
                            select cur;
                if (curr.Count() == 0) curList.Add(qd);
                else curr.ToList<QuoteData>()[0].update(qd);
            }
        }

        void gTrade1_ConnectionLost(object sender, AxICE_GTRADELib._DICE_gTradeEvents_ConnectionLostEvent e)
        {
            toolStripStatusLabel3.Text = ("連線中斷");
            log.Info("連線中斷");
            connTag = false;
            ConnectionStatus();
        }

        void gTrade1_LoginFail(object sender, AxICE_GTRADELib._DICE_gTradeEvents_LoginFailEvent e)
        {
            toolStripStatusLabel3.Text = e.strErrorMsg;
            log.Error("LoginFail:" + e.strErrorMsg);
            loginFail = true;
            connTag = false;
            ConnectionStatus();
        }

        void gTrade1_LoginReady(object sender, AxICE_GTRADELib._DICE_gTradeEvents_LoginReadyEvent e)
        {
            toolStripStatusLabel3.Text = ("登入成功");
            log.Info("登入成功");
            connTag = true;
            ConnectionStatus();
        }

        void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            gTrade1.Logout(iniData.instance.d.strSession1);
            log.Info("program end");
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            if (!connTag)
            {
                MessageBox.Show("請先進行連線");
                return;
            }
            FormFutures fr = new FormFutures();
            fr.Show();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            if (!connTag)
            {
                MessageBox.Show("請先進行連線");
                return;
            }
            FormOption fo = new FormOption();
            fo.Show();
        }
        private void btnConn_Click(object sender, EventArgs e)
        {
            int code = 0;
            if (!connTag)
            {
                log.Info("下單連線");
                code = gTrade1.TouchanceLogin(iniData.instance.d.profile, iniData.instance.d.strSession);
                if (code == 0)//1
                {
                    toolStripStatusLabel3.Text = ("取得授權失敗");
                    log.Error("取得授權失敗");
                    return;
                }
                gTrade1.TouchanceLoginY(iniData.instance.d.strSession);
                int result = gTrade1.Login(iniData.instance.d.profile, iniData.instance.d.strSession1);
                if (result != 3)//3
                {
                    //toolStripStatusLabel3.Text = ("連線參數錯誤");
                    toolStripStatusLabel3.Text = (rtnMsg.instance.getLoginMsg(result));
                    log.Error(rtnMsg.instance.getLoginMsg(result));
                    return;
                }
            }
            connTag = !connTag;
            loginFail = false;
            ConnectionStatus();
        }
        private void ConnectionStatus()
        {
            if (connTag)
            {
                btnConn.Text = "連線中";
                toolStripStatusLabel2.Text = "已連線";
            }
            else
            {
                log.Info("取消下單連線");
                gTrade1.Logout(iniData.instance.d.strSession1);
                btnConn.Text = "下單連線";
                toolStripStatusLabel2.Text = ("未連線");
                if(!loginFail) toolStripStatusLabel3.Text = ("---");
                curList.Clear();
                orderList.Clear();
                dealList.Clear();
            }
        }
        public void Order(OrderData o)
        {
            gTrade1.SetSecurities(1, "", 1);
            gTrade1.SetSecurities(2, "", 1);
            gTrade1.SetOrderInfoString(0, o.orderCategory);//0:委託類別,S:證券,F:期貨,O:選擇權,R:刪改單
            gTrade1.SetOrderInfoString(1, o.account);      //1:  帳號
            gTrade1.SetOrderInfoString(2, o.symbolID);     //2:  商品ID
            gTrade1.SetOrderInfoString(3, o.orderType);    //3:  委託別 : R:ROD I:IOC F:FOK
            gTrade1.SetOrderInfoString(4, o.buySell);      //4:  買賣別 : B S
            gTrade1.SetOrderInfoString(5, o.priceFlag);    //5:  價格別 : L:限價 M:市價 P:一定範圍市價
            gTrade1.SetOrderInfoValue(6, o.price);         //6:  委託價格(數值)
            gTrade1.SetOrderInfoValue(7, o.qty);           //7:  委託數量(數值)
            gTrade1.SetOrderInfoString(10, o.dayTrade);    //10: 當沖 : Y N
            gTrade1.SetOrderInfoString(11, o.userKey);     //11: userKey
            gTrade1.SetOrderInfoValue(14, 0);              //14: 停損價格(數值)(0表無停損價)(只有期貨商品為必填欄位)
            gTrade1.SetOrderInfoString(15, o.openClose);   //15: 倉別 : A:自動 O:新倉 C:平倉
            gTrade1.SetOrderInfoString(16,o.callPut);      //16: Call/Put
            gTrade1.SetOrderInfoValue(17,o.strikePrice);   //17:履約價
            gTrade1.SetOrderInfoString(18,o.orderno);      //18:委託書號
            gTrade1.SetOrderInfoString(20, o.symbolID2);   //20:商品ID2
            gTrade1.SetOrderInfoString(21, o.buySell2);    //21:買賣別2
            gTrade1.SetOrderInfoString(22, o.commYM2);     //22:月份2
            gTrade1.SetOrderInfoString(23, o.callPut2);    //23:CallPut2
            gTrade1.SetOrderInfoValue(24, o.strikePrice2); //24:履約價2
            //log.Info(o.toString());
            int intReturn = gTrade1.ProcessOrder();
            //log.Info(intReturn+rtnMsg.instance.getProcessOrder(intReturn));
            //if (intReturn != 1) MessageBox.Show(rtnMsg.instance.getProcessOrder(intReturn));
        }
    }
}
