/*
 * Copyright (C) 2023 favdb
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package storybook.exim.exporter;

import i18n.I18N;
import storybook.exim.EXIM;
import storybook.model.book.BookParamExport;
import storybook.model.book.BookParamLayout;
import storybook.model.hbn.entity.Chapter;
import storybook.model.hbn.entity.Chapters;
import storybook.model.hbn.entity.Item;
import storybook.model.hbn.entity.Location;
import storybook.model.hbn.entity.Locations;
import storybook.model.hbn.entity.Part;
import storybook.model.hbn.entity.Person;
import storybook.model.hbn.entity.Scene;
import storybook.model.hbn.entity.Scenes;
import storybook.tools.DateUtil;
import storybook.tools.ListUtil;
import storybook.tools.Markdown;
import storybook.tools.StringUtil;
import storybook.tools.html.Html;
import storybook.ui.MainFrame;

/**
 * utilities to export a Part, a Chapter or a Scene to HTML
 *
 * @author favdb
 */
public class ExportToHtml {

	private static final String TT = "ExportToHtml.";

	/**
	 * get the HTML content of a given Part
	 *
	 * @param mainFrame
	 * @param part
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String getPart(MainFrame mainFrame, Part part) {
		StringBuilder b = new StringBuilder();
		b.append(partGetTitle(mainFrame, part));
		for (Chapter chapter : Chapters.find(mainFrame, part)) {
			b.append(getChapter(mainFrame, chapter));
		}
		return b.toString();
	}

	/**
	 * get title of a Part
	 *
	 * @param mainFrame
	 * @param part
	 * @return
	 */
	public static String partGetTitle(MainFrame mainFrame, Part part) {
		//LOG.trace(TT+".getPartTitle("+part.getName()+")");
		String b = "";
		if (mainFrame.getBook().getParam().getParamLayout().getPartTitle()) {
			b = Html.intoH(1, part.getName());
		}
		return b;
	}

	public static String getChapter(MainFrame mainFrame, Chapter chapter) {
		//LOG.trace(TT + "getChapter(mainFrame, chapter=" + LOG.trace(chapter) + ")");
		BookParamLayout layout = mainFrame.getBook().getParam().getParamLayout();
		StringBuilder b = new StringBuilder();
		int lev = 1;
		if (layout.getPartTitle()) {
			lev++;
		}
		if (layout.getChapterTitle()) {
			b.append(titleOf(lev, chapter.getIdent(), getTitle(layout, chapter)));
		}
		b.append(chapterGetDidascalie(mainFrame, chapter));
		b.append(chapterGetDescription(mainFrame, chapter));
		for (Scene scene : Scenes.findBy(mainFrame, chapter)) {
			b.append(getScene(mainFrame, scene));
		}
		return b.toString();
	}

	/**
	 * get the Chapter didascalie (dates and locations)
	 *
	 * @param mainFrame
	 * @param chapter
	 * @return
	 */
	public static String chapterGetDidascalie(MainFrame mainFrame, Chapter chapter) {
		//LOG.trace(TT + ".chapterGetDateLocation(chapter=" + App.traceEntity(chapter) + ")");
		StringBuilder b = new StringBuilder();
		if (mainFrame.getBook().getParam().getParamLayout().getChapterDateLocation()) {
			String date = DateUtil.getNiceDates(Chapters.findDates(mainFrame, chapter));
			String loc = ListUtil.join(Locations.find(mainFrame, chapter), ", ");
			if (!(date + loc).isEmpty()) {
				StringBuilder bx = new StringBuilder();
				if (!date.isEmpty()) {
					bx.append(date);
				}
				if (!loc.isEmpty()) {
					if (!date.isEmpty()) {
						bx.append(" : ");
					}
					bx.append(loc);
				}
				b.append(Html.intoP(Html.intoI(bx.toString()), "margin-right: 3.5cm;"));
			}
		}
		return b.toString();
	}

	/**
	 * get the Chapter description
	 *
	 * @param mainFrame
	 * @param chapter
	 * @return
	 */
	public static String chapterGetDescription(MainFrame mainFrame, Chapter chapter) {
		//LOG.trace(TT + ".chapterGetDescription(mainFrame, chapter=" + LOG.trace(chapter) + ")");
		if (mainFrame.getBook().getParam().getParamLayout().getChapterDescription()
		   && !chapter.getDescription().isEmpty()) {
			return (Html.intoP(Html.intoI(chapter.getDescription()), "margin-left: 3.5cm;text-align: right;"));
		}
		return "";
	}

