package com.usai.redant.util;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.media.MediaMetadataRetriever;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.PermissionChecker;
import android.util.Log;
import android.webkit.MimeTypeMap;

import com.usai.redant.redantmobile.RedAntApplication;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * Created by ray on 27/06/2017.
 */


public class RAUtil {
    public static final int MY_PERMISSIONS_REQUEST= 1;
//    public static void checkPermissions1(Activity activity, String[] permissions)
//    {
//        Log.d("_RAIMAGE", "checkPermissions1:==================================== ");
//        for(String permission : permissions) {
//            boolean bshow=ActivityCompat.shouldShowRequestPermissionRationale(activity,permission);
//            boolean granted= ContextCompat.checkSelfPermission(activity,
//                    Manifest.permission.ACCESS_FINE_LOCATION)
//                    == PackageManager.PERMISSION_GRANTED;
//            boolean pc = PermissionChecker.checkSelfPermission(activity,permission)==PermissionChecker.PERMISSION_GRANTED;
//            Log.d("_RAIMAGE", "checkPermissions1: "+permission+"  SHOW  "+bshow+"  granted  "+granted +","+pc);
//        }
//        Log.d("_RAIMAGE", "checkPermissions1:==================================== ");
//    }
    public static boolean isNumeric(String str){
        for (int i = 0; i < str.length(); i++){
            System.out.println(str.charAt(i));
            if (!Character.isDigit(str.charAt(i))){
                return false;
            }
        }
        return true;
    }
    public static Boolean checkPermissions(Activity activity, String[] permissions)
    {
        if (Build.VERSION.SDK_INT >= 23)
        {
            return checkPermissions_23(activity,permissions);
        }
        else
        {
            return false;
//            return checkPermissions_23(activity,permissions);
        }
    }

    public static Boolean checkPermissions_23(String[] permissions)
    {
        Log.d("_RAIMAGE", "checkPermissions23:==================================== ");
        ArrayList<String> request_list = new ArrayList<String>();
        Context context = RedAntApplication.getInstance().getApplicationContext();
        for(String permission : permissions) {

            boolean pc = PermissionChecker.checkSelfPermission(context,permission)== PermissionChecker.PERMISSION_GRANTED;
            if(!pc)
                return false;
        }
        Log.d("_RAIMAGE", "checkPermissions23:==================================== ");



        return true;

    }

    public static void updateGallery(String filename)//filename是我们的文件全名，包括后缀哦
    {

        Context context = RedAntApplication.getInstance().getApplicationContext();
        MediaScannerConnection.scanFile(context,
                new String[] { filename }, null,
                new MediaScannerConnection.OnScanCompletedListener() {
                    public void onScanCompleted(String path, Uri uri) {
                        Log.i("ExternalStorage", "Scanned " + path + ":");
                        Log.i("ExternalStorage", "-> uri=" + uri);
                    }
                });
    }

