using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using CaLib.Encryption;
using System.Diagnostics;

namespace ClipClop.User
{
	class XmlFileReader
	{
		readonly string xsdpath_;

		string lastReadFile_;

		List<string> errorMessages_ = new List<string>();

		public XmlFileReader(string xsdpath)
		{
			this.xsdpath_ = xsdpath;
		}

		public bool Read(XmlDocument doc, string filepath)
		{
			errorMessages_.Clear();
			lastReadFile_ = filepath;

			try
			{
				XmlReaderSettings settings = new XmlReaderSettings();
				XmlReader xsdReader = XmlReader.Create(this.xsdpath_);

				settings.IgnoreComments = true;
				settings.IgnoreWhitespace = true;
				settings.Schemas.Add(null, xsdReader);
				settings.ValidationEventHandler += new ValidationEventHandler(SchemaValidationHandler);
				settings.ValidationType = ValidationType.Schema;

				using (XmlReader reader = XmlReader.Create(filepath, settings))
				{
					doc.Load(reader);
					reader.Close();
				}
			}
			catch (Exception exp)
			{
				errorMessages_.Add(exp.Message);
				return false;
			}

			return errorMessages_.Count>0?false:true;
		}

		void SchemaValidationHandler(object sender, ValidationEventArgs e)
		{
			///引数のeにエラーなのか警告なのかが指定されます。
			///e.Exception.LineNumber：問題が発生した行数
			///e.Exception.LinePosition：問題が発生したカラム数

			if (e.Severity == XmlSeverityType.Warning)
			{
				//警告の場合
			}
			else
			{
				errorMessages_.Add(
					string.Format(global::ClipClop.Properties.Resources.MSG004, e.Exception.LineNumber, e.Exception.LinePosition, e.Message)
				);
			}
		}

		const int MAX_ERROR_COUNT_ = 10;

		public string GetErrorMessage()
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendLine(global::ClipClop.Properties.Resources.EF008);
			sb.AppendLine(lastReadFile_ + Environment.NewLine);

			int count = 0;
			foreach (string s in this.errorMessages_)
			{
				if (count > MAX_ERROR_COUNT_)
				{
					sb.AppendLine(" ...");
					break;
				}
				sb.AppendLine(" " + s);
				count++;
			}
			return sb.ToString();
		}
	}
}
