#include "stdafx.h"
#include "scintilla_prop_sets.h"


const t_prop_set_init_table prop_sets_init_table[] =
{
	{"style.default", "font:Verdana,size:9"},
	{"style.comment", "fore:#008000"},
	{"style.keyword", "bold,fore:#0000ff"},
	{"style.indentifier", "$(style.default)"},
	{"style.string", "fore:#ff0000"},
	{"style.number", "fore:#ff0000"},
	{"style.operator", "$(style.default)"},
	{"style.linenumber", "font:Courier New,size:8,fore:#2b91af"},
	{"style.bracelight", "bold,fore:#000000,back:#ffee62"},
	{"style.bracebad", "bold,fore:#ff0000"},
	{"style.selection.fore", ""},
	{"style.selection.back", ""},
	{"style.selection.alpha", "256"},  // 256 - SC_ALPHA_NOALPHA
	{"style.caret.fore", ""},
	{"style.caret.width", "1"},
	{"style.caret.line.back", ""},
	{"style.caret.line.back.alpha", "256"},
	{0, 0},
};

// {3E56779F-2884-4f98-9A61-992F664999D0}
static const GUID guid_prop_sets = 
{ 0x3e56779f, 0x2884, 0x4f98, { 0x9a, 0x61, 0x99, 0x2f, 0x66, 0x49, 0x99, 0xd0 } };
cfg_sci_prop_sets g_sci_prop_sets(guid_prop_sets, prop_sets_init_table);


void cfg_sci_prop_sets::get_data_raw(stream_writer * p_stream, abort_callback & p_abort)
{
	try
	{
		p_stream->write_lendian_t(m_data.get_count(), p_abort);

		for (t_size i = 0; i < m_data.get_count(); ++i)
		{
			p_stream->write_string(m_data[i].key, p_abort);
			p_stream->write_string(m_data[i].val, p_abort);
		}
	}
	catch (std::exception &)
	{

	}
}

void cfg_sci_prop_sets::set_data_raw(stream_reader * p_stream, t_size p_sizehint, abort_callback & p_abort)
{
	t_str_to_str_map data_map;
	pfc::string8_fast key, val;
	t_size count;

	try
	{
		p_stream->read_lendian_t(count, p_abort);

		for (t_size i = 0; i < count; ++i)
		{
			p_stream->read_string(key, p_abort);
			p_stream->read_string(val, p_abort);

			data_map[key] = val;
		}
	} 
	catch (std::exception &)
	{
		// Load default
		init_data(prop_sets_init_table);
		return;
	}

	merge_data(data_map);
}

void cfg_sci_prop_sets::reset()
{
	for (t_size i = 0; i < m_data.get_count(); ++i)
	{
		m_data[i].val = m_data[i].defaultval;
	}
}

void cfg_sci_prop_sets::export_to_file(const char * filename)
{
	file_ptr io;
	abort_callback_dummy abort;

	try
	{
		filesystem::g_open_write_new(io, filename, abort);

		io->write_string_raw("# Generated by WSH Panel Mod\r\n", abort);

		for (t_size i = 0; i < m_data.get_count(); ++i)
		{
			io->write_string_raw(m_data[i].key, abort);
			io->write_string_raw("=", abort);
			io->write_string_raw(m_data[i].val, abort);
			io->write_string_raw("\r\n", abort);
		}
	}
	catch (std::exception &)
	{
		return;
	}
}

void cfg_sci_prop_sets::import_from_file(const char * filename)
{
	typedef pfc::chain_list_v2_t<pfc::string8_fast> t_string_chain_list;
	t_string_chain_list lines;
	pfc::string8_fast text, key;
	t_str_to_str_map data_map;
	file_ptr io;
	abort_callback_dummy abort;

	try
	{
		filesystem::g_open_read(io, filename, abort);

		// First read whole content in a string
		io->read_string_raw(text, abort);
	}
	catch (std::exception &)
	{
		return;
	}

	splitStringByLines(lines, text);

	// Read data
	for (t_string_chain_list::iterator iter = lines.first(); iter != lines.last(); ++iter)
	{
		if (iter->get_length() > 0)
		{
			int len = iter->get_length();
			const char * ptr = iter->get_ptr();

			// Comment or len two small, skip
			if (*ptr == '#' || len <= 3)
				continue;

			const char * delim = strchr(ptr, '=');

			if (delim - ptr + 1 > len)
				continue;

			key.set_string(ptr, delim - ptr);
			data_map[key].set_string(delim + 1);
		}
	}

	// Merge
	merge_data(data_map);
}

void cfg_sci_prop_sets::init_data(const t_prop_set_init_table * p_default)
{
	t_sci_prop_set temp;

	m_data.remove_all();

	for (int i = 0; p_default[i].key; ++i)
	{
		temp.key = p_default[i].key;
		temp.defaultval = p_default[i].defaultval;
		temp.val = temp.defaultval;
		m_data.add_item(temp);
	}
}

void cfg_sci_prop_sets::merge_data(const t_str_to_str_map & data_map)
{
	pfc::string8_fast val;

	for (t_size i = 0; i < m_data.get_count(); ++i)
	{
		if (data_map.query(m_data[i].key, val))
		{
			m_data[i].val = val;
		}
	}
}
