package yuku.kpriviewer.fr;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import yuku.afw.V;
import yuku.alkitab.base.fr.base.BaseFragment;
import yuku.alkitab.debug.R;
import yuku.kpri.model.Lyric;
import yuku.kpri.model.Song;
import yuku.kpri.model.Verse;
import yuku.kpri.model.VerseKind;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
public class SongFragment extends BaseFragment {
public static final String TAG = SongFragment.class.getSimpleName();
private static final String ARG_song = "song";
private static final String ARG_templateFile = "templateFile";
private static final String ARG_customVars = "customVars";
private WebView webview;
private Song song;
private String templateFile;
private Bundle customVars;
public interface ShouldOverrideUrlLoadingHandler {
boolean shouldOverrideUrlLoading(WebViewClient client, WebView view, String url);
}
public static SongFragment create(Song song, String templateFile, Bundle optionalCustomVars) {
SongFragment res = new SongFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_song, song);
args.putString(ARG_templateFile, templateFile);
if (optionalCustomVars != null) args.putBundle(ARG_customVars, optionalCustomVars);
res.setArguments(args);
return res;
}
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
song = getArguments().getParcelable(ARG_song);
templateFile = getArguments().getString(ARG_templateFile);
customVars = getArguments().getBundle(ARG_customVars);
}
@SuppressLint("SetJavaScriptEnabled")
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View res = inflater.inflate(R.layout.fragment_song, container, false);
webview = V.get(res, R.id.webview);
webview.setBackgroundColor(0x00000000);
webview.setWebViewClient(webViewClient);
final WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(false);
// prevent user system-wide display settings (sp scaling) from changing the actual text size inside webview.
settings.setTextZoom(100);
return res;
}
@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
renderLagu(song);
}
final WebViewClient webViewClient = new WebViewClient() {
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
Activity activity = getActivity();
if (activity instanceof ShouldOverrideUrlLoadingHandler && ((ShouldOverrideUrlLoadingHandler)activity).shouldOverrideUrlLoading(this, view, url)) {
return true;
} else {
return super.shouldOverrideUrlLoading(view, url);
}
}
boolean pendingResize = false;
@Override
public void onScaleChanged(final WebView view, final float oldScale, final float newScale) {
super.onScaleChanged(view, oldScale, newScale);
// "restore" auto text-wrapping behavior from before KitKat
if (pendingResize) return;
pendingResize = true;
view.postDelayed(() -> {
view.evaluateJavascript("document.getElementsByTagName('body')[0].style.width = window.innerWidth + 'px';", null);
pendingResize = false;
}, 100);
}
};
private void renderLagu(Song song) {
try {
InputStream is = getResources().getAssets().open(templateFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
while (true) {
int read = is.read(buf);
if (read < 0) break;
baos.write(buf, 0, read);
}
String template = new String(baos.toByteArray(), "utf-8");
if (customVars != null) {
for (String key: customVars.keySet()) {
template = templateVarReplace(template, key, customVars.get(key));
}
}
template = templateDivReplace(template, "code", song.code);
template = templateDivReplace(template, "title", song.title);
template = templateDivReplace(template, "title_original", song.title_original);
template = templateDivReplace(template, "tune", song.tune);
template = templateDivReplace(template, "keySignature", song.keySignature);
template = templateDivReplace(template, "timeSignature", song.timeSignature);
template = templateDivReplace(template, "authors_lyric", song.authors_lyric);
template = templateDivReplace(template, "authors_music", song.authors_music);
template = templateDivReplace(template, "lyrics", songToHtml(song, false));
webview.loadDataWithBaseURL("file:///android_asset/" + templateFile, template, "text/html", "utf-8", null);
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
webview.loadDataWithBaseURL(null, sw.toString(), "text/plain", "utf-8", null);
}
}
public static String songToHtml(final Song song, final boolean forPatchText) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < song.lyrics.size(); i++) {
Lyric lyric = song.lyrics.get(i);
sb.append("<div class='lyric'>");
if (song.lyrics.size() > 1 || lyric.caption != null) { // otherwise, only lyric and has no name
if (lyric.caption != null) {
sb.append("<div class='lyric_caption'>").append(lyric.caption).append("</div>");
} else {
sb.append("<div class='lyric_caption'>Versi ").append(i + 1).append("</div>");
}
}
int bait_normal_no = 0;
int bait_reff_no = 0;
for (Verse verse: lyric.verses) {
sb.append("<div class='verse" + (verse.kind == VerseKind.REFRAIN? " refrain": "") + "'>");
{
if (verse.kind == VerseKind.REFRAIN) {
bait_reff_no++;
} else {
bait_normal_no++;
}
if (forPatchText) {
sb.append(verse.kind == VerseKind.REFRAIN ? ("reff " + bait_reff_no) : bait_normal_no);
} else {
sb.append("<div class='verse_ordering'>" + (verse.kind == VerseKind.REFRAIN? bait_reff_no: bait_normal_no) + "</div>");
}
sb.append("<div class='verse_content'>");
for (String line : verse.lines) {
if (forPatchText) {
sb.append(line).append("<br/>");
} else {
sb.append("<p class='line'>").append(line).append("</p>");
}
}
sb.append("</div>");
}
sb.append("</div>");
}
sb.append("</div>");
}
return sb.toString();
}
private String templateDivReplace(String template, String name, String value) {
return template.replace("{{div:" + name + "}}", value == null ? "" : ("<div class='" + name + "'>" + value + "</div>"));
}
private String templateDivReplace(String template, String name, List<String> value) {
return templateDivReplace(template, name, value == null ? null : TextUtils.join("; ", value.toArray(new String[value.size()])));
}
private String templateVarReplace(String template, String name, Object value) {
return template.replace("{{$" + name + "}}", value == null ? "" : value.toString());
}
public int getWebViewTextZoom() {
if (webview == null) return 0; // not ready
return webview.getSettings().getTextZoom();
}
public void setWebViewTextZoom(final int percent) {
if (webview == null) return;
webview.getSettings().setTextZoom(percent);
}
}