/*
 * 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.taobao.weex.utils;

import android.content.Intent;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.net.Uri;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;

import com.taobao.weex.WXEnvironment;
import com.taobao.weex.WXSDKManager;
import com.taobao.weex.adapter.IWXHttpAdapter;
import com.taobao.weex.common.WXRequest;
import com.taobao.weex.common.WXResponse;
import com.taobao.weex.dom.WXStyle;

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

/**
 * Created by sospartan on 7/13/16.
 */
public class TypefaceUtil {
  public static final String FONT_CACHE_DIR_NAME = "font-family";
  private final static String TAG = "TypefaceUtil";
  private final static Map<String, FontDO> sCacheMap = new HashMap<>(); //Key: fontFamilyName

  public static final String ACTION_TYPE_FACE_AVAILABLE = "type_face_available";

  public static void putFontDO(FontDO fontDO) {
    if (fontDO != null && !TextUtils.isEmpty(fontDO.getFontFamilyName())) {
      sCacheMap.put(fontDO.getFontFamilyName(), fontDO);
    }
  }

  public static FontDO getFontDO(String fontFamilyName) {
    return sCacheMap.get(fontFamilyName);
  }

  public static void applyFontStyle(Paint paint, int style, int weight, String family) {
    int oldStyle;
    Typeface typeface = paint.getTypeface();
    if (typeface == null) {
      oldStyle = 0;
    } else {
      oldStyle = typeface.getStyle();
    }

    int want = 0;
    if ((weight == Typeface.BOLD)
      || ((oldStyle & Typeface.BOLD) != 0 && weight == WXStyle.UNSET)) {
      want |= Typeface.BOLD;
    }

    if ((style == Typeface.ITALIC)
      || ((oldStyle & Typeface.ITALIC) != 0 && style == WXStyle.UNSET)) {
      want |= Typeface.ITALIC;
    }

    if (family != null) {
      typeface = getOrCreateTypeface(family, want);
    }

    if (typeface != null) {
      paint.setTypeface(Typeface.create(typeface, want));
    } else {
      paint.setTypeface(Typeface.defaultFromStyle(want));
    }
  }

  public static Typeface getOrCreateTypeface(String family, int style) {
    FontDO fontDo = sCacheMap.get(family);
    if (fontDo != null && fontDo.getTypeface() != null) {
      return fontDo.getTypeface();
    }

    return Typeface.create(family, style);
  }

  private static void loadFromAsset(FontDO fontDo,String path){
    try {
      Typeface typeface = Typeface.createFromAsset(WXEnvironment.getApplication().getAssets(), path);
      if (typeface != null) {
        if(WXEnvironment.isApkDebugable()) {
          WXLogUtils.d(TAG, "load asset file success");
        }
        fontDo.setState(FontDO.STATE_SUCCESS);
        fontDo.setTypeface(typeface);
      } else {
        WXLogUtils.e(TAG, "Font asset file not found " + fontDo.getUrl());
      }
    } catch (Exception e) {
      WXLogUtils.e(TAG, e.toString());
    }
  }

  public static void loadTypeface(final FontDO fontDo) {
    if (fontDo != null && fontDo.getTypeface() == null &&
            (fontDo.getState() == FontDO.STATE_FAILED || fontDo.getState() == FontDO.STATE_INIT)) {
      fontDo.setState(FontDO.STATE_LOADING);
      if (fontDo.getType() == FontDO.TYPE_LOCAL) {
        Uri uri = Uri.parse(fontDo.getUrl());
        loadFromAsset(fontDo,uri.getPath().substring(1));//exclude slash
      } else if (fontDo.getType() == FontDO.TYPE_NETWORK) {
        final String url = fontDo.getUrl();
        final String fontFamily = fontDo.getFontFamilyName();
        final String fileName = url.replace('/', '_').replace(':', '_');
        File dir = new File(getFontCacheDir());
        if(!dir.exists()){
          dir.mkdirs();
        }
        final String fullPath =  dir.getAbsolutePath()+ File.separator +fileName;
        if (!loadLocalFontFile(fullPath, fontFamily)) {
          downloadFontByNetwork(url, fullPath, fontFamily);
        }
      } else if (fontDo.getType() == FontDO.TYPE_FILE) {
        boolean result = loadLocalFontFile(fontDo.getUrl(), fontDo.getFontFamilyName());
        if (!result) {
          fontDo.setState(FontDO.STATE_FAILED);
        }
      }
    }
  }

