/*
 * 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;

namespace Apache.Geode.Client.IntegrationTests
{
  using Apache.Geode.Client;
  public class Position
    : IDataSerializable
  {
    #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 = "bondRatingString";
      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;
      }
      set
      {
        m_sharesOutstanding = value;
      }
    }

    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 Position()
    {
      Init();
    }

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

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

    public Position(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

    #region IDataSerializable Members

    public void FromData(DataInput input)
    {
      m_avg20DaysVol = input.ReadInt64();
      m_bondRating = input.ReadUTF();
      m_convRatio = input.ReadDouble();
      m_country = input.ReadUTF();
      m_delta = input.ReadDouble();
      m_industry = input.ReadInt64();
      m_issuer = input.ReadInt64();
      m_mktValue = input.ReadDouble();
      m_qty = input.ReadDouble();
      m_secId = input.ReadUTF();
      m_secLinks = input.ReadUTF();
      m_secType = input.ReadUTF();
      m_sharesOutstanding = input.ReadInt32();
      m_underlyer = input.ReadUTF();
      m_volatility = input.ReadInt64();
      m_pid = input.ReadInt32();
    }

    public void ToData(DataOutput output)
    {
      output.WriteInt64(m_avg20DaysVol);
      output.WriteUTF(m_bondRating);
      output.WriteDouble(m_convRatio);
      output.WriteUTF(m_country);
      output.WriteDouble(m_delta);
      output.WriteInt64(m_industry);
      output.WriteInt64(m_issuer);
      output.WriteDouble(m_mktValue);
      output.WriteDouble(m_qty);
      output.WriteUTF(m_secId);
      output.WriteUTF(m_secLinks);
      output.WriteUTF(m_secType);
      output.WriteInt32(m_sharesOutstanding);
      output.WriteUTF(m_underlyer);
      output.WriteInt64(m_volatility);
      output.WriteInt32(m_pid);
      
    }

    public UInt64 ObjectSize
    {
      get
      {
        UInt64 objectSize = 0;
        objectSize += (UInt64)sizeof(long);
        objectSize += (UInt64) (m_bondRating.Length * sizeof(char));
        objectSize += (UInt64)sizeof(double);
        objectSize += (UInt64)(m_country.Length * sizeof(char));
        objectSize += (UInt64)sizeof(double);
        objectSize += (UInt64)sizeof(Int64);
        objectSize += (UInt64)sizeof(Int64);
        objectSize += (UInt64)sizeof(double);
        objectSize += (UInt64)sizeof(double);
        objectSize += (UInt64)(m_secId.Length * sizeof(char));
        objectSize += (UInt64)(m_secLinks.Length * sizeof(char));
        objectSize += (UInt64)(m_secType == null ? 0 : sizeof(char) * m_secType.Length);
        objectSize += (UInt64)sizeof(Int32);
        objectSize += (UInt64)(m_underlyer.Length * sizeof(char));
        objectSize += (UInt64)sizeof(Int64);
        objectSize += (UInt64)sizeof(Int32);
        return objectSize;
      }
    }

    #endregion

    public static ISerializable CreateDeserializable()
    {
      return new Position();
    }
  }
}