    public static Boolean checkPermissions_23(Activity activity, String[] permissions)
    {
        Log.d("_RAIMAGE", "checkPermissions23:==================================== ");
        ArrayList<String> request_list = new ArrayList<String>();
        for(String permission : permissions) {
            boolean bshow= ActivityCompat.shouldShowRequestPermissionRationale(activity,permission);
//            boolean granted= ContextCompat.checkSelfPermission(activity,
//                    Manifest.permission.ACCESS_FINE_LOCATION)
//                    == PackageManager.PERMISSION_GRANTED;
            boolean pc = PermissionChecker.checkSelfPermission(activity,permission)== PermissionChecker.PERMISSION_GRANTED;
//            Log.d("_RAIMAGE", "checkPermissions23: "+permission+"  SHOW  "+bshow+"  granted  "+granted +","+pc);

            if(!pc)
                request_list.add(permission);
        }
        Log.d("_RAIMAGE", "checkPermissions23:==================================== ");


        if(request_list.isEmpty())
            return false;
        ActivityCompat.requestPermissions(activity,
                request_list.toArray(new String[0]),
                MY_PERMISSIONS_REQUEST);


        return true;

    }
    public static Boolean checkPermissions_24(Activity activity, String[] permissions)
    {




//        ArrayList<String> request_list = new ArrayList<String>();
//        for(String permission : permissions) {
//
//
////            boolean bshow=ActivityCompat.shouldShowRequestPermissionRationale(activity,permission);
////
////
////            AppOpsManager appOpsManager = (AppOpsManager) activity.getSystemService(Context.APP_OPS_SERVICE);
////            String opsName = AppOpsManager.permissionToOp(permission);
////            if (opsName == null) {
////                return true;
////            }
////            int opsMode = appOpsManager.checkOpNoThrow(opsName, Process.myUid(), activity.getPackageName());
//////            return opsMode == AppOpsManager.MODE_ALLOWED;
//
//
////            if (ContextCompat.checkSelfPermission(activity,
////                    Manifest.permission.ACCESS_FINE_LOCATION)
////                    != PackageManager.PERMISSION_GRANTED||opsMode != AppOpsManager.MODE_ALLOWED)
//
//                request_list.add(permission);
//
//        }

//        File logfile = new File(Environment.getExternalStorageDirectory()
//                .getPath() + "/redant/pop/" + "debug" + ".log");
//
//        // int mode = Application.MODE_APPEND;
//        if (!logfile.exists())
//        {
//            // mode = Application.MODE_PRIVATE;
//            try
//            {
//                logfile.createNewFile();
//            }
//            catch (IOException e)
//            {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//
//            }
//        }
        if(permissions.length==0)
            return true;
        ActivityCompat.requestPermissions(activity,
                permissions,
                MY_PERMISSIONS_REQUEST);


        return true;

//
//        if (ContextCompat.checkSelfPermission(activity,
//                Manifest.permission.ACCESS_FINE_LOCATION)
//                != PackageManager.PERMISSION_GRANTED)
//        {
//
//
////            if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
////                    permission))
////            {
////                return false;
////            }
////            else
//            {
//                ActivityCompat.requestPermissions(activity,
//                        new String[]{permission},
//                        MY_PERMISSIONS_REQUEST);
//                return true;
//            }
//        } else
//        {
//           return true;
//        }
//        if(true)
//        return true;
        // 调用Context的checkCallingOrSelfPermission来检查权限

//        Activity activity1 = (Activity) activity;
//        if(activity==null)
//            return false;
//        if (PackageManager.PERMISSION_GRANTED!= context.checkCallingOrSelfPermission(permission)) {
//
////            String[] tmp = permission.split("\\.");
////            String permission_name = tmp[tmp.length - 1];
////            permission_name = permission_name.replace("_"," ");
////
////
////            new AlertDialog.Builder(context)
////                    .setTitle("Warning")
////                    .setMessage("RA Image need " + permission_name.toLowerCase() + " permission")
////                    .setPositiveButton("OK", null)
////                    .show();
////
////            return false;
//
//
//             if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
//                    permission)) {
//
//                Log.d("_RAIMAGE", "checkPermission: shouldShowRequestPermissionRationale TRUE   " + permission);
//                // Show an expanation to the user *asynchronously* -- don't block
//                // this thread waiting for the user's response! After the user
//                // sees the explanation, try again to request the permission.
//
//            } else {
//
//                // No explanation needed, we can request the permission.
//
//
//                Log.d("_RAIMAGE", "checkPermission: shouldShowRequestPermissionRationale false   "+ permission);
//                ActivityCompat.requestPermissions(activity,
//                        new String[]{permission},
//                        123);
//
//                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
//                // app-defined int constant. The callback method gets the
//                // result of the request.
//            }
//
//        }
//        return true;
    }

    public static String lastPathComponent(String path){

        int start=path.lastIndexOf("/");
        int end=path.lastIndexOf(".");
        if(start!=-1 && end!=-1){
            return path.substring(start+1,end);
        }else{
            return null;
        }

    }

