//  
//  PubStatUser.cs
//  
//  Author:
//       Robert BRACCAGNI alias Gai-Luron <lfsgailuron@free.fr>
// 
//  Copyright (c) 2010 Gai-Luron
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.


using System;
using System.Text;
using System.Collections;
using System.Threading;
using System.IO;
using System.Net;
using System.Net.Cache;
using System.Reflection;
using Configurator;



namespace LapperThreads
{
    public class PubStatUser
    {
		public class PubStatUserPst
		{
			public string userName = "";
			public long distance = 0;
			public long fuel = 0;
			public long laps = 0;
			public long hostsJoined = 0;
			public long wins = 0;
			public long second = 0;
			public long third = 0;
			public long finished = 0;
			public long quals = 0;
			public long pole = 0;
			public long drags = 0;
			public long dragWins = 0;
			public string country = "";

			public PubStatUserPst(string puserName, long pdistance, long pfuel, long plaps, long phostsJoined, long pwins, long psecond, long pthird, long pfinished, long pquals, long ppole, long pdrags, long pdragsWin, string pcountry)
			{
				userName = puserName;
				distance = pdistance;
				fuel = pfuel;
				laps = plaps;
				hostsJoined = phostsJoined;
				wins = pwins;
				second = psecond;
				third = pthird;
				finished = pfinished;
				quals = pquals;
				pole = ppole;
				drags = pdrags;
				dragWins = pdragsWin;
				country = pcountry;
			}

		}
        public class PubStatUserPb 
        {
			public class PbElem{
				public string track;
				public string car;
				public long split1 = 0;
				public long split2 = 0;
				public long split3 = 0;
				public long lapTime = 0;
				public long lapCount = 0;
				public DateTime datPB;

				public PbElem(string ptrack, string pcar, long psplit1, long psplit2, long psplit3, long plapTime, long plapCount, long ptimeStamp)
				{
					this.track = ptrack;
					this.car = pcar;
					this.split1 = psplit1;
					this.split2 = psplit2;
					this.split3 = psplit3;
					this.lapTime = plapTime;
					this.lapCount = plapCount;
					this.datPB = UTILS.utils.TimestampToDateTime((double)ptimeStamp);
				}
			}
			public class sByCar : IComparer
			{
				int IComparer.Compare(object a, object b)
				{
					if (string.Compare((a as PbElem).car, (b as PbElem).car) > 0)
						return 1;
					else if (string.Compare((a as PbElem).car, (b as PbElem).car) < 0)
						return -1;
					else
					{
						if (string.Compare((a as PbElem).track, (b as PbElem).track) > 0)
							return 1;
						else if (string.Compare((a as PbElem).track, (b as PbElem).track) < 0)
							return -1;
						else
							return 0;
					}
				}
			}
			public class sByTrack : IComparer
			{
				int IComparer.Compare(object a, object b)
				{
					if (string.Compare((a as PbElem).track, (b as PbElem).track) > 0)
						return 1;
					else if (string.Compare((a as PbElem).track, (b as PbElem).track) < 0)
						return -1;
					else
					{
						if (string.Compare((a as PbElem).car, (b as PbElem).car) > 0)
							return 1;
						else if (string.Compare((a as PbElem).car, (b as PbElem).car) < 0)
							return -1;
						else
							return 0;
					}
				}
			}
			public string userName = "";
			public ArrayList listPbElem = new ArrayList();
			public PubStatUserPb(string puserName)
			{
				this.userName = puserName;
			}
			public void sortByCar()
			{
				listPbElem.Sort( new sByCar() );
			}
			public void sortByTrack()
			{
				listPbElem.Sort( new sByTrack() );
			}
        }
		