  private static void downloadFontByNetwork(final String url, final String fullPath, final String fontFamily) {
    IWXHttpAdapter adapter = WXSDKManager.getInstance().getIWXHttpAdapter();
    if (adapter == null) {
      WXLogUtils.e(TAG, "downloadFontByNetwork() IWXHttpAdapter == null");
      return;
    }
    WXRequest request = new WXRequest();
    request.url = url;
    request.method = "GET";
    adapter.sendRequest(request, new IWXHttpAdapter.OnHttpListener() {
      @Override
      public void onHttpStart() {
        if(WXEnvironment.isApkDebugable()) {
          WXLogUtils.d(TAG, "downloadFontByNetwork begin url:" + url);
        }
      }

      @Override
      public void onHeadersReceived(int statusCode, Map<String, List<String>> headers) {

      }

      @Override
      public void onHttpUploadProgress(int uploadProgress) {

      }

      @Override
      public void onHttpResponseProgress(int loadedLength) {

      }

      @Override
      public void onHttpFinish(WXResponse response) {
        int statusCode = 0;
        if (!TextUtils.isEmpty(response.statusCode)) {
          try {
            statusCode = Integer.parseInt(response.statusCode);
          } catch (NumberFormatException e) {
            statusCode = 0;
            WXLogUtils.e(TAG, "IWXHttpAdapter onHttpFinish statusCode:" + response.statusCode);
          }
        }
        boolean result;
        if (statusCode >= 200 && statusCode <= 299 && response.originalData != null) {
          result = WXFileUtils.saveFile(fullPath, response.originalData, WXEnvironment.getApplication());
          if (result) {
            result = loadLocalFontFile(fullPath, fontFamily);
          } else {
            if(WXEnvironment.isApkDebugable()) {
              WXLogUtils.d(TAG, "downloadFontByNetwork() onHttpFinish success, but save file failed.");
            }
          }
        } else {
          result = false;
        }

        if (!result) {
          FontDO fontDO = sCacheMap.get(fontFamily);
          if (fontDO != null) {
            fontDO.setState(FontDO.STATE_FAILED);
          }
        }
      }
    });
  }

  private static boolean loadLocalFontFile(String path, String fontFamily) {
    if (TextUtils.isEmpty(path) || TextUtils.isEmpty(fontFamily)) {
      return false;
    }
    try {
      File file = new File(path);
      if (!file.exists()) {
        return false;
      }
      Typeface typeface = Typeface.createFromFile(path);
      if (typeface != null) {
        FontDO fontDo = sCacheMap.get(fontFamily);
        if (fontDo != null) {
          fontDo.setState(FontDO.STATE_SUCCESS);
          fontDo.setTypeface(typeface);
          if(WXEnvironment.isApkDebugable()) {
            WXLogUtils.d(TAG, "load local font file success");
          }

          Intent intent = new Intent(ACTION_TYPE_FACE_AVAILABLE);
          intent.putExtra("fontFamily", fontFamily);
          LocalBroadcastManager.getInstance(WXEnvironment.getApplication()).sendBroadcast(intent);
          return true;
        }
      } else {
        WXLogUtils.e(TAG, "load local font file failed, can't create font.");
      }
    } catch (Exception e) {
      WXLogUtils.e(TAG, e.toString());
    }
    return false;
  }

  private static String getFontCacheDir() {
    return WXEnvironment.getDiskCacheDir(WXEnvironment.getApplication()) + "/" + FONT_CACHE_DIR_NAME;
  }
}
