/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

package com.facebook.react.modules.deviceinfo;

import javax.annotation.Nullable;

import java.util.HashMap;
import java.util.Map;

import android.util.DisplayMetrics;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.uimanager.DisplayMetricsHolder;

/**
 * Module that exposes Android Constants to JS.
 */
@ReactModule(name = "DeviceInfo")
public class DeviceInfoModule extends ReactContextBaseJavaModule implements
    LifecycleEventListener {

  private float mFontScale;

  public DeviceInfoModule(
      ReactApplicationContext reactContext) {
    super(reactContext);

    mFontScale = getReactApplicationContext().getResources().getConfiguration().fontScale;
  }

  @Override
  public String getName() {
    return "DeviceInfo";
  }

  @Override
  public @Nullable Map<String, Object> getConstants() {
    HashMap<String, Object> constants = new HashMap<>();
    constants.put(
        "Dimensions",
        getDimensionsConstants());
    return constants;
  }

  @Override
  public void onHostResume() {
    float fontScale = getReactApplicationContext().getResources().getConfiguration().fontScale;
    if (mFontScale != fontScale) {
      mFontScale = fontScale;
      emitUpdateDimensionsEvent();
    }
  }

  @Override
  public void onHostPause() {
  }

  @Override
  public void onHostDestroy() {
  }

  public void emitUpdateDimensionsEvent() {
    getReactApplicationContext()
        .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
        .emit("didUpdateDimensions", getDimensionsConstants());
  }

  private WritableMap getDimensionsConstants() {
    DisplayMetrics windowDisplayMetrics = DisplayMetricsHolder.getWindowDisplayMetrics();
    DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();

    WritableMap windowDisplayMetricsMap = Arguments.createMap();
    windowDisplayMetricsMap.putInt("width", windowDisplayMetrics.widthPixels);
    windowDisplayMetricsMap.putInt("height", windowDisplayMetrics.heightPixels);
    windowDisplayMetricsMap.putDouble("scale", windowDisplayMetrics.density);
    windowDisplayMetricsMap.putDouble("fontScale", mFontScale);
    windowDisplayMetricsMap.putDouble("densityDpi", windowDisplayMetrics.densityDpi);

    WritableMap screenDisplayMetricsMap = Arguments.createMap();
    screenDisplayMetricsMap.putInt("width", screenDisplayMetrics.widthPixels);
    screenDisplayMetricsMap.putInt("height", screenDisplayMetrics.heightPixels);
    screenDisplayMetricsMap.putDouble("scale", screenDisplayMetrics.density);
    screenDisplayMetricsMap.putDouble("fontScale", mFontScale);
    screenDisplayMetricsMap.putDouble("densityDpi", screenDisplayMetrics.densityDpi);

    WritableMap dimensionsMap = Arguments.createMap();
    dimensionsMap.putMap("windowPhysicalPixels", windowDisplayMetricsMap);
    dimensionsMap.putMap("screenPhysicalPixels", screenDisplayMetricsMap);

    return dimensionsMap;
  }
}

@@ -435,16 +435,48 @@
 l.Map;%0A%0A
+import android.content.Context;%0A
 import a
@@ -548,16 +548,65 @@
 uments;%0A
+import com.facebook.react.bridge.BaseJavaModule;%0A
 import c
@@ -716,69 +716,8 @@
 xt;%0A
-import com.facebook.react.bridge.ReactContextBaseJavaModule;%0A
 impo
@@ -1072,20 +1072,8 @@
 nds 
-ReactContext
 Base
@@ -1124,16 +1124,86 @@
 ener %7B%0A%0A
+  private @Nullable ReactApplicationContext mReactApplicationContext;%0A
   privat
@@ -1249,23 +1249,16 @@
 oModule(
-%0A      
 ReactApp
@@ -1297,14 +1297,23 @@
     
-super(
+this((Context) 
 reac
@@ -1327,54 +1327,234 @@
 t);%0A
-%0A
     m
-FontScale = getReactApplicationContext()
+ReactApplicationContext = reactContext;%0A  %7D%0A%0A  public DeviceInfoModule(Context context) %7B%0A    mReactApplicationContext = null;%0A    DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(context);%0A    mFontScale = context
 .get
@@ -1937,24 +1937,89 @@
 tResume() %7B%0A
+    if (mReactApplicationContext == null) %7B%0A      return;%0A    %7D%0A%0A
     float fo
@@ -2028,19 +2028,17 @@
 Scale = 
-get
+m
 ReactApp
@@ -2052,18 +2052,16 @@
 nContext
-()
 .getReso
@@ -2353,19 +2353,82 @@
 ) %7B%0A    
-get
+if (mReactApplicationContext == null) %7B%0A      return;%0A    %7D%0A%0A    m
 ReactApp
@@ -2442,18 +2442,16 @@
 nContext
-()
 %0A       

Allow DeviceInfoModule to be instantiated with only an android Context