#include <vector>
#include "utils.h"
#include <algorithm> 
#include <cctype>
#include <sstream>
#include <PIXDFLT.H>
#include "logger.h"
#include <atlbase.h>
#include <atlcom.h>
#include "ScannerCsv.h"



static void ltrim(std::string &s) {
	s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
		return !std::isspace(ch);
	}));
}


static void rtrim(std::string &s) {
	s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
		return !std::isspace(ch);
	}).base(), s.end());
}


static void trim(std::string &s) {
	ltrim(s);
	rtrim(s);
}


static std::string trim_copy(std::string s) {
	trim(s);
	return s;
}

HRESULT AtlReportPixError(const CLSID& clsid, PixDrvHandle hDrv, INT32 lCode)
{
	char lpcString[255], lpcErrString[255];
	if (lCode >= PIX_SUCCESS)
	{
		return S_OK;
	}
	if (!hDrv.lpCode) 
	{
		PixDrvGetError(static_cast<char *>(nullptr), nullptr, lCode, lpcString,
			sizeof lpcString);
	}
	else
	{
		PixDrvGetError(static_cast<char *>(nullptr), &hDrv, lCode, lpcString,
			sizeof lpcString);
	}

	const auto shortCode = static_cast<INT16>(HIWORD(lCode));
	sprintf_s<255U>(lpcErrString, "%s (%d)", lpcString, shortCode);
	const auto hresult = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, -shortCode);

	return AtlReportError(clsid, lpcErrString, GUID_NULL, hresult);
}

template<typename Out>
void split(const std::string &s, char delimiter, Out result) {
	std::stringstream ss(s);
	std::string item;
	while (std::getline(ss, item, delimiter)) {
		*(result++) = item;
	}
}

std::vector<std::string> split(const std::string &s, char delimiter) {
	std::vector<std::string> elems;
	split(s, delimiter, std::back_inserter(elems));
	return elems;
}

std::string FindScannerDriverName(const std::string& modelName)
{
	if (modelName == "Demo Driver")
	{
		return "filespew";
	}
	for each(auto row in scannerList)
	{
		auto parts = split(row, ',');
		if (parts.size() < 14)
		{
			continue;
		}
		if (parts.at(0)[0] == ';')
		{
			continue;
		}
		auto name = trim_copy(parts.at(1));
		if (name == modelName)
		{
			auto driver = trim_copy(parts.at(13));
			return driver;
		}
	}
	throw std::exception((std::string("Scanner model ") + modelName + " not found").c_str());
}


