/*
         * private static CP2ConnectorNative _instance;
         *
         * private static CP2ConnectorNative Create (IAlarmable alarmable)
         * {
         * _instance = new CP2ConnectorNative(alarmable);
         * return _instance;
         *
         * }
         */


        public /*static*/ UInt32 Callback(int *conn, int *listener, cg_msg_t *msg, void *data)
        {
            try
            {
                switch (msg->type)
                {
                case CG_MSG_STREAM_DATA:
                {
                    cg_msg_streamdata_t *replmsg = (cg_msg_streamdata_t *)msg;
                    //string name = new string(replmsg->msg_name);
                    string name = Marshal.PtrToStringAnsi((IntPtr)replmsg->msg_name);


                    if (name == "deal")
                    {
                        Deal *deal = (Deal *)replmsg->data;

                        Int64 intpart = 0;
                        byte  scale;

                        cg_bcd_get(deal->price, &intpart, &scale);
                        double price = intpart;

                        for (int i = 0; i < scale; i++)
                        {
                            price /= 10;
                        }


                        DateTime dtServer = new DateTime(deal->moment.year, deal->moment.month, deal->moment.day,
                                                         deal->moment.hour, deal->moment.minute, deal->moment.second,
                                                         deal->moment.msec);


                        DateTime dtLocal = (DateTime.Now).AddHours(-2);

                        double delta  = (dtLocal - dtServer).TotalMilliseconds;
                        string marker = "";
                        if ((DateTime.Now - dtStarted).TotalSeconds > 3)
                        {
                            if (delta > 30)
                            {
                                marker = " <==";
                                // _alarmer.Error("native deals dt=" + delta);
                                Error("native deals dt=" + delta);
                            }
                        }
                        _log.Log("replID=" + deal->replID + " replRev=" + deal->replRev + " id_deal" + deal->id_deal + " isin_id=" + deal->isin_id
                                 + " moment=" + dtServer.ToString("hh:mm:ss.fff") + " dt=" + delta + marker);
                    }

                    else if (name == "orders_aggr")
                    {
                        orders_aggr *oa = (orders_aggr *)replmsg->data;


                        if (oa->isin_id != 430354 && oa->isin_id != 422393 &&
                            oa->isin_id != 457935 && oa->isin_id != 457974)
                        {
                            break;
                        }

                        Int64 intpart = 0;
                        byte  scale;

                        cg_bcd_get(oa->price, &intpart, &scale);
                        double price = intpart;

                        for (int i = 0; i < scale; i++)
                        {
                            price /= 10;
                        }


                        string dt = CGTImeToString(oa->moment);


                        string msgToLog = String.Format("replId={0} replRev={1} isin_id={2} price={3} volume={4} moment={5}",
                                                        oa->replID, oa->replRev, oa->isin_id, price, oa->volume, dt);
                        _log.Log(msgToLog);
                    }



                    break;
                }

                case CG_MSG_P2REPL_ONLINE:
                {
                    _log.Log("======================================================================== ONLINE ============================================================================================================================");

                    break;
                }

                case CG_MSG_TN_BEGIN:
                {
                    _log.Log("==================================================== Begin ============================================================");
                    break;
                }

                case CG_MSG_TN_COMMIT:
                {
                    _log.Log("==================================================== Commit ============================================================");

                    break;
                }

                case CG_MSG_OPEN:
                {
                    break;
                }

                case CG_MSG_CLOSE:
                {
                    break;
                }

                case CG_MSG_P2REPL_LIFENUM:
                {
                    break;
                }

                    //   default:
                }
            }
            catch (Exception e)
            {
                //  _alarmer.Error("Error in native callback");
                Error("Error in native callback");
            }

            // System.Threading.Thread.Sleep(1000);
            return((UInt32)0);
        }
        public void ThredProcess()
        {
            pt = Marshal.AllocHGlobal(BUFFER_SIZE);

            intPart = Marshal.AllocHGlobal(8);
            scale   = Marshal.AllocHGlobal(1);


            //Int64* intPart = ( Int64*) Marshal.AllocHGlobal(16);
            // byte* scale = (byte*) Marshal.AllocHGlobal(8);
            //TODO check initialization
            InitStock(_isinId);

            long  lng;
            sbyte sb;



            _logger = new CLogger(String.Format("CP2StockReaderNative_{0}", _isinId), false, "P2StockReaderNative");
            int itmp = 0;

            while (_bRun)
            {
                //ReadData(out pt);
                try
                {
                    ReadStock(_isinId, out pt);

                    int    iBuy    = 0;
                    int    iSell   = 0;
                    string stDebug = "";
                    for (int cnt = 0; cnt < 2 * STOCK_DEPTH; cnt++)
                    {
                        orders_aggr *el = (orders_aggr *)pt + cnt;
                        //if empty element
                        if (el->replID == 0)
                        {
                            continue;
                        }

                        decimal price  = GetDecimalFromBCD(el->price);
                        long    volume = el->volume;
                        sbyte   dir    = el->dir;

                        lock (_outStock.Lck)
                        {
                            //Direction
                            int ind = 0;
                            if (dir == (sbyte)EnmOrderDir.Buy)
                            {
                                ind = iBuy++;
                            }
                            else
                            {
                                ind = iSell++;
                            }

                            _outStock[(Direction)dir][ind].Price  = price;
                            _outStock[(Direction)dir][ind].Volume = volume;

                            stDebug += String.Format("d={0} p={1} v={2}",
                                                     (Direction)dir,
                                                     _outStock[(Direction)dir][ind].Price,
                                                     _outStock[(Direction)dir][ind].Volume);
                        }

                        //_outStock.

                        /*
                         *
                         * //cg_bcd_get(el->price, &lng, &scale);
                         *
                         * Int64* intPartVal = (Int64*)intPart;
                         * sbyte* scaleVal = (sbyte*)scale;
                         * s
                         *
                         * if (intPartVal != null)
                         *  Thread.Sleep(0);
                         *
                         * if (scaleVal != null)
                         *  Thread.Sleep(0);
                         *
                         * // Console.WriteLine(el->volume.ToString());
                         */
                    }

                    _outStock.UpdateBidAsk();

                    _dealingServer.UpdateInpStocks(_isinId, ref _outStock);
                    if (!_bSentStockRecieved)
                    {
                        _client.UpdateStockReieved(_isinId);
                    }

                    Log(stDebug);
                    Log("==================================================================================================");


                    Thread.Sleep(1);
                }
                catch (Exception e)
                {
                    //TODO ERROR !
                    _dealingServer.Error("P2StockReaderNative.ThredProcess", e);
                }
            }



            try
            {
                CloseStock(_isinId);
            }
            catch (Exception e)
            {
                _dealingServer.Error("P2StockReaderNative error close stock", e);
            }

            //Close();
        }