    public static File routeBitmap(File sourceFile, String file_name)
    {
        /**
         * 获取图片的旋转角度，有些系统把拍照的图片旋转了，有的没有旋转
         */
        int degree = RAUtil.readPictureDegree(sourceFile.getAbsolutePath());

        BitmapFactory.Options opts=new BitmapFactory.Options();//获取缩略图显示到屏幕上
        opts.inSampleSize=1;
        Bitmap cbitmap= BitmapFactory.decodeFile(sourceFile.getAbsolutePath(),opts);

        /**
         * 把图片旋转为正的方向
         */
        Bitmap newbitmap = RAUtil.rotaingImageView(degree, cbitmap);

        //sourceFile.get
        String routedPath = "";
        if(file_name==null) {
            String path = sourceFile.getPath();

            routedPath=path.replace(".jpg", "_routed.jpg");
        }
        else
        {
            String path = sourceFile.getParent();
            routedPath = path+"/"+file_name;
        }
        File routedFile = new File(routedPath);
        try {

            FileOutputStream outputStream = new FileOutputStream(routedFile);
            newbitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);

            outputStream.flush();
            outputStream.close();

            String filepath = sourceFile.getAbsolutePath();
            sourceFile.delete();
            RAUtil.updateGallery(filepath);
//				scaleFile.renameTo(new File(path));
            return routedFile;

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

    }
    /**
     * 读取图片属性：旋转的角度
     * @param path 图片绝对路径
     * @return degree旋转的角度
     */
    public static int readPictureDegree(String path) {
        int degree  = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }
    /*
     * 旋转图片
     * @param angle
     * @param bitmap
     * @return Bitmap
     */
    public static Bitmap rotaingImageView(int angle , Bitmap bitmap) {
        //旋转图片 动作
        Matrix matrix = new Matrix();;
        matrix.postRotate(angle);
        System.out.println("angle2=" + angle);
        // 创建新的图片
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }
    public static JSONObject Bundle2Json(Bundle bundle)
    {
        JSONObject json = new JSONObject();
        Set<String> keys = bundle.keySet();
        for (String key : keys) {
            try {
                Log.d("", "Bundle2Json: key:"+key+"  val: "+wrap(bundle.get(key)));
                 json.put(key, wrap(bundle.get(key))); //see edit below
//                json.put(key, JSONObject.wrap(bundle.get(key)));
            } catch(JSONException e) {
                //Handle exception here
            }
        }
        return json;
    }

    private static Object wrap(Object o) {
        if (o == null) {
            return JSONObject.NULL;
        }
        if (o instanceof JSONArray || o instanceof JSONObject) {
            return o;
        }
        if (o.equals(JSONObject.NULL)) {
            return o;
        }
        try {
            if (o instanceof Bundle)
            {
                return Bundle2Json((Bundle) o);

            }
            if (o instanceof Collection) {
                return new JSONArray((Collection) o);
            } else if (o.getClass().isArray()) {
                return toJSONArray(o);
            }
            if (o instanceof Map) {
                return new JSONObject((Map) o);
            }
            if (o instanceof Boolean ||
                    o instanceof Byte ||
                    o instanceof Character ||
                    o instanceof Double ||
                    o instanceof Float ||
                    o instanceof Integer ||
                    o instanceof Long ||
                    o instanceof Short ||
                    o instanceof String) {
                return o;
            }
            if (o.getClass().getPackage().getName().startsWith("java.")) {
                return o.toString();
            }
        } catch (Exception ignored) {
        }
        return null;
    }