	/**
	 * get the title of Part, Chapter or Scene
	 *
	 * @param level
	 * @param name
	 * @param text
	 * @return
	 */
	public static String titleOf(int level, String name, String text) {
		if (EXIM.getTitle(text).isEmpty()) {
			return "";
		}
		if (level == 0 || text.isEmpty()) {
			return Html.intoA(name, "", "");
		}
		return "<h" + level + ">"
		   + Html.intoA(name, "", EXIM.getTitle(text))
		   + "</h" + level + ">\n";
	}

	/**
	 * get the Chapter title, if needed, with number
	 *
	 * @param layout
	 * @param chapter
	 * @return
	 */
	public static String getTitle(BookParamLayout layout, Chapter chapter) {
		StringBuilder b = new StringBuilder();
		if (layout.getChapterTitle()) {
			if (layout.getChapterNumber()) {
				if (layout.getChapterRoman()) {
					b.append(StringUtil.intToRoman(chapter.getChapterno())).append(" ");
				} else {
					b.append(chapter.getChapterno().toString()).append(" ");
				}
			}
			b.append(getTitle(chapter.getName()));
		}
		return b.toString();
	}

	public static String getTitle(String title) {
		if (title.contains("@")) {
			String tx[] = title.split("@");
			if (tx.length > 1) {
				return tx[1];
			}
			return "";
		}
		return title;
	}

	/**
	 * get the Scene HTML code
	 *
	 * @param mainFrame
	 * @param scene
	 * @return
	 */
	public static String getScene(MainFrame mainFrame, Scene scene) {
		//LOG.trace(TT + "getScene(mainFrame, scene=" + LOG.trace(scene) + ")");
		BookParamLayout layout = mainFrame.getBook().getParam().getParamLayout();
		StringBuilder b = new StringBuilder();
		if (layout.getSceneTitle() && !getTitle(scene.getName()).isEmpty()) {
			int n = 2;
			if (layout.getPartTitle()) {
				n++;
			}
			if (layout.getChapterTitle()) {
				n++;
			}
			b.append(titleOf(n, scene.getIdent(), getTitle(scene.getName())));
		}
		if (layout.getSceneDidascalie()) {
			b.append(getDidascalie(mainFrame.getBook().getParam().getParamExport(), scene));
		}
		String x = scene.getTextToHtml(false);
		if (mainFrame.getBook().isMarkdown()) {
			Markdown md = new Markdown("ExportBook", "text/plain", "");
			md.setHeader(scene, mainFrame.getBook().info.scenarioGet());
			x = md.getHtmlBody();
		} else {
			x = Html.emTag(x, mainFrame.getBook().getParam().getParamExport().getHighlight());
		}
		x = x.replace("<p align=\"center\">", "<p style=\"text-align:center;\">");
		b.append(x).append("\n");
		return b.toString();
	}

	/**
	 * get the didascalie of a Scene
	 *
	 * @param param
	 * @param scene
	 * @return a String reprenting the HTML code
	 */
	public static String getDidascalie(BookParamExport param, Scene scene) {
		//LOG.trace(TT+"getDidascalie(param, scene="+LOG.trace(scene)+")");
		String rc = "";
		if (param.getLayout().getSceneDidascalie()) {
			if (!scene.getPersons().isEmpty()) {
				rc += "<i>" + Html.intoB(I18N.getMsg("persons")) + " : ";
				for (Person p : scene.getPersons()) {
					rc += p.getFullName() + ", ";
				}
				rc = rc.substring(0, rc.length() - 2);
				rc += "</i>" + Html.BR;
			}
			if (!scene.getLocations().isEmpty()) {
				rc += "<i>" + Html.intoB(I18N.getMsg("locations")) + " : ";
				for (Location p : scene.getLocations()) {
					rc += p.getFullName() + ", ";
				}
				rc = rc.substring(0, rc.length() - 2);
				rc += "</i>" + Html.BR;
			}
			if (!scene.getItems().isEmpty()) {
				rc += "<i>" + Html.intoB(I18N.getMsg("items")) + " : ";
				for (Item p : scene.getItems()) {
					rc += p.getName() + ", ";
				}
				rc = rc.substring(0, rc.length() - 2);
				rc += "</i>" + Html.BR;
			}
			if (!scene.getScenario_pitch().isEmpty()) {
				rc += "<i>" + Html.intoB(I18N.getMsg("scenario.pitch")) + " : ";
				rc += scene.getScenario_pitch();
				rc += "</i>" + Html.BR;
			}
			if (!rc.isEmpty()) {
				rc = Html.intoP(rc, "text-align:right");
			}
		}
		return (rc);
	}

}
