using craftsReport.Interfaces;
using System;
using System.Collections.Generic;

namespace craftsReport.modules
{
	public class rp1101_xbs : IReportModule, IReportModuleEvents
	{
		#region Members and Contructor

		private bool m_IsLastPage = false;
		private int m_ZeileMax;
		private string m_HeaderResourceName = "KopfDetail";

		class Summen
        {
			public decimal Soll { set; get; }
			public decimal Haben { set; get; }
		}
		Dictionary<string, Summen> m_Summen = new Dictionary<string, Summen>();		

		public rp1101_xbs()
		{
		}

		#endregion

		#region IReportModule

		public IReportHost HostObject { set; get; }

		// Kladdenzeilen
		public bool Execute()
		{
			if (!HostObject.IsVar("mCode"))
				HostObject.DefineVariable2("mCode", "u,20,0");
			if (HostObject.IsEmpty("mCode"))
				HostObject.Set("mCode", @"BELEGSTAPEL ", true);

			if (!HostObject.IsVar("mRepTitle"))
				HostObject.DefineVariable2("mRepTitle", "c,250,0");
			if (HostObject.IsEmpty("mRepTitle"))
				HostObject.Set("mRepTitle", "Erfassungsstapel", false);

			// SQL-Abfrage erstellen
			#region SqlQuery (Satznummernabfrage nach recSQLMain)
			// ---------------------------------------------------------------------------------
			System.Text.StringBuilder sbCondition = new System.Text.StringBuilder();
			sbCondition.Append("WHERE ((VkzExport = 1) OR (TransNo = ''))");
			string bsFilterText = "";

			if (!HostObject.IsEmpty("mCode"))
			{
				sbCondition.Append(" AND (Code = " + HostObject.FormatSqlString("$[mCode]", true) + ")");
				bsFilterText = HostObject.EvalString("$[mCode]");
			}

			if (HostObject.IsVar("Jahr") && (!HostObject.IsEmpty("Jahr")))
            {
				sbCondition.Append(" AND (YEAR(BuchDatum) = " + HostObject.EvalString("$[Jahr]") + ")");
				bsFilterText += "|" + HostObject.EvalString("$[Jahr]");

				if (HostObject.IsVar("Monat") && (!HostObject.IsEmpty("Monat")))
				{
					sbCondition.Append(" AND (MONTH(BuchDatum) = " + HostObject.EvalString("$[Monat]") + ")");
					bsFilterText += "|" + HostObject.EvalString("$[Monat]");

					if (HostObject.IsVar("Tag") && (!HostObject.IsEmpty("Tag")))
					{
						sbCondition.Append(" AND (DAY(BuchDatum) = " + HostObject.EvalString("$[Tag]") + ")");
						bsFilterText += "|" + HostObject.EvalString("$[Tag]");
					}
				}
			}

			string bsMainQuery = "SELECT RecId FROM dbo.ut_KladdenZeile " + sbCondition.ToString() + " ORDER BY Code, LfdNr";
			var recSqlMain = HostObject.DefineSqlRecord("recSQLMain", bsMainQuery);
			if (recSqlMain == null)
			{
				HostObject.Confirm("Die SQL-Abfrage ist fehlgeschlagen\r\n\r\n" + bsMainQuery);
				return false;
			}
			// ---------------------------------------------------------------------------------

			HostObject.DefineVariable2("mFilterText", "c,250,0");
			HostObject.Set("mFilterText", bsFilterText, false);
			#endregion

			HostObject.LoadAdditionalResources("/r");
			HostObject.PaperDefinition("PaperDefinition");
			m_ZeileMax = HostObject.EvalInt("$[ZlMax]");

			HostObject.DefineRecord("recBK", "KLADDENZEILE", 0, 0, "");
			HostObject.DefineVariable2("BilExists", "L,1,0");
			HostObject.DefineVariable2("BilSoll", "N,12,2");
			HostObject.DefineVariable2("BilHaben", "N,12,2");

			HostObject.DokumentStart();
			HostObject.SeitenKopf();

			//  Schleife ueber Zeilen
			while (!recSqlMain.Eof)
			{
				HostObject.SeekRecord("recBK", HostObject.CastInt(recSqlMain.GetI(1)));
				SUB_loopMAIN();
				recSqlMain.GoNext();
			}
			SUB_subBilanzOut();
			if ((m_ZeileMax) > HostObject.EvalInt("$[Zeile]"))
				HostObject.ProcessResource("Sterne");

			// Summen je Konto
			m_HeaderResourceName = "KopfKontoSumme";
			HostObject.FormFeed();
			SUB_SummenAusgeben();
			if ((m_ZeileMax) > HostObject.EvalInt("$[Zeile] + 1"))
				HostObject.ProcessResource("BilanzSumme");
			if ((m_ZeileMax) > HostObject.EvalInt("$[Zeile]"))
				HostObject.ProcessResource("Sterne");

			m_IsLastPage = true;
			HostObject.SeitenFuss();
			HostObject.DokumentEnde();
			return true;
		}

