/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using Apache.Geode.Client;

namespace PdxTests
{
  public class PositionPdx
    : IPdxSerializable
  {
    #region Private members

    private long m_avg20DaysVol;
    private string m_bondRating;
    private double m_convRatio;
    private string m_country;
    private double m_delta;
    private long m_industry;
    private long m_issuer;
    private double m_mktValue;
    private double m_qty;
    private string m_secId;
    private string m_secLinks;
    private string m_secType;
    private int m_sharesOutstanding;
    private string m_underlyer;
    private long m_volatility;
    private int m_pid;

    private static int m_count = 0;

    #endregion

    #region Private methods

    private void Init()
    {
      m_avg20DaysVol = 0;
      m_bondRating = null;
      m_convRatio = 0.0;
      m_country = null;
      m_delta = 0.0;
      m_industry = 0;
      m_issuer = 0;
      m_mktValue = 0.0;
      m_qty = 0.0;
      m_secId = null;
      m_secLinks = null;
      m_secType = null;
      m_sharesOutstanding = 0;
      m_underlyer = null;
      m_volatility = 0;
      m_pid = 0;
    }

    private UInt64 GetObjectSize(ISerializable obj)
    {
      return (obj == null ? 0 : obj.ObjectSize);
    }

    #endregion

    #region Public accessors

    public string SecId
    {
      get
      {
        return m_secId;
      }
    }

    public int Id
    {
      get
      {
        return m_pid;
      }
    }

    public int SharesOutstanding
    {
      get
      {
        return m_sharesOutstanding;
      }
    }

    public static int Count
    {
      get
      {
        return m_count;
      }
      set
      {
        m_count = value;
      }
    }

    public override string ToString()
    {
      return "Position [secId="+m_secId+" sharesOutstanding="+m_sharesOutstanding+ " type="+m_secType +" id="+m_pid+"]";
    }
    #endregion

    #region Constructors

    public PositionPdx()
    {
      Init();
    }

    //This ctor is for a data validation test
    public PositionPdx(Int32 iForExactVal)
    {
      Init();

      char[] id = new char[iForExactVal+1];
      for (int i = 0; i <= iForExactVal; i++)
      {
        id[i] = 'a';
      }
      m_secId = new string(id);
      m_qty = iForExactVal % 2 == 0 ? 1000 : 100;
      m_mktValue = m_qty * 2;
      m_sharesOutstanding = iForExactVal;
      m_secType = "a";
      m_pid = iForExactVal;
    }

    public PositionPdx(string id, int shares)
    {
      Init();
      m_secId = id;
      m_qty = shares * (m_count % 2 == 0 ? 10.0 : 100.0);
      m_mktValue = m_qty * 1.2345998;
      m_sharesOutstanding = shares;
      m_secType = "a";
      m_pid = m_count++;      
    }

    #endregion

    public static IPdxSerializable CreateDeserializable()
    {
      return new PositionPdx();
    }

    #region IPdxSerializable Members

    public void FromData(IPdxReader reader)
    {
      m_avg20DaysVol = reader.ReadLong("avg20DaysVol");
      m_bondRating = reader.ReadString("bondRating");
      m_convRatio = reader.ReadDouble("convRatio");
      m_country = reader.ReadString("country");
      m_delta = reader.ReadDouble("delta");
      m_industry = reader.ReadLong("industry");
      m_issuer = reader.ReadLong("issuer");
      m_mktValue = reader.ReadDouble("mktValue");
      m_qty = reader.ReadDouble("qty");
      m_secId = reader.ReadString("secId");
      m_secLinks = reader.ReadString("secLinks");
      m_secType = reader.ReadString("secType");
      m_sharesOutstanding = reader.ReadInt("sharesOutstanding");
      m_underlyer = reader.ReadString("underlyer");
      m_volatility = reader.ReadLong("volatility");
      m_pid = reader.ReadInt("pid");

    }

    public void ToData(IPdxWriter writer)
    {
      writer.WriteLong("avg20DaysVol", m_avg20DaysVol);
      writer.WriteString("bondRating", m_bondRating);
      writer.WriteDouble("convRatio", m_convRatio);
      writer.WriteString("country", m_country);
      writer.WriteDouble("delta", m_delta);
      writer.WriteLong("industry", m_industry);
      writer.WriteLong("issuer", m_issuer);
      writer.WriteDouble("mktValue", m_mktValue);
      writer.WriteDouble("qty", m_qty);
      writer.WriteString("secId", m_secId);
      writer.WriteString("secLinks", m_secLinks);
      writer.WriteString("secType", m_secType);
      writer.WriteInt("sharesOutstanding", m_sharesOutstanding);
      writer.WriteString("underlyer", m_underlyer);
      writer.WriteLong("volatility", m_volatility);
      writer.WriteInt("pid", m_pid);
      //identity field
      writer.MarkIdentityField("pid");
    }

    #endregion
  }
}
