package mobi.monaca.framework.nativeui;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import mobi.monaca.framework.InternalSettings;
import mobi.monaca.framework.MonacaApplication;
import mobi.monaca.framework.MonacaPageActivity;
import mobi.monaca.framework.bootloader.LocalFileBootloader;
import mobi.monaca.framework.nativeui.component.Component;
import mobi.monaca.framework.nativeui.component.PageComponent;
import mobi.monaca.framework.util.InputStreamLoader;
import android.content.Context;
import android.content.ContextWrapper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.util.DisplayMetrics;
import android.util.SparseIntArray;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
public class UIContext extends ContextWrapper {
public interface OnRotateListener {
public void onRotate(int orientation);
}
//private static final String TAG = UIContext.class.getSimpleName();
protected String uiFilePath;
protected MonacaPageActivity pageActivity;
protected PageComponent mPageComponent;
protected DisplayMetrics metrics;
protected SparseIntArray computedFontSizeCache = new SparseIntArray();
protected ArrayList<OnRotateListener> onRotateListeners = new ArrayList<OnRotateListener>();
protected InternalSettings settings;
protected Map<String, Component> mComponentIDsMap = new HashMap<String, Component>();
public UIContext(String uiFilePath, MonacaPageActivity pageActivity) {
super(pageActivity);
this.uiFilePath = uiFilePath;
this.pageActivity = pageActivity;
metrics = new DisplayMetrics();
pageActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
MonacaApplication app = (MonacaApplication) pageActivity.getApplication();
this.settings = app.getInternalSettings();
}
public void setPageComponent(PageComponent mPageComponent) {
this.mPageComponent = mPageComponent;
}
public PageComponent getPageComponent() {
return mPageComponent;
}
public Map<String, Component> getComponentIDsMap() {
return mComponentIDsMap;
}
public InternalSettings getSettings() {
return this.settings;
}
public DisplayMetrics getDisplayMetrics() {
return metrics;
}
public MonacaPageActivity getPageActivity() {
return pageActivity;
}
public void showSoftInput(View view) {
((InputMethodManager) pageActivity.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(view, 0);
}
public String getUIFilePath() {
return uiFilePath;
}
public void react(String uri) {
if (uri.startsWith("javascript:")) {
pageActivity.sendJavascript(uri.substring(11));
} else {
pageActivity.pushPageWithIntent(uri, null);
}
}
public void loadRelativePathWithoutUIFile(String relativePath) {
String resolved = resolve(relativePath);
pageActivity.loadUri(resolved, true);
}
public void changeCurrentUri(String uri) {
String resolvedUri = resolve(uri);
pageActivity.setCurrentUri(resolvedUri);
}
public Bitmap readScaledBitmap(String path) throws IOException {
path = resolve(path);
if (path.startsWith("file:///android_asset/")) {
InputStream stream = InputStreamLoader.loadAssetFile(this, path.substring("file:///android_asset/".length()));
Bitmap bitmap = BitmapFactory.decodeStream(stream);
stream.close();
Matrix matrix = new Matrix();
float scale = getDensityScale() * getBitmapScaleFactorFromPath(path);
matrix.postScale(scale, scale);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
} else if (path.startsWith("file:///")) {
InputStream stream = InputStreamLoader.loadLocalFile(path.substring("file://".length()));
Bitmap bitmap = BitmapFactory.decodeStream(stream);
stream.close();
Matrix matrix = new Matrix();
float scale = getDensityScale() * getBitmapScaleFactorFromPath(path);
matrix.postScale(scale, scale);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
return null;
}
protected float getDensityScale() {
DisplayMetrics metrics = new DisplayMetrics();
pageActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
return metrics.density;
}
protected float getBitmapScaleFactorFromPath(String path) {
if (path.endsWith("@2x.png") || path.endsWith("@2x.gif") || path.endsWith("@2x.jpg") || path.endsWith("@2x.jpeg")) {
return 0.5f;
}
return 1.0f;
}
public String resolve(String path) {
try {
path = new URI(uiFilePath).resolve(path).toString();
} catch (Exception e) {
return path;
}
path = path.startsWith("file:/android_asset/") ? "file://" + path.substring("file:".length()) : path;
path = path.startsWith("file:/data") ? "file:///" + path.substring("file:/".length()) : path;
String preferredPath = getPreferredPath(path);
return preferredPath != null && exists(preferredPath) ? preferredPath : path;
}
public static String getPreferredPath(String path) {
if (path.endsWith(".png")) {
return path.substring(0, path.length() - 4) + "@2x.png";
}
if (path.endsWith(".jpg")) {
return path.substring(0, path.length() - 4) + "@2x.jpg";
}
if (path.endsWith(".jpeg")) {
return path.substring(0, path.length() - 5) + "@2x.jpeg";
}
if (path.endsWith(".gif")) {
return path.substring(0, path.length() - 4) + "@2x.gif";
}
return null;
}
protected boolean exists(String resolvedPath) {
if (resolvedPath.startsWith("file:///android_asset/")) {
try {
InputStream stream = LocalFileBootloader.openAsset(pageActivity.getApplicationContext(),
resolvedPath.substring("file:///android_asset/".length()));
stream.close();
return true;
} catch (Exception e) {
}
return false;
} else if (resolvedPath.startsWith("file://")) {
return new File(resolvedPath.substring("file://".length())).exists();
}
throw new RuntimeException("unsupported path: " + resolvedPath);
}
public int getFontSizeFromDip(int dip) {
return UIUtil.getFontSizeFromDip(this, dip);
}
public void addOnRotateListener(OnRotateListener listener) {
onRotateListeners.add(listener);
}
public void fireOnRotateListeners(int orientation) {
for (OnRotateListener listener : onRotateListeners) {
listener.onRotate(orientation);
}
}
public int getUIOrientation() {
return pageActivity.getResources().getConfiguration().orientation;
}
}