		#endregion

		#region IReportModuleEvents

		public void OnAfterPageStart()
		{
			HostObject.ProcessResource(m_HeaderResourceName);

			if (HostObject.EvalInt("$[Seite]") == 1)
			{
			}
			else
			{
			}
		}

		public void OnBeforePageClose()
		{
			if (m_IsLastPage)
			{
				//if ((m_ZeileMax) > HostObject.EvalInt("$[Zeile]"))
				//	HostObject.ProcessResource("Sterne");
			}
			else
			{
			}
		}

		public void OnAfterExecute(string szOutFileName)
		{
		}

		#endregion

		#region Internals

		bool SUB_loopMAIN()
		{
			HostObject.VariablesPush();

			//  ---------- erster Datensatz druckt vorherige Bilanz und Ueberschrift
			if (!HostObject.EvalBool("$[recBK.Joined]"))
			{
				// Abschluss vorherige Zeile
				SUB_subBilanzOut();

				HostObject.Set("BilSoll", @"0", true);
				HostObject.Set("BilHaben", @"0", true);
				HostObject.Set("BilExists", @"1", true);

				HostObject.CheckPageSpace(4);
				SUB_subFillLine();
				HostObject.ProcessResource("KopfTransaction");
			}

			//  ------------------ Betrag 0
			if (HostObject.EvalBool("($[recBK.Betrag]) = (0)"))
				return HostObject.VariablesPop();

			HostObject.DefineVariable2("mTyp", "C,1,0");
			HostObject.DefineVariable2("mKonto", "C,8,0");
			HostObject.DefineVariable2("mSoll", "N,12,2");
			HostObject.DefineVariable2("mHaben", "N,12,2");
			HostObject.DefineVariable2("cSoll", "C,12,0");
			HostObject.DefineVariable2("cHaben", "C,12,0");
			HostObject.DefineVariable2("mCurrBetra", "N,12,2");

			//  -------------------------------- Gegenkonto
			if (!HostObject.IsEmpty("recBK.GK_Typ"))
				SUB_subGKonto();

			//  -------------------------------- Konto
			if (!HostObject.IsEmpty("recBK.Typ"))
				SUB_subKonto();

			return HostObject.VariablesPop();
		}

