#include "lgi/common/Lgi.h"
#include "resdefs.h"
#include "lgi/common/TextLog.h"

//////////////////////////////////////////////////////////////////
const char *AppName = "VsLaunch";

struct VsInfo
{
	int Year;
	int MscVer;
	double Ver;
}
Versions[] =
{
	{2019, _MSC_VER_VS2019, 16.0},
	{2017, _MSC_VER_VS2017, 15.0},
	{2015, _MSC_VER_VS2015, 14.0},
	{2013, _MSC_VER_VS2013,	12.0},
	{2012, _MSC_VER_VS2012, 11.0},
	{2010, _MSC_VER_VS2010, 10.0},
	{2008, _MSC_VER_VS2008, 9.0},
	{2005, _MSC_VER_VS2005, 8.0},
	{2003, _MSC_VER_VS2003, 7.1},
	{7, _MSC_VER_VC7, 7.0},
	{6, _MSC_VER_VC6, 6.0},
	{5, _MSC_VER_VC5, 5.0},
};

double YearToVer(int64 y)
{
	for (int i=0; i<CountOf(Versions); i++)
	{
		if (Versions[i].Year == y)
			return Versions[i].Ver;
	}
	
	return 0.0;
}

int VerToYear(double v)
{
	for (int i=0; i<CountOf(Versions); i++)
	{
		if (Versions[i].Ver - v < 0.001)
			return Versions[i].Year;
	}
	
	return 0;
}

class App : public LWindow
{
	LTextLog *Log;

public:
    App()
    {
        Name(AppName);
        LRect r(0, 0, 500, 300);
        SetPos(r);
        MoveToCenter();
        SetQuitOnClose(true);

        if (Attach(0))
        {
			AddView(Log = new LTextLog(100));
			AttachChildren();
			SetPulse(500);
        }
    }

	void OnPulse()
	{
		Visible(true);
	}
    
	void OnReceiveFiles(LArray<const char*> &Files)
	{
		Log->Print("Got %i files...\n", Files.Length());
		for (unsigned i=0; i<Files.Length(); i++)
		{
			const char *File = Files[i];
			Log->Print("\t%s...\n", File);
	
			const char *Ext = LGetExtension(File);
			if (Ext && !_stricmp(Ext, "sln"))
			{
				LFile f;
				if (f.Open(File, O_READ))
				{
					LString::Array a = f.Read().Split("\n");
					f.Close();
					
					double FileVersion = 0.0;
					int64 VsYear = -1;
					double VsVersion = 0.0;
					for (unsigned i=0; i<a.Length() && VsVersion == 0.0; i++)
					{
						if (a[i].Find("File, Format Version") >= 0)
						{
							LString::Array p = a[i].Split(" ");
							FileVersion = p.Last().Float();
						}
						else if (a[i](0) == '#')
						{
							LString::Array p = a[i].Split(" ");
							for (auto s : p)
							{
								auto i = s.Int();
								if (i > 2000 && i < 2030)
								{
									VsYear = i;
									VsVersion = YearToVer(VsYear);
									break;
								}
								else if (i >= 10 && i <= 16)
								{
									VsVersion = (double)i;
									VsYear = VerToYear(VsVersion);
								}
							}
						}
					}
					
					if (VsVersion > 0.0)
					{
						// C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe
						LFile::Path p(LSP_USER_APPS, 32);
						LString v;

						if (VsVersion >= 16.0)
							v.Printf("Microsoft Visual Studio\\%" PRIi64 "\\Community", VsYear);
						else
							v.Printf("Microsoft Visual Studio %.1f", VsVersion);

						p += v;
						p += "Common7\\IDE\\devenv.exe";
						if (p.IsFile())
						{
							LExecute(p, File);
							LCloseApp();
						}
						else Log->Print("\t\tError: The file '%s' doesn't exist.", p.GetFull().Get());
					}
					else Log->Print("\t\tError: No version in '%s'.", File);
				}
				else Log->Print("\t\tError: Failed to open '%s'\n", File);
			}
		}
	}
};

//////////////////////////////////////////////////////////////////
int LgiMain(OsAppArguments &AppArgs)
{
	LApp a(AppArgs, AppName);
	if (a.IsOk())
	{
		a.AppWnd = new App;
		a.Run();
	}

	return 0;
}