		public Queue QReturnedUserPb = new Queue(100);
		public Queue QReturneduserPst = new Queue(100);
		public Queue QQueryUserPubStat = new Queue(100);
		private GLDebug.Debug myDebug;
        private string PubStatIdk = "";
        public PubStatUser(GLDebug.Debug pmyDebug, string pPubStatIdk)
        {
            this.myDebug = pmyDebug;
            this.PubStatIdk = pPubStatIdk;
        }
        public void ThreadUserPubStat()
        {
            myDebug.WriteLine("mss","PubStat Thread Started...");
            while (true)
            {
// PB Request, hight priority
				Monitor.Enter(QQueryUserPubStat);
				if (QQueryUserPubStat.Count != 0)
                {
					string user = (string)QQueryUserPubStat.Dequeue();
					Monitor.Exit(QQueryUserPubStat);
					while (queryUserPb(user) == false)
						System.Threading.Thread.Sleep(6000);
					while (queryUserPst(user) == false)
						System.Threading.Thread.Sleep(6000);
					continue;
                }
                else
                {
					Monitor.Exit(QQueryUserPubStat);
                }
                System.Threading.Thread.Sleep(100);
            }
        }
		public void requestPubStat( string userName ){
			if (userName == "")
				return;
			Monitor.Enter(QQueryUserPubStat);
			QQueryUserPubStat.Enqueue(userName);
			Monitor.Exit(QQueryUserPubStat);

		}
        private bool queryUserPb(string userName )
        {
            if (userName == "" || PubStatIdk == "" )
                return true;
            try
            {
                string readLine = "";
                string url = "http://www.lfsworld.net/pubstat/get_stat2.php?version=1.4"
                                + "&idk=" + PubStatIdk 
                                + "&action=pb"
                                + "&racer=" + userName;

                WebRequest req = WebRequest.Create(url);
                req.Timeout = (int)LFSLapper.paramLapper.webTimeOut;

                RequestCachePolicy policy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
                //                    req.CachePolicy = policy;
                WebResponse result = req.GetResponse();
                Stream receiveStream = result.GetResponseStream();
				PubStatUserPb UserPb = new PubStatUserPb( userName );
                using (StreamReader sr = new StreamReader(receiveStream))
                {
                    string track = "";
                    string car = "";
                    string[] par;
                    long lapTime = 0;
                    while (!sr.EndOfStream)
                    {
                        readLine = sr.ReadLine().Trim();
                        par = readLine.Split(' ');
                        if (par[0] == "can't")
                            return false;
                        if (par[0].ToLower() == "invalid") // Wrong pubstatIdk
                        {
                            PubStatIdk = "";
                            return true;
                        }
                        track = UTILS.utils.convTrack(par[0]);
                        car = par[1];
                        lapTime = long.Parse(par[5]);
                        if( lapTime != 0 ) {
							UserPb.listPbElem.Add( new PubStatUserPb.PbElem(track, car
															,long.Parse( par[2] )
															,long.Parse( par[3] )
															,long.Parse( par[4] )
															,lapTime
															,long.Parse( par[6] )
															,long.Parse( par[7] )
														)
												);
//                            Console.WriteLine(readLine);
                        }
                    }
                }
                UserPb.sortByCar();
                Monitor.Enter(QReturnedUserPb);
				QReturnedUserPb.Enqueue(UserPb);
				Monitor.Exit(QReturnedUserPb);
            }
            catch( Exception)
            {
                myDebug.WriteLine("err", "Error on retreiving pubstat info");
            }
            return true;

        }
		private bool queryUserPst(string userName)
		{
			if (userName == "" || PubStatIdk == "")
				return true;
			try
			{
				string readLine = "";
				string url = "http://www.lfsworld.net/pubstat/get_stat2.php?version=1.4"
								+ "&idk=" + PubStatIdk
								+ "&action=pst"
								+ "&racer=" + userName;

				WebRequest req = WebRequest.Create(url);
				req.Timeout = (int)LFSLapper.paramLapper.webTimeOut;

				RequestCachePolicy policy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
				//                    req.CachePolicy = policy;
				WebResponse result = req.GetResponse();
				Stream receiveStream = result.GetResponseStream();
				ArrayList pbUser = new ArrayList();
				using (StreamReader sr = new StreamReader(receiveStream))
				{
					long distance = 0;
					long fuel = 0;
					long laps = 0;
					long hostsJoined = 0;
					long wins = 0;
					long second = 0;
					long third = 0;
					long finished = 0;
					long quals = 0;
					long pole = 0;
					long drags = 0;
					long dragsWin = 0;
					string country = "";

					readLine = sr.ReadLine().Trim();
					if (readLine.IndexOf( "can't" ) == 0)
						return false;
					if (readLine.ToLower() == "invalid") // Wrong pubstatIdk
					{
						PubStatIdk = "";
						return true;
					}
					distance = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					fuel = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					laps = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					hostsJoined = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					wins = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					second = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					third = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					finished = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					quals = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					pole = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					drags = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					dragsWin = long.Parse(readLine);
					readLine = sr.ReadLine().Trim();
					country = readLine;
					Monitor.Enter(QReturneduserPst);
					QReturneduserPst.Enqueue( new PubStatUserPst(userName, distance, fuel, laps, hostsJoined, wins, second, third, finished, quals, pole, drags, dragsWin, country) );
					Monitor.Exit(QReturneduserPst);

				}
			}
			catch (Exception)
			{
				myDebug.WriteLine("err", "Error on retreiving pubstat Pst info");
			}
			return true;

		}


    }
}