    private static JSONArray toJSONArray(Object array) throws JSONException {
        JSONArray result = new JSONArray();
        if (!array.getClass().isArray()) {
            throw new JSONException("Not a primitive array: " + array.getClass());
        }
        final int length = Array.getLength(array);
        for (int i = 0; i < length; ++i) {
            result.put(wrap(Array.get(array, i)));
        }
        return result;
    }
    public static Bundle Json2Bundle(JSONObject s) {
        Bundle bundle = new Bundle();

        for (Iterator<String> it = s.keys(); it.hasNext(); ) {
            String key = it.next();
            try {
                Object o = s.get(key);



                if (o == null) {
                    continue;
                }
                else if ( o instanceof JSONObject) {
                    bundle.putBundle(key,Json2Bundle((JSONObject) o));
                }
                else if(o instanceof JSONArray)
                {
                    throw new JSONException("Json2Bundle does not support Json array: " + o.getClass());// bundle.putarr
                }
                else if (o.equals(JSONObject.NULL)) {
                    continue;
                }
                else if (o instanceof Boolean)
                {
                    bundle.putBoolean(key,((Boolean) o).booleanValue());
                }
                else if(o instanceof Byte)
                {
                    bundle.putByte(key, ((Byte) o).byteValue());
                }
                else if(o instanceof Character)
                {
                    bundle.putChar(key, ((Character) o).charValue());
                }
                else if(o instanceof Double)
                {
                    bundle.putDouble(key, ((Double) o).doubleValue());
                }
                else if(o instanceof Float)
                {
                    bundle.putFloat(key, ((Float) o).floatValue());
                }
                else if(o instanceof Integer)
                {
                    bundle.putInt(key, ((Integer) o).intValue());
                }
                else if(o instanceof Long)
                {
                    bundle.putLong(key, ((Long) o).longValue());
                }
                else if(o instanceof Short)
                {
                    bundle.putShort(key, ((Short) o).shortValue());
                }
                else if(o instanceof String)
                {
                    bundle.putString(key, o.toString());
                }

//                ArrayList<Parcelable> a = new ArrayList<>();
//                a.add("");
//                a.add(1);
//                bundle.putParcelableArrayList("arr", a);



            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return bundle;
    }
    public static Bundle Json2Bundle1(JSONObject s) {
        Bundle bundle = new Bundle();

        for (Iterator<String> it = s.keys(); it.hasNext(); ) {
            String key = it.next();
            JSONArray arr = s.optJSONArray(key);
            Double num = s.optDouble(key);
//            Integer i = s.optInt(key);
            String str = s.optString(key);
            JSONObject obj = s.optJSONObject(key);
            if (arr != null && arr.length() <= 0)
            {
                bundle.putStringArray(key, new String[]{});
            }

            else if (arr != null && !Double.isNaN(arr.optDouble(0))) {
                double[] newarr = new double[arr.length()];
                for (int i=0; i<arr.length(); i++)
                    newarr[i] = arr.optDouble(i);
                bundle.putDoubleArray(key, newarr);
            }

            else if (arr != null && arr.optString(0) != null) {
                String[] newarr = new String[arr.length()];
                for (int i=0; i<arr.length(); i++)
                    newarr[i] = arr.optString(i);
                bundle.putStringArray(key, newarr);
            }


            else if (obj != null)
            {
                Bundle b=Json2Bundle(obj);
                bundle.putBundle(key, b);
            }

            else if (!num.isNaN())
                bundle.putDouble(key, num);

            else if (str != null)
                bundle.putString(key, str);

            else
                System.err.println("unable to transform json to bundle " + key);
        }
        return bundle;
    }
//    public static Bundle Json2Bundle(JSONObject jsonObject) throws JSONException {
//        Bundle bundle = new Bundle();
//        Iterator iter = jsonObject.keys();
//        while(iter.hasNext()){
//            String key = (String)iter.next();
//            String value = jsonObject.getString(key);
//            bundle.putString(key,value);
//        }
//        return bundle;
//    }

    public static JSONArray jsonObject2KVArray(JSONObject object, boolean trim) {

        if (object == null) {
            return null;
        }

        try {
            JSONArray ret = new JSONArray();
            Iterator<String> iterator = object.keys();

            while (iterator.hasNext()) {

                JSONObject kv = new JSONObject();

                String key = iterator.next();
                Object value = object.get(key);

                kv.put("key",key);
                if (trim) {
                    if (value == null) {
                        continue;
                    }
                    String val = value.toString();
                    if (val.length() == 0) {
                        continue;
                    }
                }

                kv.put("value",value);
                ret.put(kv);

            }

            return ret;

        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }

    }

    public static String getApplicationName(Context context) {

        PackageManager packageManager = null;
        ApplicationInfo applicationInfo = null;
        try {
            packageManager = context.getPackageManager();
            applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            applicationInfo = null;
        }
        String applicationName = (String) packageManager.getApplicationLabel(applicationInfo);
        return applicationName;
    }

    public static String SDCardRoot() {
        return Environment.getExternalStorageDirectory()+File.separator;
    }

    public static File createSDDir(String dir)throws IOException{
        File dirFile=new File(SDCardRoot()+dir);
        dirFile.mkdir();//mkdir()只能创建一层文件目录，mkdirs()可以创建多层文件目录
        return dirFile;
    }

    //在SD卡上创建文件
    public static File createFileInSDCard(String fileName,String dir) throws IOException {
        File file=new File(SDCardRoot()+dir+File.separator+fileName);
        file.createNewFile();
        return file;
    }

    public static boolean isFileExist(String fileName,String dir){
        File file=new File(SDCardRoot()+dir+File.separator+fileName);
        return file.exists();
    }

    //将一个InoutStream里面的数据写入到SD卡中
    public static File write2SDFromInput(String fileName,String dir,InputStream input){
        File file=null;
        OutputStream output=null;
        try {
            //创建目录
            createSDDir(dir);
            //创建文件
            file=createFileInSDCard(fileName,dir);
            //写数据流
            output=new FileOutputStream(file);
            byte buffer[]=new byte[4*1024];//每次存4K
            int temp;
            //写入数据
            while((temp=input.read(buffer))!=-1){
                output.write(buffer,0,temp);
            }
            output.flush();
        } catch (Exception e) {
            System.out.println("写数据异常："+e);
        }
        finally{
            try {
                output.close();
            } catch (Exception e2) {
                System.out.println(e2);
            }
        }
        return file;
    }

    public static String getMimeType(String filePath) {
        String ext = MimeTypeMap.getFileExtensionFromUrl(filePath);
        String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
        if (mime == null || mime.isEmpty()) {
            mime = "text/plain";
        }
        return mime;
    }

}