		void SUB_subGKonto()
		{
			if (HostObject.IsEmpty("recBK.GK_KtoUSt") || HostObject.EvalBool("($[recBK.MWSt]) = (0)") || (HostObject.EvalString("$[recBK.GK_Typ]") == "P"))
			{
				//  --------------------------- kein Mehrwertsteueranteil
				HostObject.Set("mTyp", @"$[recBK.GK_Typ]", true);
				HostObject.Set("mKonto", @"$[recBK.GK_Kto]", true);
				HostObject.Set("mCurrBetra", @"$[recBK.Betrag]", true);
				if (HostObject.EvalBool("($[recBK.Betrag]) < (0)"))
					SUB_subGKontoSoll();
				else
					SUB_subGKontoHabe();
				SUB_subDetailOut();
			}
			else
			{
				//  ---------------------------- Nettoanteil
				HostObject.Set("mTyp", @"$[recBK.GK_Typ]", true);
				HostObject.Set("mKonto", @"$[recBK.GK_Kto]", true);
				HostObject.Set("mCurrBetra", @"$[recBK.Netto]", true);
				if (HostObject.EvalBool("($[recBK.Betrag]) < (0)"))
					SUB_subGKontoSoll();
				else
					SUB_subGKontoHabe();
				SUB_subDetailOut();

				//  ---------------------------- Steueranteil
				HostObject.Set("mTyp", @"U", true);
				HostObject.Set("mKonto", @"$[recBK.GK_KtoUSt]", true);
				HostObject.Set("mCurrBetra", @"$[recBK.MWSt]", true);
				if (HostObject.EvalBool("($[recBK.Betrag]) < (0)"))
					SUB_subGKontoSoll();
				else
					SUB_subGKontoHabe();
				SUB_subDetailOut();
			}
		}

		void SUB_subKonto()
		{
			if (HostObject.IsEmpty("recBK.KtoUSt") || HostObject.EvalBool("($[recBK.MWSt]) = (0)") || (HostObject.EvalString("$[recBK.Typ]") == "P"))
			{
				//  --------------------------- kein Mehrwertsteueranteil
				HostObject.Set("mTyp", @"$[recBK.Typ]", true);
				HostObject.Set("mKonto", @"$[recBK.Kto]", true);
				HostObject.Set("mCurrBetra", @"0.00 - $[recBK.Betrag]", true);
				if (HostObject.EvalBool("($[recBK.Betrag]) < (0)"))
					SUB_subKontoHabe();
				else
					SUB_subKontoSoll();
				SUB_subDetailOut();
			}
			else
			{
				//  ---------------------------- Nettoanteil
				HostObject.Set("mTyp", @"$[recBK.Typ]", true);
				HostObject.Set("mKonto", @"$[recBK.Kto]", true);
				HostObject.Set("mCurrBetra", @"0.00 - $[recBK.Netto]", true);
				if (HostObject.EvalBool("($[recBK.Betrag]) < (0)"))
					SUB_subKontoHabe();
				else
					SUB_subKontoSoll();
				SUB_subDetailOut();

				//  ---------------------------- Steueranteil
				HostObject.Set("mTyp", @"U", true);
				HostObject.Set("mKonto", @"$[recBK.KtoUSt]", true);
				HostObject.Set("mCurrBetra", @"0.00 - $[recBK.MWSt]", true);
				if (HostObject.EvalBool("($[recBK.Betrag]) < (0)"))
					SUB_subKontoHabe();
				else
					SUB_subKontoSoll();
				SUB_subDetailOut();
			}
		}

		void SUB_subDetailOut()
		{
			HostObject.CheckPageSpace(1);
			if (HostObject.IsEmpty("mKonto"))
				SUB_subFillRed();

			HostObject.ProcessResource("Detail");
			if (!HostObject.IsEmpty("mKonto"))
			{
				HostObject.Set("BilSoll", @"$[BilSoll] + $[mSoll]", true);
				HostObject.Set("BilHaben", @"$[BilHaben] + $[mHaben]", true);
			}

			string bsKonto = HostObject.GetVariable("mKonto").Get();
			if (!String.IsNullOrEmpty(bsKonto))
			{
				if (!m_Summen.ContainsKey(bsKonto))
					m_Summen.Add(bsKonto, new Summen());
				m_Summen[bsKonto].Soll += (decimal)(HostObject.GetVariable("mSoll").GetDouble());
				m_Summen[bsKonto].Haben += (decimal)(HostObject.GetVariable("mHaben").GetDouble());
			}
		}

		void SUB_subGKontoSoll()
		{
			HostObject.Set("mSoll", @"0,00 - $[mCurrBetra]", true);
			HostObject.Set("mHaben", @"0,00", true);
			HostObject.Set("cSoll", @"$[mSoll]", true);
			HostObject.Set("cHaben", @"", true);
		}

