/***************************************************
Written  by:  Rushi Rawal, Bill Taft, Benjamin Ross
Debugged by:  Rushi Rawal, Bill Taft, Benjamin Ross
Integrated by:  Rushi Rawal, Bill Taft, Benjamin Ross
****************************************************/

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using MySql.Data.MySqlClient;
using Mapack;

[WebService(Namespace = "http://tempuri.org/namespace")]
// the service could also be run at this url and made public to almost any client that would want to use it.
//[WebService(Namespace = "http://software-ece.rutgers.edu/~group803")]  
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
    public Service () {

        //Uncomment the following line if using designed components 
        //InitializeComponent(); 
    }

    // Predictor method is the main prediction algorithm, refer to the final report for inputs, outputs and exceptions.   
    [WebMethod]
    public double[] Predictor(string tickers, System.Int32 principal, System.Int32 day)
    {
        string tickersymbol = Conversion(tickers);

        int stockSize = getStockSize(tickersymbol, "price"); //get stock size

        double[] stockprices = getStockData(tickersymbol, "price", stockSize); //get array of stock values

        Console.WriteLine(stockSize);

        Console.WriteLine(" ");

        double[] stockprice1 = new double[40];

        for (int i = 0; i < 40; i++)
        {
            int ii = 39 - i;
            int iii = stockSize - i - 1;
            stockprice1[ii] = stockprices[iii];
        }

        foreach (double i in stockprice1)
        {
            Console.WriteLine(i);
        }
        Console.WriteLine(" ");

        Matrix A = new Matrix(30, 10);
        Matrix B = new Matrix(30, 1);
        Matrix Pre = new Matrix(1, 10);
        //  Matrix Pred = new Matrix(10, 1);
        Matrix Output = new Matrix(10, 1);

        /// Initial Training

        for (int i = 0; i < 30; i++)
        {
            int k = 9 + i;
            int n = k + 1;
            B[i, 0] = stockprice1[n];
            for (int j = 0; j < 10; j++)
            {
                int m = k - j;
                A[i, j] = stockprice1[m];
            }
        }

        // Console.WriteLine(A);
        // Console.WriteLine(B);

        Matrix Atran = A.Transpose();
        Matrix AA = Atran * A;
        Matrix Ainv = AA.Inverse;
        Matrix AAA = Ainv * Atran;
        Matrix x = AAA * B;

        //  Console.WriteLine(x);

        for (int i = 0; i < 10; i++)
        {
            int k = 20 + i;
            Pre[0, i] = stockprice1[k];
        }

        for (int i = 0; i < 10; i++)
        {
            // Console.WriteLine(Pre);
            Matrix Pred = Pre * x;
            Output[i, 0] = Pred[0, 0];

            Matrix CopyPre = Pre;

            for (int j = 0; j < 9; j++)
            {
                int k = j + 1;
                Pre[0, j] = CopyPre[0, k];
            }
            Pre[0, 9] = Pred[0, 0];
        }


        //Console.WriteLine(Output);

        if ((int)day > 10)
        {
            (int)day = 10;
        }

        int day1 = day - 1;

        double[] OutputA = new double[11];
        double[] OutputB = new double[3];

        for (int k = 0; k < 10; k++)
        {
            OutputA[k] = Output[k, 0];
        }

        OutputB[0] = ((double)principal / stockprice1[39]) * OutputA[day1];
        OutputB[1] = OutputA[day1];
        OutputB[2] = 11 - day;


        return OutputB;
    }
     
	// T o convert the user input company name string to a ticker symbol to generate the query for the database 
    static string Conversion(string stockname1)
    {
        string stocksymbol = "";

        switch (stockname1)
        {
            case "Apple":
                stocksymbol = "AAPL";
                break;
            case "Cisco":
                stocksymbol = "CSCO";
                break;
            case "Microsoft":
                stocksymbol = "MSFT";
                break;
            case "Intel":
                stocksymbol = "INTC";
                break;
            case "Nokia":
                stocksymbol = "NOK";
                break;
            case "Oracle":
                stocksymbol = "ORCL";
                break;
            case "Dell":
                stocksymbol = "DELL";
                break;
            case "Canon":
                stocksymbol = "CAJ";
                break;
            case "Amgen":
                stocksymbol = "AMGN";
                break;
            case "Texas Instruments":
                stocksymbol = "TXN";
                break;
            case "EMC":
                stocksymbol = "EMC";
                break;
            case "Motorola":
                stocksymbol = "MOT";
                break;
            case "AMD":
                stocksymbol = "AMD";
                break;
            case "Johnson & Johnson":
                stocksymbol = "JNJ";
                break;
            case "Pfizer":
                stocksymbol = "PFE";
                break;
            case "Glaxo SmithKline":
                stocksymbol = "GSK";
                break;
            case "Novartis":
                stocksymbol = "NVS";
                break;
            case "Merck":
                stocksymbol = "MRK";
                break;
            case "AstraZeneca":
                stocksymbol = "AZN";
                break;
            case "Northrop Grumann":
                stocksymbol = "NOC";
                break;
            case "Sybase":
                stocksymbol = "SY";
                break;
            case "Abbott":
                stocksymbol = "ABT";
                break;
            case "Wyeth":
                stocksymbol = "WYE";
                break;
            case "Generntech":
                stocksymbol = "DNA";
                break;
            case "Alcon":
                stocksymbol = "ACL";
                break;
            case "Citigroup":
                stocksymbol = "C";
                break;
            case "Bank Of America":
                stocksymbol = "BAC";
                break;
            case "HSBC":
                stocksymbol = "HBC";
                break;
            case "Berkshire Hathaway":
                stocksymbol = "BRK-A";
                break;
            case "AIG":
                stocksymbol = "AIG";
                break;
            case "JP Morgan":
                stocksymbol = "JPM";
                break;
            case "Allianz":
                stocksymbol = "AZ";
                break;
            case "Wachovia":
                stocksymbol = "WB";
                break;
            case "Clic":
                stocksymbol = "LFC";
                break;
            case "Goldman Sachs":
                stocksymbol = "GS";
                break;
            case "Barclays":
                stocksymbol = "BCS";
                break;
            case "AXA":
                stocksymbol = "AXA";
                break;
            case "Exxon":
                stocksymbol = "XOM";
                break;
            case "Gamestop":
                stocksymbol = "GME";
                break;
            case "Chevron":
                stocksymbol = "CVX";
                break;
            case "BP":
                stocksymbol = "BP";
                break;
            case "OXY":
                stocksymbol = "OXY";
                break;
            case "ImpOil":
                stocksymbol = "IMO";
                break;
            case "China Mobile Ltd":
                stocksymbol = "CHL";
                break;
            case "AT&T":
                stocksymbol = "T";
                break;
            case "Vodafone":
                stocksymbol = "VOD";
                break;
            case "Google":
                stocksymbol = "GOOG";
                break;
            case "Walmart":
                stocksymbol = "WMT";
                break;
            case "Verizon Wireless":
                stocksymbol = "VZ";
                break;
            case "Akamai":
                stocksymbol = "AKAM";
                break;

        }
        return stocksymbol;
    }


    // Database connection module. Connects to the software-ece.rutgers.edu server and queries the database.
	// Takes the results and passes them on to the prediction algorithm.
    public static double[] getStockData(string ticker, string dataType, int i)
    {
      // Enter in Database Information
      string username = "group803";
      string password = "SE#287";
      string server = "128.6.29.169";
      string database = "group803";
      string table = "STOCKS";
      string record = "stock";
      string column1 = "value";
      string column2 = "intra_down";

      // Connect to Database
      string connString = "Userid=" + username + ";database=" + database + ";server=" + server + ";password=" + password + "";
      MySqlConnection conn = new MySqlConnection(connString);
      conn.Open();

      // Query the Database
      string cmdString1 = "select " + column1 + " from " + table + " where " + record + "=\"" + ticker + "\";";
      string cmdString2 = "select " + column2 + " from " + table + " where " + record + "=\"" + ticker + "\";";
      //MySqlCommand comm = new MySqlCommand(cmdString1, conn);
      MySqlCommand comm;
      if (dataType == "price")
      {
          comm = new MySqlCommand(cmdString1, conn);
      }
      else
      {
          comm = new MySqlCommand(cmdString2, conn);
      }
      MySqlDataReader dr = comm.ExecuteReader();

      // Create array
      int j = 0;
      double[] data = new double[i];
      while (dr.Read())
      {
          if (j <= i)
          {
              data[j] = Convert.ToDouble(dr.GetValue(0));
          }
          j = j + 1;
      }

      // Disconnect from Database
      dr.Close();
      conn.Close();

      // Return values
      return data;

  }

  public static int getStockSize(string ticker, string dataType)
  {
      // Enter in Database Information
      string username = "group803";
      string password = "SE#287";
      string server = "128.6.29.169";
      string database = "group803";
      string table = "STOCKS";
      string record = "stock";
      string column1 = "value";
      string column2 = "intra_down";

      // Connect to Database
      string connString = "Userid=" + username + ";database=" + database + ";server=" + server + ";password=" + password + "";
      MySqlConnection conn = new MySqlConnection(connString);
      conn.Open();

      // Query the Database
      string cmdString1 = "select " + column1 + " from " + table + " where " + record + "=\"" + ticker + "\";";
      string cmdString2 = "select " + column2 + " from " + table + " where " + record + "=\"" + ticker + "\";";
      //MySqlCommand comm = new MySqlCommand(cmdString1, conn);
      MySqlCommand comm;
      if (dataType == "price")
      {
          comm = new MySqlCommand(cmdString1, conn);
      }
      else
      {
          comm = new MySqlCommand(cmdString2, conn);
      }
      MySqlDataReader dr = comm.ExecuteReader();

      // Count number of elements in array
      int i = 0;
      while (dr.Read())
      {
          i = i + 1;
      }
      return i;
  }
    
}
