using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.Web;
using BeWo.Service.Plugins;
using BS.Shared.Core;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.ServiceContracts;
using BeWo.Service.Security;

using BS.Shared;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using BS.Shared.RSS;
using BS.Shared.Services;
using DevExpress.XtraReports.UI;
using System.Xml.Serialization;
using Utils = BeWo.Service.Core.Utils;

namespace BeWo.Service.ServiceImplementations
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
    public class DownloadServiceImp : IDownloadService
    {
        public string PrepareExcelFile(string pFileID, string[] pHeaderCaption, string[][] pContent)
        {
            try
            {
                return WriteHTMLFile(pHeaderCaption, pContent);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string PrepareExcelFileCustomerExport(string pFileID, long[] pSortedOids)
        {
            try
            {
                var lCustomers = DAOFactory.GenericDAO.LoadByIDs<Customer>(pSortedOids);

                string[] lHeaderCaption = {
                                              "Nachname", // 0
                                              "Vorname", // 1
                                              "Geburtsdatum", // 3
                                              "Beruf", // 4
                                              "Geschlecht", // 5
                                              "Familienstand", // 6
                                              "Telefon", // 7
                                              "Mobil", // 8
                                              "Mail", // 9
                                              "Fax", // 10
                                              "Strasse", // 11
                                              "PLZ", // 12
                                              "Ort", // 13
                                              "Bemerkung", // 14
                                              "Erstbetreuung" // 15
                                          };
                var lContent = new string[lCustomers.Count][];

                for (int iRowCount = 0; iRowCount < lCustomers.Count; iRowCount++)
                {
                    lContent[iRowCount] = new string[lHeaderCaption.Count()];

                    lContent[iRowCount][0] = lCustomers[iRowCount].Person.LastName;
                    lContent[iRowCount][1] = lCustomers[iRowCount].Person.FirstName;
                    //lContent[iRowCount][2] = lCustomers[iRowCount].ReferenceNumber;

                    if (lCustomers[iRowCount].Person.DateOfBirth.HasValue)
                    {
                        lContent[iRowCount][2] = lCustomers[iRowCount].Person.DateOfBirth.Value.ToShortDateString();
                    }

                    lContent[iRowCount][3] = lCustomers[iRowCount].Person.Profession;

                    lContent[iRowCount][4] = lCustomers[iRowCount].Person.Sex == Sex.Male
                                                 ? "männlich"
                                                 : "weiblich";

                    if (lCustomers[iRowCount].Person.FamilyStatus != null)
                    {
                        switch (lCustomers[iRowCount].Person.FamilyStatus.Value)
                        {
                            case FamilyStatus.Divorced:
                                lContent[iRowCount][5] = "geschieden";
                                break;
                            case FamilyStatus.Married:
                                lContent[iRowCount][5] = "verheiratet";
                                break;
                            case FamilyStatus.Single:
                                lContent[iRowCount][5] = "ledig";
                                break;
                            case FamilyStatus.Widowed:
                                lContent[iRowCount][5] = "verwitwet";
                                break;
                            case FamilyStatus.Partner:
                                lContent[iRowCount][5] = "in Partnerschaft";
                                break;
                            case FamilyStatus.PartnerDivorced:
                                lContent[iRowCount][5] = "getrennt lebend";
                                break;
                            case FamilyStatus.PartnerDead:
                                lContent[iRowCount][5] = "partnerhinterblieben";
                                break;
							case FamilyStatus.PartnerMarried:
                                lContent[iRowCount][5] = "verpartnert";
                                break;
							case FamilyStatus.Entpartnert:
                                lContent[iRowCount][5] = "entpartnert";
                                break;
                        }
                    }

                    foreach (var iContact in lCustomers[iRowCount].Person.Contacts)
                    {
                        switch (iContact.Type)
                        {
                            case ContactType.business_Phone:
                                lContent[iRowCount][6] = iContact.Value;
                                break;
                            case ContactType.business_MobilePhone:
                                lContent[iRowCount][7] = iContact.Value;
                                break;
                            case ContactType.business_Mail:
                                lContent[iRowCount][8] = iContact.Value;
                                break;
                            case ContactType.business_Fax:
                                lContent[iRowCount][9] = iContact.Value;
                                break;
                        }
                    }

                    if (lCustomers[iRowCount].Person.Address != null)
                    {
                        lContent[iRowCount][10] = lCustomers[iRowCount].Person.Address.Street;
                        lContent[iRowCount][11] = lCustomers[iRowCount].Person.Address.PostalCode;
                        lContent[iRowCount][12] = lCustomers[iRowCount].Person.Address.Town;
                    }

                    lContent[iRowCount][13] = lCustomers[iRowCount].Notice;

                    if (lCustomers[iRowCount].Employee2CustomerList == null) 
                        continue;

                    foreach (var e2c in lCustomers[iRowCount].Employee2CustomerList)
                    {
                        foreach (var vle in e2c.ValueList.Select(vle2o => vle2o.Entry).Where(vle => vle.SystemEntryID != null && vle.SystemEntryID.Value == SystemEntryID.EmployeeRoleMainAttendant))
                        {
                            lHeaderCaption[lHeaderCaption.Length - 1] = vle.Value;
                            lContent[iRowCount][14] = e2c.Employee.Person.FirstName + " " + e2c.Employee.Person.LastName;
                        }
                    }
                }

                //WriteExcelFile(pFileID, lHeaderCaption, lContent, pPath);
                return WriteHTMLFile(lHeaderCaption, lContent);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string PrepareExcelFileEmployeeExport(string pFileID, long[] pSortedOids)
        {
            try
            {
                var lEmployees = DAOFactory.GenericDAO.LoadByIDs<Employee>(pSortedOids);

                string[] lHeaderCaption = {
                                              "Nachname", // 0
                                              "Vorname", // 1
                                              "Personalnummer", // 2
                                              "Geburtsdatum", // 3
                                              "Beruf", // 4
                                              "Geschlecht", // 5
                                              "Familienstand", // 6
                                              "Krankenkasse", // 7
                                              "Steuernummer", // 8
                                              "beschäftigt als", // 9
                                              "Probezeit (Tage)", // 10
                                              "Kündigungsfrist (Tage)", // 11
                                              "Urlaubstage", // 12
                                              "FLS/Woche", // 13
                                              "Gesamtstunden/Woche", // 14
											  "Arbeitstage pro Woche", // 15
                                              "Eintrittsdatum", // 16
                                              "Versicherungsnummer", 
                                              "Stundensatz", 
                                              "Telefon", 
                                              "Mobil", // 20
                                              "Mail", 
                                              "private Mail", 
                                              "Fax",
                                              "Strasse",
                                              "PLZ", // 25
                                              "Ort", 
                                              "Kontonummer", 
                                              "Bankleitzahl",
                                              "Bank",
                                              "BIC", // 30
                                              "IBAN", 
                                              "Bemerkung" // 32
                                          };
                string[][] lContent = new string[lEmployees.Count][];

                for (int iRowCount = 0; iRowCount < lEmployees.Count; iRowCount++)
                {
                    lContent[iRowCount] = new string[lHeaderCaption.Count()];

                    lContent[iRowCount][0] = lEmployees[iRowCount].Person.LastName;
                    lContent[iRowCount][1] = lEmployees[iRowCount].Person.FirstName;
                    lContent[iRowCount][2] = lEmployees[iRowCount].PersonnelNumber;

                    lContent[iRowCount][3] = lEmployees[iRowCount].Person.DateOfBirth.DoIfNotNull(d => d.ToShortDateString());

                    lContent[iRowCount][4] = lEmployees[iRowCount].Person.Profession;

                    lContent[iRowCount][5] = lEmployees[iRowCount].Person.Sex == Sex.Male
                                                 ? "männlich"
                                                 : "weiblich";

                    if (lEmployees[iRowCount].Person.FamilyStatus != null)
                    {
                        switch (lEmployees[iRowCount].Person.FamilyStatus.Value)
                        {
                            case FamilyStatus.Divorced:
                                lContent[iRowCount][6] = "geschieden";
                                break;
                            case FamilyStatus.Married:
                                lContent[iRowCount][6] = "verheiratet";
                                break;
                            case FamilyStatus.Single:
                                lContent[iRowCount][6] = "ledig";
                                break;
                            case FamilyStatus.Widowed:
                                lContent[iRowCount][6] = "verwitwet";
                                break;
                            case FamilyStatus.Partner:
                                lContent[iRowCount][6] = "in Partnerschaft";
                                break;
							case FamilyStatus.PartnerDivorced:
                                lContent[iRowCount][6] = "getrennt lebend";
                                break;
							case FamilyStatus.PartnerDead:
								lContent[iRowCount][5] = "partnerhinterblieben";
								break;
							case FamilyStatus.PartnerMarried:
								lContent[iRowCount][5] = "verpartnert";
								break;
							case FamilyStatus.Entpartnert:
								lContent[iRowCount][5] = "entpartnert";
								break;
                        }
                    }

                    lContent[iRowCount][7] = lEmployees[iRowCount].HealthInsurance;
                    lContent[iRowCount][8] = lEmployees[iRowCount].TaxNumber;

                    var lValuelistEntry = lEmployees[iRowCount].ValueList.SingleOrDefault(vle => vle.Entry.Type == ValueListEntryType.EmploymentType);
                    if (lValuelistEntry != null)
                    {
                        lContent[iRowCount][9] = lValuelistEntry.Entry.Value;
                    }

                    Contract lastContract = lEmployees[iRowCount].LastContract;

                    if (lastContract != null)
                    {

                        lContent[iRowCount][10] = lastContract.ProbationPeriod.ToString();
                        lContent[iRowCount][11] = lastContract.CancellationPeriod.ToString();
                        if (lastContract.LeaveDays.HasValue)
                        {
                            lContent[iRowCount][12] = lastContract.LeaveDays.Value.ToStringNullCheck();
                        }

                        if (lastContract.WeeklyFLS.HasValue)
                        {
                            lContent[iRowCount][13] = lastContract.WeeklyFLS.Value.ToStringNullCheck();
                        }

                        if (lastContract.WeeklyTotalHours.HasValue)
                        {
                            lContent[iRowCount][14] = lastContract.WeeklyTotalHours.Value.ToStringNullCheck();
                        }

						var wd = lastContract.WeeklyDays ?? 5;
						
						if (wd == 0)
							wd = 5;

						lContent[iRowCount][15] = String.Format("{0}", wd);
						
						lContent[iRowCount][16] = lastContract.EntryDate.DoIfNotNull(d => d.ToShortDateString());
                    }

                    lContent[iRowCount][17] = lEmployees[iRowCount].InsuranceNumber;

                    if (lastContract != null)
                    {
                        if (lastContract.HourlyRate.HasValue)
                        {
                            lContent[iRowCount][18] = lastContract.HourlyRate.Value.ToStringNullCheck();
                        }
                    }
                    foreach (var iContact in lEmployees[iRowCount].Person.Contacts)
                    {
                        switch (iContact.Type)
                        {
                            case ContactType.business_Phone:
                                lContent[iRowCount][19] = iContact.Value;
                                break;
                            case ContactType.business_MobilePhone:
                                lContent[iRowCount][20] = iContact.Value;
                                break;
                            case ContactType.business_Mail:
                                lContent[iRowCount][21] = iContact.Value;
                                break;
                            case ContactType.private_Mail:
                                lContent[iRowCount][22] = iContact.Value;
                                break;
                            case ContactType.business_Fax:
                                lContent[iRowCount][23] = iContact.Value;
                                break;
                        }
                    }

                    if (lEmployees[iRowCount].Person.Address != null)
                    {
                        lContent[iRowCount][24] = lEmployees[iRowCount].Person.Address.Street;
                        lContent[iRowCount][25] = lEmployees[iRowCount].Person.Address.PostalCode;
                        lContent[iRowCount][26] = lEmployees[iRowCount].Person.Address.Town;
                    }

                    if (lEmployees[iRowCount].Person.BankAccount != null)
                    {
                        lContent[iRowCount][27] = lEmployees[iRowCount].Person.BankAccount.AccountNumber;
                        lContent[iRowCount][28] = lEmployees[iRowCount].Person.BankAccount.BankCode;
                        lContent[iRowCount][29] = lEmployees[iRowCount].Person.BankAccount.BankName;
                        lContent[iRowCount][30] = lEmployees[iRowCount].Person.BankAccount.Bic;
                        lContent[iRowCount][31] = lEmployees[iRowCount].Person.BankAccount.IBAN;
                    }

                    lContent[iRowCount][32] = lEmployees[iRowCount].Notice;
                    
                }

                return WriteHTMLFile(lHeaderCaption, lContent);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string PrepareExcelFileOrganisationExport(string pFileID, long[] pSortedOids)
        {
            try
            {
                var lOrganisations = DAOFactory.GenericDAO.LoadByIDs<Organisation>(pSortedOids);

                string[] lHeaderCaption = {
                                              "Name", // 0
                                              "Notizen", // 1
                                              "Ist Kostenträger", // 2
                                              "Stundensatz", // 3
                                              "Rundungsintervall (Minuten)", // 4
                                              "pauschaler Faktor (%)", // 5
                                              "Strasse", // 6
                                              "PLZ", // 7
                                              "Ort", // 8
                                              "Postfach", // 9
                                              "Telefon", // 10
                                              "Fax", // 11
                                              "Mail", // 12
                                              "Homepage" // 13
                                          };
                string[][] lContent = new string[lOrganisations.Count][];

                for (int iRowCount = 0; iRowCount < lOrganisations.Count; iRowCount++)
                {
                    lContent[iRowCount] = new string[lHeaderCaption.Count()];

                    lContent[iRowCount][0] = lOrganisations[iRowCount].Name;
                    lContent[iRowCount][1] = lOrganisations[iRowCount].Notice;
                    lContent[iRowCount][2] = lOrganisations[iRowCount].CostBearer != null
                                                 ? "Ja"
                                                 : "Nein";
                    if (lOrganisations[iRowCount].CostBearer != null)
                    {
                        var costRates = lOrganisations[iRowCount].CostBearer.CostRatePeriods.MapToNewDCs();

                        lContent[iRowCount][3] = costRates.GetCurrentlyValidRateValue(CostRatePeriodType.HourlyRate).ToStringNullCheck();
                        lContent[iRowCount][4] = costRates.GetCurrentlyValidRateValue(CostRatePeriodType.MinutesIntervall).ToStringNullCheck();
                        lContent[iRowCount][5] = costRates.GetCurrentlyValidRateValue(CostRatePeriodType.RateFactor).ToStringNullCheck();
                    }

                    if (lOrganisations[iRowCount].Address != null)
                    {
                        lContent[iRowCount][6] = lOrganisations[iRowCount].Address.Street;
                        lContent[iRowCount][7] = lOrganisations[iRowCount].Address.PostalCode;
                        lContent[iRowCount][8] = lOrganisations[iRowCount].Address.Town;
                    }

                    foreach (var iContact in lOrganisations[iRowCount].Contacts)
                    {
                        switch (iContact.Type)
                        {
                            case ContactType.business_POBox:
                                lContent[iRowCount][9] = iContact.Value;
                                break;
                            case ContactType.business_Phone:
                                lContent[iRowCount][10] = iContact.Value;
                                break;
                            case ContactType.business_Fax:
                                lContent[iRowCount][11] = iContact.Value;
                                break;
                            case ContactType.business_Mail:
                                lContent[iRowCount][12] = iContact.Value;
                                break;
                            case ContactType.business_Homepage:
                                lContent[iRowCount][13] = iContact.Value;
                                break;
                        }
                    }
                }

                return WriteHTMLFile(lHeaderCaption, lContent);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string PrepareExcelFilePersonExport(string pFileID, long[] pSortedOids)
        {
            try
            {
                string lPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, pFileID + ".tmp");

                var lPersons = DAOFactory.GenericDAO.LoadByIDs<Person>(pSortedOids);

                string[] lHeaderCaption = {
                                              "Titel", // 0
                                              "Nachname", // 1
                                              "Vorname", // 2
                                              "Funktion", // 3
                                              "Geburtsdatum", // 4
                                              "Strasse", // 5
                                              "PLZ", // 6
                                              "Ort", // 7
                                              "Telefon", // 8
                                              "Mobil", // 9
                                              "Mail", // 10
                                              "Fax", // 11
                                              "Bemerkung" // 12
                                          };
                string[][] lContent = new string[lPersons.Count][];

                for (int iRowCount = 0; iRowCount < lPersons.Count; iRowCount++)
                {
                    lContent[iRowCount] = new string[lHeaderCaption.Count()];

                    if (lPersons[iRowCount].Title != null)
                    {
                        lContent[iRowCount][0] = lPersons[iRowCount].Title.Value;
                    }
                    else
                    {
                        lContent[iRowCount][0] = string.Empty;
                    }
                    lContent[iRowCount][1] = lPersons[iRowCount].LastName;
                    

                    lContent[iRowCount][2] = lPersons[iRowCount].FirstName;
                    

                    if (lPersons[iRowCount].Function != null)
                    {
                        lContent[iRowCount][3] = lPersons[iRowCount].Function.Value;
                    }
                    else
                    {
                        lContent[iRowCount][3] = string.Empty;
                    }

                    lContent[iRowCount][4] = lPersons[iRowCount].DateOfBirth.DoIfNotNull(d => d.ToShortDateString());

                    // lContent[iRowCount][4] = lPersons[iRowCount].Sex == Sex.Male ? "männlich" : "weiblich";
                    if (lPersons[iRowCount].Address != null)
                    {
                        lContent[iRowCount][5] = lPersons[iRowCount].Address.Street;
                        lContent[iRowCount][6] = lPersons[iRowCount].Address.PostalCode;
                        lContent[iRowCount][7] = lPersons[iRowCount].Address.Town;
                    }

                    foreach (var iContact in lPersons[iRowCount].Contacts)
                    {
                        switch (iContact.Type)
                        {
                            case ContactType.private_Phone:
                                lContent[iRowCount][8] = iContact.Value;
                                break;
                            case ContactType.private_MobilePhone:
                                lContent[iRowCount][9] = iContact.Value;
                                break;
                            case ContactType.private_Mail:
                                lContent[iRowCount][10] = iContact.Value;
                                break;
                            case ContactType.private_Fax:
                                lContent[iRowCount][11] = iContact.Value;
                                break;
                        }
                    }

                    lContent[iRowCount][12] = lPersons[iRowCount].Notice;
                }

                return WriteHTMLFile(lHeaderCaption, lContent);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string PrepareExcelFileSupportConceptExport(string pFileID, long[] pSortedOids)
        {
            try
            {
                string lPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, pFileID + ".tmp");

                var lSupportConcepts = DAOFactory.GenericDAO.LoadByIDs<SupportConcept>(pSortedOids);

				
				string[] lHeaderCaption = {
                                              "Nachname", // 0
											  "Vorname", // 1
                                              "Kommentar", // 2
                                              "Hilfeplankonferenz", // 3
                                              "Kostenträger", // 4
                                              "Aktenzeichen", // 5
                                              "beantragt von", // 6
                                              "beantragt bis", // 7
                                              "bewilligt von", // 8
                                              "bewilligt bis", // 9
											  "Verlängerung beantragt am", // 10
                                              "gen. FLS/Woche", // 11
                                              "gen. FLS Gesamt", // 12
                                              "Stundensatz", // 13
                                              "Kostenträger Notiz", // 14
											  "BetreuerIn", // 15
											  "Betreuung beendet am" // 16
                                          };

                List<string[]> lContent = new List<string[]>();

                int lContentIndex = 0;

                for (int iRowCount = 0; iRowCount < lSupportConcepts.Count; iRowCount++)
                {
                    lContent.Add(new string[lHeaderCaption.Count()]);
	                lContent[lContentIndex][0] = lSupportConcepts[iRowCount].Customer.Person.LastName;
					lContent[lContentIndex][1] = lSupportConcepts[iRowCount].Customer.Person.FirstName;

                    lContent[lContentIndex][2] = lSupportConcepts[iRowCount].Notice;
					
                    lContent[lContentIndex][3] = lSupportConcepts[iRowCount].ConferenceDate != null
                                                     ? lSupportConcepts[iRowCount].ConferenceDate.Value.ToShortDateString()
                                                     : string.Empty;
					lContent[lContentIndex][10] = lSupportConcepts[iRowCount].RenewalSendDate != null
													 ? lSupportConcepts[iRowCount].RenewalSendDate.Value.ToShortDateString()
													 : string.Empty;

                    int cbCount = 0;
                    foreach (var iCostBearer in lSupportConcepts[iRowCount].CostBearer2SupportConceptList)
                    {
                        if (cbCount++ > 0)
                        {
                            lContent.Add(new string[lHeaderCaption.Count()]);
                            lContentIndex++;
                        }
                        if (iCostBearer.CostBearer != null && iCostBearer.CostBearer.Organisation != null)
                        {
                            lContent[lContentIndex][4] = iCostBearer.CostBearer.Organisation.Name;

							var calc = PluginLoader.FindClass<Calculations>(iCostBearer.CostBearer.ID) ?? Calculations.GetInstance(iCostBearer.CostBearer.ID);
                            SupportConceptCostBearerRelDC relDC = MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(iCostBearer);

                            DateTime dt = DateTime.Now;
                            DateTime end = DateTime.MaxValue;
                            if (iCostBearer.ApprovedEndDate.HasValue)
                                end = iCostBearer.ApprovedEndDate.Value;
                            else if (iCostBearer.RequestedEndDate.HasValue)
                                end = iCostBearer.RequestedEndDate.Value;
                            if (dt > end)
                                dt = end;
							if (relDC.ApprovalPeriodList.Count == 1)
							{
								var ap = relDC.ApprovalPeriodList[0];
								if (ap.ApprovedBEPerInterval.HasValue && ap.ApprovedBEInterval.HasValue && ap.ApprovedBEInterval.Value == SupportConceptApprovalInterval.Weekly)
								{
									var serviceUnit = relDC.CostBearer.CostRatePeriods.GetCostRatePeriodForDate(CostRatePeriodType.MinutesPerServiceUnit, DateTime.Now);
									if (serviceUnit != null)
										lContent[lContentIndex][11] = String.Format("{0:0.##}", serviceUnit.GetBEInHours(ap.ApprovedBEPerInterval));
								}
							} 
							else
							{
								lContent[lContentIndex][11] = String.Format("{0:0.##}", calc.GetApprovedHoursPerWeek(relDC, dt, false)); // iCostBearer.ApprovedFLS.ToStringNullCheck();	
							}
                            
                            lContent[lContentIndex][12] = String.Format("{0:0.##}", calc.GetApprovedHoursTotal(relDC, false)); //iCostBearer.ApprovedFLSTotal.ToStringNullCheck();
                        }
                        else
                        {
                            lContent[lContentIndex][4] = string.Empty;
                        }

                        lContent[lContentIndex][5] = iCostBearer.CustomerReferenceNumber;
                        lContent[lContentIndex][6] = iCostBearer.RequestedStartDate.DoIfNotNull(d => d.ToShortDateString());
                        lContent[lContentIndex][7] = iCostBearer.RequestedEndDate.DoIfNotNull(d => d.ToShortDateString());
                        lContent[lContentIndex][8] = iCostBearer.ApprovedStartDate.DoIfNotNull(d => d.ToShortDateString());
                        lContent[lContentIndex][9] = iCostBearer.ApprovedEndDate.DoIfNotNull(d => d.ToShortDateString());
						
                        if (iCostBearer.CostBearer != null)
                        {
                            lContent[lContentIndex][13] = iCostBearer.CostBearer.CostRatePeriods.MapToNewDCs()
                                .GetCurrentlyValidRateValue(CostRatePeriodType.HourlyRate).ToStringNullCheck();
                        }

                        lContent[lContentIndex][14] = iCostBearer.Notice;

	                    String mainAttendant = "";
						foreach (Employee2Customer e2c in lSupportConcepts[iRowCount].Customer.Employee2CustomerList)
						{
							foreach (ValueListEntry2Object vle2o in e2c.ValueList)
							{
								ValueListEntry vle = vle2o.Entry;
								if (vle.SystemEntryID != null && vle.SystemEntryID.Value == SystemEntryID.EmployeeRoleMainAttendant)
								{
									string empName = e2c.Employee.Person.FirstName + " " + e2c.Employee.Person.LastName;
									if (String.IsNullOrEmpty(mainAttendant))
										mainAttendant = empName;
									else
									{
										if (!mainAttendant.Contains(empName))
										{
											mainAttendant += ", " + empName;
										}
									}
								}
							}
						}



						lContent[lContentIndex][15] = mainAttendant;

	                    if (lSupportConcepts[iRowCount].Customer.TerminationDate.HasValue)
	                    {
							lContent[lContentIndex][16] = String.Format("{0:dd.MM.yyyy}", lSupportConcepts[iRowCount].Customer.TerminationDate);
	                    }
	                    else
	                    {
		                    lContent[lContentIndex][16] = "";
	                    }
                    }

                    // if (iRowCount < lSupportConcepts.Count - 1)
                    // {
                    // //next Row
                    // lContentIndex++; lContent.Add(new string[lHeaderCaption.Count()]);

                    // }
                    lContentIndex++;
                }

                return WriteHTMLFile(lHeaderCaption, lContent.ToArray());
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string PrepareExcelFileTeamExport(string pFileID, long[] pSortedOids)
        {
            try
            {
                string lPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, pFileID + ".tmp");

                var lTeams = DAOFactory.GenericDAO.LoadByIDs<Team>(pSortedOids);

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

                string[][] lContent = new string[lTeams.Max(t => t.MemberList.Count)][];

                for (int i = 0; i < lTeams.Max(t => t.MemberList.Count); i++)
                {
                    lContent[i] = new string[lTeams.Count * 2];
                }

                int iColumnCount = 0;
                foreach (var iTeam in lTeams)
                {
                    lHeaderCaption.AddRange(new[]
                                            {
                                                iTeam.Name + " (Leitung: " + iTeam.Leader.Person + ")", string.Empty
                                            });

                    int lRowCount = 0;
                    foreach (var iMember in iTeam.MemberList)
                    {
                        lContent[lRowCount++][iColumnCount] = iMember.Person.ToString();
                    }

                    iColumnCount += 2;
                }

                return WriteHTMLFile(lHeaderCaption.ToArray(), lContent);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string PrepareExcelFileUserExport(string pFileID, long[] pSortedOids)
        {
            try
            {
                string lPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, pFileID + ".tmp");

                var lUser = DAOFactory.GenericDAO.LoadByIDs<ApplicationUser>(pSortedOids);

                string[] lHeaderCaption = {
                                              "Mitarbeiter", "Login", "zugeordnete Benutzergruppen"
                                          };
                string[][] lContent = new string[lUser.Count][];

                for (int iRowCount = 0; iRowCount < lUser.Count; iRowCount++)
                {
                    lContent[iRowCount] = new string[3];

                    lContent[iRowCount][0] = lUser[iRowCount].Employee.Person.ToString();
                    lContent[iRowCount][1] = lUser[iRowCount].LoginName;
                    lContent[iRowCount][2] = string.Join(", ", lUser[iRowCount].UserGroups.Select(ug => ug.Name).ToArray());
                }

                return WriteHTMLFile(lHeaderCaption, lContent);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string PrepareExcelFileUserGroupExport(string pFileID, long[] pSortedOids)
        {
            try
            {
                var lUserGroups = DAOFactory.GenericDAO.LoadByIDs<UserGroup>(pSortedOids);

                string[] lHeaderCaption = {
                                              "Name", "Beschreibung", "zugeordnete Rechte"
                                          };
                string[][] lContent = new string[lUserGroups.Count][];

                for (int iRowCount = 0; iRowCount < lUserGroups.Count; iRowCount++)
                {
                    lContent[iRowCount] = new string[3];

                    lContent[iRowCount][0] = lUserGroups[iRowCount].Name;
                    lContent[iRowCount][1] = lUserGroups[iRowCount].Description;
                    lContent[iRowCount][2] = string.Join(", ", lUserGroups[iRowCount].Rights.Select(r => BS.Shared.Core.Utils.EnumName(r.RightType)).ToArray());
                }

                return WriteHTMLFile(lHeaderCaption, lContent);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public RssFeed ReadRssFeed(string url)
        {
            try
            {
	            if (string.IsNullOrEmpty(url))
	            {
					url = ConfigurationManager.AppSettings.Get("RssFeedUrl");

	            }
				if (string.IsNullOrEmpty(url))
				{
					url = "http://bsnewsmaster.beyondsoft.de/news_rss.php?ClientOID=236180486&CategoryOID=2002858128";

				}
                RssFeed feed = new RssFeed();

                RssManager mgr = new RssManager(url);
                feed.Items = mgr.GetFeed();
                feed.Title = mgr.FeedTitle;
                feed.Description = mgr.FeedDescription;

                return feed;
            }
            catch (Exception)
            {
                // throw(BeWo.Service.Core.Utils.ThrowBeWoFaultException(e));
                return null;
            }
        }

        private void WriteExcelFile(string pFileID, string[] pHeaderCaption, string[][] pContent, string pPath = "")
        {
            using (var uFileStream = File.Create(pPath))
                using (var uSw = new StreamWriter(uFileStream))
                    uSw.Write(new ExcelDownload(pHeaderCaption, pContent).CreateExcelOutputString());
        }

        private string WriteHTMLFile(string[] pHeaderCaption, string[][] pContent)
        {
            return new ExcelDownload(pHeaderCaption, pContent).CreateExcelOutputString();
        }

        public string CreateTemporaryToken(string link, bool noExpiration)
        {
            string token = SecurityUtils.CreateToken(noExpiration);
            var slicedToken = SecurityUtils.sliceToken(token, link);

            var isPermaLink = Boolean.Parse(slicedToken["ispermalink"].ToString());

            var lUser = new ApplicationUser();
            if (slicedToken.ContainsKey("user"))
                lUser = DAOFactory.UserDAO.FindUserByLoginName(slicedToken["user"].ToString());

            var tt = new TemporaryToken
            {
                EmployeeOid = lUser.Employee.Oid,
                EncodedToken = token,
                ExpirationDate = DateTime.Parse(slicedToken["expdate"].ToString()),
                RequestedLink = link,
                IsPermaLink = isPermaLink,
                CreatorIP = Utils.GetClientIP()
            };

            try
            {
                DAOFactory.GenericDAO.Insert(tt);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }

            return token;
        }

        public FileAttachmentDC GetFileAttachment(long oid)
        {
            var lFA = DAOFactory.GenericDAO.LoadByID<FileAttachment>(oid);
            var dc = MapperFactory.FileAttachmentDC_FileAttachment.MapToNewDC(lFA);

            dc.BinaryData = lFA.Data;
            dc.URL = lFA.Path;
            return dc;
        }
    }
}