		void SUB_subGKontoHabe()
		{
			HostObject.Set("mSoll", @"0,00 ", true);
			HostObject.Set("mHaben", @"$[mCurrBetra]", true);
			HostObject.Set("cSoll", @"", true);
			HostObject.Set("cHaben", @"$[mHaben]", true);
		}

		void SUB_subKontoSoll()
		{
			HostObject.Set("mSoll", @"0,00 - $[mCurrBetra]", true);
			HostObject.Set("mHaben", @"0,00", true);
			HostObject.Set("cSoll", @"$[mSoll]", true);
			HostObject.Set("cHaben", @"", true);
		}

		void SUB_subKontoHabe()
		{
			HostObject.Set("mSoll", @"0,00 ", true);
			HostObject.Set("mHaben", @"$[mCurrBetra]", true);
			HostObject.Set("cSoll", @"", true);
			HostObject.Set("cHaben", @"$[mHaben]", true);
		}

		void SUB_subBilanzOut()
		{
			if (HostObject.EvalBool("$[BilExists]"))
			{
				HostObject.CheckPageSpace(1);
				if (HostObject.EvalBool("($[BilSoll]) <> ($[BilHaben])"))
					SUB_subFillRed();
				HostObject.ProcessResource("Bilanz");
			}
		}

		bool SUB_subFillRed()
		{
			return FillLine(15263999);
		}

		bool SUB_subFillLine()
		{
			return FillLine(15263976);
		}

		bool FillLine(int nColor)
		{
			HostObject.VariablesPush();
			HostObject.DefineVariable2("mFillStart", "d,8,2");
			HostObject.Set("mFillStart", @" $[RandY] + ($[cyZeile] * $[Zeile])", true);
			HostObject.WriteLine(HostObject.EvalString(@"RGBFILL $[RandX];$[mFillStart];$[SizeX];$[cyZeile];" + nColor.ToString()));
			return HostObject.VariablesPop();
		}

		void SUB_SummenAusgeben()
        {
			HostObject.Set("BilSoll", @"0", true);
			HostObject.Set("BilHaben", @"0", true);

			HostObject.VariablesPush();
			var recKonto = HostObject.DefineRecord("recKonto", "Kontenplan", 0, 0, "");
			var vSoll = HostObject.DefineVariable2("mSoll", "N,12,2");
			var vHaben = HostObject.DefineVariable2("mHaben", "N,12,2");

			// Personenkonten
			HostObject.CheckPageSpace(4);
			HostObject.ProcessResource("KopfPersonenKonten");
			foreach (var s in m_Summen)
            {
				vSoll.Set(s.Value.Soll.ToString());
				vHaben.Set(s.Value.Haben.ToString());
				recKonto.Find("P" + s.Key.PadRight(8));
				if (!recKonto.Eof)
				{
					HostObject.CheckPageSpace(1);
					HostObject.ProcessResource("KontoSumme");
					HostObject.Set("BilSoll", "$[BilSoll] + $[mSoll]", true);
					HostObject.Set("BilHaben", "$[BilHaben] + $[mHaben]", true);
				}
			}

			// Sachkonten
			HostObject.CheckPageSpace(4);
			HostObject.ProcessResource("KopfSachKonten");
			foreach (var s in m_Summen)
			{
				vSoll.Set(s.Value.Soll.ToString());
				vHaben.Set(s.Value.Haben.ToString());
				recKonto.Find("S" + s.Key.PadRight(8));
				if (!recKonto.Eof)
				{
					HostObject.CheckPageSpace(1);
					HostObject.ProcessResource("KontoSumme");
					HostObject.Set("BilSoll", "$[BilSoll] + $[mSoll]", true);
					HostObject.Set("BilHaben", "$[BilHaben] + $[mHaben]", true);
				}
			}

			HostObject.VariablesPop();
		}

		#endregion
	}
}
