/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.math; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.core.envs.*;
public class Xomath_latex_bldr {
	public static void Async(Xoae_app app, Xoae_page page, gplx.xowa.guis.cbks.js.Xog_js_wkr js_wkr) {
		// get len; if 0, exit
		Gfo_usr_dlg usr_dlg = app.Usr_dlg();
		int len = page.File_math().Count();
		if (len == 0) return;

		usr_dlg.Prog_one("", "", "page.async.math; count=~{0}", len);
		// loop each item
		for (int i = 0; i < len; ++i) {
			// if canceled, exit
			if (usr_dlg.Canceled()) {
				usr_dlg.Prog_none("", "", "");
				app.Log_wtr().Queue_enabled_(false);
				return;
			}

			try {
				// get itm and generate png
				Xomath_latex_itm itm = (Xomath_latex_itm)page.File_math().Get_at(i);
				String queue_msg = usr_dlg.Prog_many("", "", "generating math ~{0} of ~{1}: ~{2}", i + List_adp_.Base1, len, itm.Src());
				Generate_png(app, itm.Src(), itm.Md5(), itm.Png(), queue_msg);

				// get png size; update <img> src; delete <span>
				gplx.gfui.SizeAdp size = app.File_mgr().Img_mgr().Wkr_query_img_size().Exec(itm.Png());
				js_wkr.Html_img_update("xowa_math_img_" + itm.Uid(), itm.Png().To_http_file_str(), size.Width(), size.Height());
				js_wkr.Html_elem_delete("xowa_math_txt_" + itm.Uid());
			}
			catch (Exception e) {
				usr_dlg.Warn_many("", "", "page.async.math: page=~{0} err=~{1}", page.Ttl().Raw(), Err_.Message_gplx_log(e));
			}
		}
		page.File_math().Clear();
	}
	private static void Generate_png(Xoae_app app, byte[] math, byte[] hash, Io_url png_url, String prog_fmt) {
		// init
		Io_url tmp_dir = app.Usere().Fsys_mgr().App_temp_dir().GenSubDir("math");
		Io_url tex_fil = tmp_dir.GenSubFil("xowa_math_temp.tex");

		// make tex_bry
		byte[] tex_doc = Bry_.Replace(math, Bry_.new_a7("\n\n"), Byte_ascii.Nl_bry);	// remove completely blank lines; not sure if this is right; PAGE:en.w:Standard Model_(mathematical_formulation); EX:<math>(\mathbf{1},\mathbf\n\n{1},0)</math>
		tex_doc = fmt__latex_doc.Bld_many_to_bry(Bry_bfr_.New(), tex_doc);
		Io_mgr.Instance.SaveFilBry(tex_fil, tex_doc);

		// run tex to dvi
		Process_adp tex_to_dvi_cmd = app.Prog_mgr().App__tex_to_dvi();
		prog_fmt = String_.Replace(prog_fmt, "~", "~~");	// double-up ~ or else will break in progress bar
		tex_to_dvi_cmd.Prog_fmt_(prog_fmt + " tex_to_dvi: ~{process_seconds} second(s); ~{process_exe_name} ~{process_exe_args}");
		boolean pass = tex_to_dvi_cmd.Run(tex_fil.Raw(), tmp_dir.Xto_api()).Exit_code_pass();
		if (!pass)
			app.Usr_dlg().Warn_many("", "tex_to_dvi.fail", "fail: tex_to_dvi: error=~{0} latex=~{1}", tex_to_dvi_cmd.Rslt_out(), tex_doc);

		// run dvi to png; NOTE: latex sometimes throws errors, but will generate .dvi; for sake of simplicity; always try to run dvipng
		Io_mgr.Instance.CreateDirIfAbsent(png_url.OwnerDir());
		Process_adp dvi_to_png_cmd = app.Prog_mgr().App__dvi_to_png();
		dvi_to_png_cmd.Prog_fmt_(prog_fmt + " dvi_to_png: ~{process_seconds} second(s); ~{process_exe_name} ~{process_exe_args}");
		pass = dvi_to_png_cmd.Run(tex_fil.GenNewExt(".dvi"), png_url, tmp_dir.Xto_api()).Exit_code_pass();
		if (!pass)
			app.Usr_dlg().Warn_many("", "dvi_to_png.fail", "fail: dvi_to_png: error=~{0} latex=~{1}", dvi_to_png_cmd.Rslt_out(), tex_doc);
	}
	private static final    Bry_fmt fmt__latex_doc = Bry_fmt.Auto(Bry_.new_a7(String_.Concat_lines_nl_skip_last
	( "\\documentclass{article}"
	, "\\usepackage{amsmath}"
	, "\\usepackage{amsfonts}"
	, "\\usepackage{amssymb}"
	, "\\usepackage{color}"
	, "\\usepackage[landscape]{geometry}"
	, "\\pagestyle{empty}"
	, "\\begin{document}"
	, "\\begin{Large}"
	, "\\nonumber"
	, "$\\displaystyle"
	, "~{0}"
	, "$\\end{Large}"
	, "\\end{document}"
	)));
}
