/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 * <p/>
 * 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.statusbar;

import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.support.v4.view.ViewCompat;
import android.view.View;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.UiThreadUtil;

public class StatusBarModule extends ReactContextBaseJavaModule {

  private static final String ERROR_NO_ACTIVITY =
    "Tried to change the status bar while not attached to an Activity";

  private int mWindowFlags = 0;

  public StatusBarModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }

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

  @ReactMethod
  public void setColor(final int color, final boolean animated, final Promise res) {
    final Activity activity = getCurrentActivity();
    if (activity == null) {
      res.reject(ERROR_NO_ACTIVITY);
      return;
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      UiThreadUtil.runOnUiThread(
        new Runnable() {
          @TargetApi(Build.VERSION_CODES.LOLLIPOP)
          @Override
          public void run() {
            if (animated) {
              int curColor = activity.getWindow().getStatusBarColor();
              ValueAnimator colorAnimation = ValueAnimator.ofObject(
                new ArgbEvaluator(), curColor, color);

              colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animator) {
                  activity.getWindow().setStatusBarColor((Integer) animator.getAnimatedValue());
                }
              });
              colorAnimation
                .setDuration(300)
                .setStartDelay(0);
              colorAnimation.start();
            } else {
              activity.getWindow().setStatusBarColor(color);
            }
            res.resolve(null);
          }
        }
      );
    } else {
      res.resolve(null);
    }
  }

  @ReactMethod
  public void setTranslucent(final boolean translucent, final Promise res) {
    final Activity activity = getCurrentActivity();
    if (activity == null) {
      res.reject(ERROR_NO_ACTIVITY);
      return;
    }
    UiThreadUtil.runOnUiThread(
      new Runnable() {
        @Override
        public void run() {
          if (translucent) {
            mWindowFlags |=
              View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
          } else {
            mWindowFlags &=
              ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
          }
          activity.getWindow().getDecorView().setSystemUiVisibility(mWindowFlags);
          ViewCompat.requestApplyInsets(activity.getWindow().getDecorView());
          res.resolve(null);
        }
      }
    );
  }

  @ReactMethod
  public void setHidden(final boolean hidden, final Promise res) {
    final Activity activity = getCurrentActivity();
    if (activity == null) {
      res.reject(ERROR_NO_ACTIVITY);
      return;
    }
    UiThreadUtil.runOnUiThread(
      new Runnable() {
        @Override
        public void run() {
          if (hidden) {
            mWindowFlags |= View.SYSTEM_UI_FLAG_FULLSCREEN;
          } else {
            mWindowFlags &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
          }
          activity.getWindow().getDecorView().setSystemUiVisibility(mWindowFlags);
          res.resolve(null);
        }
      }
    );
  }
}

@@ -595,16 +595,51 @@
 ew.View;
+%0Aimport android.view.WindowManager;
 %0A%0Aimport
@@ -1003,16 +1003,91 @@
 TIVITY =
+ %22E_NO_ACTIVITY%22;%0A  private static final String ERROR_NO_ACTIVITY_MESSAGE =
 %0A    %22Tr
@@ -1156,41 +1156,8 @@
 %22;%0A%0A
-  private int mWindowFlags = 0;%0A%0A
   pu
@@ -1529,32 +1529,59 @@
 RROR_NO_ACTIVITY
+, ERROR_NO_ACTIVITY_MESSAGE
 );%0A      return;
@@ -2901,32 +2901,59 @@
 RROR_NO_ACTIVITY
+, ERROR_NO_ACTIVITY_MESSAGE
 );%0A      return;
@@ -3075,53 +3075,108 @@
    i
-f (translucent) %7B%0A            mWindowFlags %7C=
+nt flags = activity.getWindow().getDecorView().getSystemUiVisibility();%0A          if (translucent) %7B
 %0A   
@@ -3180,25 +3180,32 @@
             
- 
+flags %7C=
  View.SYSTEM
@@ -3303,37 +3303,16 @@
     
-mWindowFlags &=%0A             
+flags &=
  ~(V
@@ -3462,32 +3462,25 @@
 iVisibility(
-mWindowF
+f
 lags);%0A     
@@ -3807,16 +3807,43 @@
 ACTIVITY
+, ERROR_NO_ACTIVITY_MESSAGE
 );%0A     
@@ -3998,43 +3998,168 @@
     
-mWindowFlags %7C= View.SYSTEM_UI_FLAG
+activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);%0A            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT
 _FUL
@@ -4157,32 +4157,33 @@
 E_NOT_FULLSCREEN
+)
 ;%0A          %7D el
@@ -4203,44 +4203,79 @@
     
-mWindowFlags &= ~View.SYSTEM_UI_FLAG
+activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT
 _FUL
@@ -4281,30 +4281,21 @@
 LLSCREEN
+)
 ;%0A  
-        %7D%0A
         
@@ -4321,59 +4321,76 @@
 w().
-getDecorView().setSystemUiVisibility(mWindowFlags);
+clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);%0A          %7D%0A
 %0A   

Fix hidden StatusBar reappearing after exiting app on Android