//------------------------------------------------------------------------------
// written by: Shivangi C (Prediction code logic written by Mohnish in C++ and coverted to
//              C# by Shivangi with some enhancement)
// assisted by: Mohnish K for predictor code
// debugged by:Shivangi C
//
// summary: This file has the Data Access layer functions of the 
//          bussiness layer which has all the queries fired to the data base 
//          depending of the functionality requested by the user
//          
//------------------------------------------------------------------------------

using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Data.SqlClient;
using SFSDataAccessLayer;
using System.Data.Odbc;

namespace StockForecasterService
{
    /// <summary>
    /// This is the Web Service which has the business logic layer. It has the methods
    /// which are accessible to the client through which the different the client makes the 
    /// function calls and gets the required output. This file is basically an interface 
    /// between the client and the database.
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class StockInfo : System.Web.Services.WebService
    {
        StockInfoDAL DALObj;
        decimal[] kValue, dValue;
        decimal high = 0, low = 0;
        /// <summary>
        /// In the constructor we create an object of the data access layer
        /// </summary>
        public StockInfo()
        {
            DALObj = new StockInfoDAL();
        }

        /// <summary>
        /// The output of this fuction will be stockname,curent price, today's high and today's low  
        /// It calls the function GetStockPriceInfoDAL from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="stockID"></param>
        /// <returns></returns>
        [WebMethod]
        public DataSet GetStockPriceInfo(string stockID)
        {
            DataSet output;
            
           output = DALObj.GetStockPriceInfoDAL(stockID);

            return output;
        }

        /// <summary>
        /// The output of this fuction will Be
        ///Company name, last year Revenue, last year profit,
        ///revenue% increase, Profit %increase, last qarter revenue
        /// It calls the function GetFinancialInfoDAL from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="stockID"></param>
        /// <returns></returns>
        [WebMethod]
        public DataSet GetFinancialInfo(string stockID)
        {
            DataSet output;
            output = DALObj.GetFinancialInfoDAL(stockID);
            
            return output;
        }

        /// <summary>
        /// Returns tabular form of company names based on the sector same as the given name
        /// It calls the function GetCompetitiveStocksDAL from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="stockID"></param>
        /// <returns></returns>
        [WebMethod]
        public DataSet GetCompetitiveStocks(string stockID)
        {
            DataSet output;
            output = DALObj.GetCompetitiveStocksDAL(stockID);
            
            return output;
        }

        /// <summary>
        /// This returns hourly prices for the day for the selected stock
        /// It calls the function GetCurrentDayPerformanceDAL from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="stockID"></param>
        /// <returns></returns>
        [WebMethod]
        public DataSet GetCurrentDayPerformance(string stockID)
        {
                       
            DataSet output;
            output = DALObj.GetCurrentDayPerformanceDAL(stockID);
            return output;
        }

        /// <summary>
        /// This function implements the Register user functionality
        /// It calls the function RegisterUser from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="firstName"></param>
        /// <param name="lastName"></param>
        /// <param name="userId"></param>
        /// <param name="pwd"></param>
        /// <param name="email"></param>
        /// <returns></returns>
        [WebMethod]
        public int RegisterUser(string firstName, string lastName, string userId, string pwd, string email)
        {
            int output;
            output = DALObj.RegisterUser(firstName, lastName, userId, pwd, email);
            return output;
        }

        /// <summary>
        /// This method implements the Login Function 
        /// It calls the function LoginUser from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="pwd"></param>
        /// <returns></returns>
        [WebMethod]
        public int LoginUser(string userId, string pwd)
        {
            int output;
            output = DALObj.LoginUser(userId, pwd);
            return output;
        }

        /// <summary>
        /// This is the method that gives the Months performance of the selected stock
        /// It calls the function GetStockPerformanceDAL from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="stockID"></param>
        /// <param name="dayRangeCode"> This is the short term (0)/ longterm  (1)range code</param>
        /// <returns></returns>
        [WebMethod]
        public DataSet GetStockPerformance(string stockID, int dayRangeCode)
        {
            DataSet output;
            output = DALObj.GetStockPerformanceDAL(stockID, dayRangeCode);
            
            return output;
        }

        /// <summary>
        /// This method has the functionality for the that gives the next day price prediction of the slected stock
        /// It calls the function GetNextSpeculativePriceDAL from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="stockID"></param>
        /// <returns></returns>
        [WebMethod]
        public decimal GetNextSpeculativePrice(string stockID)
        {
            // Returns predicted price, time period, %change of price
            decimal[] priceArray;
            priceArray = DALObj.GetNextSpeculativePriceDAL(stockID,0);
            PredictCalcList(priceArray);
            decimal price1 = dValue[dValue.Length - 1] - dValue[dValue.Length - 2];
            decimal price2 = dValue[dValue.Length - 2] - dValue[dValue.Length - 3];
            decimal price3 = dValue[dValue.Length - 3] - dValue[dValue.Length - 4];
            decimal avgPrice = (price1 + price2 + price3) / 3 + kValue[kValue.Length - 1];
            decimal predictedPrice = (avgPrice / 100) * (high - low) + low;
            return predictedPrice;
        }

        /// <summary>
        /// This method has the implementation for the short term 14 days and long term 60 days 
        /// prediction of price for the selected stock
        /// It calls the function GetNextSpeculativePriceDAL from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="stockID"></param>
        /// <param name="termCode"></param>
        /// <returns></returns>
        [WebMethod]
        public decimal GetSpeculativePrice(string stockID, int termCode )
        {
            // Returns predicted price, time period, %change of price
            decimal[] priceArray;
            priceArray = DALObj.GetNextSpeculativePriceDAL(stockID, termCode);

            // this is a call to the function PredictCalcList which calculates the %D %K values
            PredictCalcList(priceArray); 
            decimal[] avgPrice = new decimal[priceArray.Length + 5];
            avgPrice[4] = dValue[dValue.Length - 1];
            avgPrice[3] = dValue[dValue.Length - 2];
            avgPrice[2] = dValue[dValue.Length - 3];
            avgPrice[1] = dValue[dValue.Length - 4];
            decimal klast = kValue[kValue.Length - 1];
            for (int i = 0; i < priceArray.Length; i++)
            {
                decimal price1 = avgPrice[i + 4] - avgPrice[i + 3];
                decimal price2 = avgPrice[i + 3] - avgPrice[i + 2];
                decimal price3 = avgPrice[i + 2] - avgPrice[i + 1];
                avgPrice[i + 5] = (price1 + price2 + price3) / 3 + klast;
                klast = avgPrice[i + 5];
            }
            decimal predictedPrice = (klast / 100) * (high - low) + low;
            return predictedPrice;
        }

        /// <summary>
        /// This method is the implemtation logic for giving tips to the user
        /// It calls the function GetTradingTipsDAL from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="stockId"></param>
        /// <param name="termCode">This is the short term(14) and long term code</param>
        /// <returns></returns>
        [WebMethod]
        public string GetTradingTips(string stockId, int termCode)
        {
            // Gives trading tips
            string tips;
            decimal[] priceArray;
            priceArray = DALObj.GetTradingTipsDAL(stockId, termCode);
            PredictCalcList(priceArray);
            decimal[] avgPrice = new decimal[priceArray.Length+5];

            avgPrice[4] = dValue[dValue.Length - 1];
            avgPrice[3] = dValue[dValue.Length - 2];
            avgPrice[2] = dValue[dValue.Length - 3];
            avgPrice[1] = dValue[dValue.Length - 4];

            decimal klast = kValue[kValue.Length - 1];
            for (int i = 0; i < priceArray.Length;i++)
            {
                decimal price1 = avgPrice[i+4] - avgPrice[i+3];
                decimal price2 = avgPrice[i + 3] - avgPrice[i + 2];
                decimal price3 = avgPrice[i + 2] - avgPrice[i+1];
                avgPrice[i + 5] = (price1 + price2 + price3) / 3 + klast;
                klast = avgPrice[i + 5];
            }
            int y =0, z=0;
            for (int i = 1; i < avgPrice.Length; i++)
            {
                if (avgPrice[i-1] >=90 && avgPrice[i] < 90)
                {
                    y = i;
                   // return tips; 
                }
                else if (avgPrice[i-1] <= 10 && avgPrice[i] > 10)
                {
                    z = i;
                    //return tips;
                }
            }
            if (y != 0 || z != 0)
            {
                if (y > z )
                {
                        tips = "As per our prediction SELL the selected Stock";
                        return tips;
                   
                }
                else
                {
                        tips = "As per our Prediction BUY the selected Stock ";
                        return tips;                    
                    
                }

            }
            else
            {

                tips = "Currently Sitout/hold the stock available";
                return tips;
            }
        }

        /// <summary>
        /// This method is called when the user searches for the stock of interest
        ///  will return the names of the matching companyName
        /// It calls the function FindStockDAL from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="companyName"></param>
        /// <returns></returns>
        [WebMethod]
        public DataSet FindStock(string companyName)
        {
            DataSet output;
            output = DALObj.FindStockDAL(companyName);
           
            return output;
        }

        /// <summary>
        /// This method will return the general info about the company.
        /// It calls the function FindStockDAL from the class in StockInfoDal.cs
        /// </summary>
        /// <param name="companyName"></param>
        /// <returns></returns>
        [WebMethod]
        public DataSet GetGeneralStockInfoDAL(string companyName)
        {
            DataSet output;
            output = DALObj.GetGeneralStockInfoDAL(companyName);
            
            return output;
        }

        /// <summary>
        /// This is a private method which calculates the %K and %D values for the selected 
        /// range of prices for the given stock
        /// </summary>
        /// <param name="priceList"></param>
        private void PredictCalcList(decimal [] priceList)
        {
            
            if (priceList[0] > priceList[1])
            {
                high = priceList[0];
                low = priceList[1];
            }
            else 
            {
                high = priceList[1];
                low = priceList[0];
            }
            kValue = new decimal[priceList.Length - 1];
            dValue = new decimal[priceList.Length - 3];
            kValue[0] = 100 * (priceList[1] - low) / (high - low);

            for (int i = 2; i < priceList.Length; i++ )
            {
                if (priceList[i] > high)
                {
                    high = priceList[i];
                }
                else if (priceList[i] < low)
                { 
                    low = priceList[i]; 
                }
                kValue[i - 1] = 100 * (priceList[i] - low) / (high - low);
            }

            for (int i = 3; i < kValue.Length; i++ )
            {
                dValue[i - 3] = (kValue[i] + kValue[i - 1] + kValue[i - 2]+ kValue[i-3]) / 4;
            }
        }

    }
}
