/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package com.alibaba.weex.commons;

import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.weex.commons.util.AssertUtil;
import com.alibaba.weex.commons.util.ScreenUtil;
import com.taobao.weex.IWXRenderListener;
import com.taobao.weex.WXEnvironment;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.common.Constants;
import com.taobao.weex.common.WXRenderStrategy;
import com.taobao.weex.utils.WXUtils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by sospartan on 5/30/16.
 */
public abstract class AbstractWeexActivity extends AppCompatActivity implements IWXRenderListener {
  private static final String TAG = "AbstractWeexActivity";

  private ViewGroup mContainer;
  private WXSDKInstance mInstance;

  protected WXAnalyzerDelegate mWxAnalyzerDelegate;

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    createWeexInstance();
    mInstance.onActivityCreate();

    mWxAnalyzerDelegate = new WXAnalyzerDelegate(this);
    mWxAnalyzerDelegate.onCreate();
    getWindow().setFormat(PixelFormat.TRANSLUCENT);
  }

  protected final void setContainer(ViewGroup container){
    mContainer = container;
  }

  protected final ViewGroup getContainer(){
    return mContainer;
  }

  protected void destoryWeexInstance(){
    if(mInstance != null){
      mInstance.registerRenderListener(null);
      mInstance.destroy();
      mInstance = null;
    }
  }

  protected void createWeexInstance(){
    destoryWeexInstance();

    Rect outRect = new Rect();
    getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect);

    mInstance = new WXSDKInstance(this);
    mInstance.registerRenderListener(this);
  }

  protected void renderPage(String template,String source){
    renderPage(template,source,null);
  }

  protected void renderPage(String template,String source,String jsonInitData){
    AssertUtil.throwIfNull(mContainer,new RuntimeException("Can't render page, container is null"));
    Map<String, Object> options = new HashMap<>();
    options.put(WXSDKInstance.BUNDLE_URL, source);
    // Set options.bundleDigest
    try {
      String banner = WXUtils.getBundleBanner(template);
      JSONObject jsonObj = JSONObject.parseObject(banner);
      String digest = null;
      if (jsonObj != null) {
        digest = jsonObj.getString(Constants.CodeCache.BANNER_DIGEST);
      }
      if (digest != null) {
        options.put(Constants.CodeCache.DIGEST, digest);
      }
    } catch (Throwable t) {}
    //Set options.codeCachePath
    String path = WXEnvironment.getFilesDir(getApplicationContext());
    path += File.separator;
    path += Constants.CodeCache.SAVE_PATH;
    path += File.separator;
    options.put(Constants.CodeCache.PATH, path);

    mInstance.setTrackComponent(true);
    mInstance.render(
      getPageName(),
      template,
      options,
      jsonInitData,
      WXRenderStrategy.APPEND_ASYNC);
  }

  protected void renderPageByURL(String url){
    renderPageByURL(url,null);
  }

  protected void renderPageByURL(String url,String jsonInitData){
    AssertUtil.throwIfNull(mContainer,new RuntimeException("Can't render page, container is null"));
    Map<String, Object> options = new HashMap<>();
    options.put(WXSDKInstance.BUNDLE_URL, url);
    mInstance.setTrackComponent(true);
    mInstance.renderByUrl(
      getPageName(),
      url,
      options,
      jsonInitData,
      WXRenderStrategy.APPEND_ASYNC);
  }

  protected String getPageName(){
    return TAG;
  }

  @Override
  public void onStart() {
    super.onStart();
    if(mInstance!=null){
      mInstance.onActivityStart();
    }
    if(mWxAnalyzerDelegate != null){
      mWxAnalyzerDelegate.onStart();
    }
  }

  @Override
  public void onResume() {
    super.onResume();
    if(mInstance!=null){
      mInstance.onActivityResume();
    }
    if(mWxAnalyzerDelegate != null){
      mWxAnalyzerDelegate.onResume();
    }
  }

  @Override
  public void onPause() {
    super.onPause();
    if(mInstance!=null){
      mInstance.onActivityPause();
    }
    if(mWxAnalyzerDelegate != null){
      mWxAnalyzerDelegate.onPause();
    }
  }

  @Override
  public void onStop() {
    super.onStop();
    if(mInstance!=null){
      mInstance.onActivityStop();
    }
    if(mWxAnalyzerDelegate != null){
      mWxAnalyzerDelegate.onStop();
    }
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    if(mInstance!=null){
      mInstance.onActivityDestroy();
    }
    if(mWxAnalyzerDelegate != null){
      mWxAnalyzerDelegate.onDestroy();
    }
  }

  @Override
  public void onViewCreated(WXSDKInstance wxsdkInstance, View view) {
    View wrappedView = null;
    if(mWxAnalyzerDelegate != null){
      wrappedView = mWxAnalyzerDelegate.onWeexViewCreated(wxsdkInstance,view);
    }
    if(wrappedView != null){
      view = wrappedView;
    }
    if (mContainer != null) {
      mContainer.removeAllViews();
      mContainer.addView(view);
    }
  }



  @Override
  public void onRefreshSuccess(WXSDKInstance wxsdkInstance, int i, int i1) {

  }

  @Override
  @CallSuper
  public void onRenderSuccess(WXSDKInstance instance, int width, int height) {
    if(mWxAnalyzerDelegate  != null){
      mWxAnalyzerDelegate.onWeexRenderSuccess(instance);
    }
  }

  @Override
  @CallSuper
  public void onException(WXSDKInstance instance, String errCode, String msg) {
    if(mWxAnalyzerDelegate != null){
      mWxAnalyzerDelegate.onException(instance,errCode,msg);
    }
  }

  @Override
  @CallSuper
  public boolean onKeyUp(int keyCode, KeyEvent event) {
    return (mWxAnalyzerDelegate != null && mWxAnalyzerDelegate.onKeyUp(keyCode,event)) || super.onKeyUp(keyCode, event);
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (mInstance != null) {
      mInstance.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
  }
}
