package com.quaap.launchtime;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.quaap.launchtime.apps.AppLauncher;
import com.quaap.launchtime.components.ExceptionHandler;
import com.quaap.launchtime.components.IconsHandler;
import com.quaap.launchtime.components.SpecialIconStore;
import com.quaap.launchtime.db.DB;

import java.io.InputStream;
import java.util.List;

/**
 *
 * Some portions of this file are derived from from ADW.Launcher (AnderWeb <[email protected]>),
 * which is under the Apache 2.0 License.
 *
 * See also https://github.com/AnderWeb/android_packages_apps_Launcher
 *
 * Modified by Tom Kliethermes. 2017
 *
 * Rest Copyright (C) 2017   Tom Kliethermes
 *
 * This file is part of LaunchTime and is is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 *
 *
 **/

public class CustomizeLaunchersActivity extends Activity {

    private LinearLayout list;

    private int mIconSize;

    private AppLauncher mAppClicked;

    private ImageView mClickedIconView;
    private TextView mClickedTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_customize_launchers);

        if (GlobState.enableCrashReporter && !BuildConfig.DEBUG) Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));

        mIconSize = (int) getResources().getDimension(android.R.dimen.app_icon_size);

        list = findViewById(R.id.custom_launchers_layout);

        final DB db = GlobState.getGlobState(this).getDB();

        final IconsHandler ich = GlobState.getIconsHandler(this);

        final Handler handler = new Handler();

        final int iconSize = (int)this.getResources().getDimension(R.dimen.icon_width);


        for (final String catID: db.getCategories()) {

            List<AppLauncher> apps = db.getApps(catID);
            if (apps.isEmpty()) continue;

            handler.post(new Runnable() {
                @Override
                public void run() {
                    TextView cat = new TextView(CustomizeLaunchersActivity.this);
                    cat.setText(db.getCategoryDisplayFull(catID));
                    cat.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24);
                    cat.setBackgroundColor(Color.BLACK);
                    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                    lp.gravity = Gravity.CENTER;
                    lp.setMargins(12,18,12,12);
                    cat.setLayoutParams(lp);
                    cat.setPadding(12,6,6,6);
                    list.addView(cat);
                }
            });


            for (final AppLauncher app: apps) {

                if (app.isWidget()) continue;

                final boolean hasCustIcon = SpecialIconStore.hasBitmap(CustomizeLaunchersActivity.this, app.getComponentName(), SpecialIconStore.IconType.Custom);
                final boolean hasCustLabel = db.appHasCustomLabel(app.getComponentName());

                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        final LinearLayout applayout = new LinearLayout(CustomizeLaunchersActivity.this);
                        applayout.setOrientation(LinearLayout.HORIZONTAL);

                        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                        lp.gravity = Gravity.CENTER_VERTICAL;
                        lp.setMargins(24,12,12,12);
                        applayout.setLayoutParams(lp);
                        applayout.setPadding(18,6,6,6);

                        if (hasCustIcon || hasCustLabel) {
                            applayout.setBackgroundColor(Color.DKGRAY);
                        }

                        final ImageView iconView = new ImageView(CustomizeLaunchersActivity.this);

                        iconView.setPadding(12,12,12,12);
                        LinearLayout.LayoutParams ilp = new LinearLayout.LayoutParams(iconSize, iconSize);
                        ilp.setMargins(12,12,24,12);
                        iconView.setLayoutParams(ilp);

                        Drawable icon = ich.getCustomIcon(app.getComponentName());

                        if (icon == null) {
                            icon = ich.getDrawableIconForPackage(app);
                        }

                        iconView.setImageDrawable(icon);

                        if (hasCustIcon) {
                            setItemModified(iconView, true);
                        }


                        iconView.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                mAppClicked = app;
                                mClickedIconView = iconView;
                                new IconTypeDialog().createDialog().show();

                            }
                        });
                        applayout.addView(iconView);

                        final TextView label = new TextView(CustomizeLaunchersActivity.this);
                        label.setText(app.getLabel());
                        label.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
                        label.setPadding(18,6,18,6);
                        label.setTextColor(Color.WHITE);
                        LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                        llp.setMargins(24,12,24,12);
                        label.setLayoutParams(llp);

                        if (hasCustLabel) {
                            setItemModified(label, true);
                        }

                        label.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                mAppClicked = app;
                                mClickedTextView = label;
                                promptForAppLabel();
                            }
                        });
                        applayout.addView(label);


                        list.addView(applayout);
                    }
                });

            }
            //list.postInvalidate();


        }

    }

    @Override
    public void onBackPressed() {
        pickingIcon = false;
        finish();
        MainActivity.openSettings(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (!pickingIcon) {
            finish();
            Log.d("Customizer", "finishing in onpause");
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        pickingIcon = false;
    }

    private void promptForAppLabel() {
        try {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle(R.string.custom_icon_text);

            final EditText input = new EditText(this);

            input.setText(mAppClicked.getLabel());

            input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
            builder.setView(input);


            builder.setPositiveButton(R.string.done, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    String labeltext = input.getText().toString();
                    if (!labeltext.isEmpty()) {
                        updateAppLabel(labeltext);
                    }
                }
            });
            if (GlobState.getGlobState(this).getDB().appHasCustomLabel(mAppClicked.getComponentName())) {
                builder.setNeutralButton(R.string.clear, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        updateAppLabel(null);
                    }
                });
            }
            builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

            builder.show();
        } catch (Exception|Error e) {
            Log.e("custLaunch", e.getMessage(), e);
        }

        //if (dialog.getWindow()!=null) dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

//        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
//        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

    }

    private void updateAppLabel(String labeltext) {
        DB db = GlobState.getGlobState(CustomizeLaunchersActivity.this).getDB();
        mAppClicked.setLabel(labeltext);
        AppLauncher.removeAppLauncher(mAppClicked.getComponentName());
        db.setAppCustomLabel(mAppClicked.getActivityName(), mAppClicked.getPackageName(), labeltext);
        mAppClicked = db.getApp(mAppClicked.getComponentName());


        mClickedTextView.setText(mAppClicked.getLabel());

        setItemModified(mClickedTextView, labeltext!=null && !labeltext.isEmpty());

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        int num = prefs.getInt("icon-update", 0);
        prefs.edit().putInt("icon-update", num+1).apply();
    }


    private boolean pickingIcon;


    private static final int PICK_CUSTOM_ICON=1;
    private static final int PICK_FROM_ICON_PACK=6;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);

        pickingIcon = false;

        if (resultCode == RESULT_OK) {
            //DB db = GlobState.getGlobState(this).getDB();
            try {
                Bitmap bitmap = null;
                switch (requestCode) {
                    case PICK_FROM_ICON_PACK:
                        bitmap = data.getParcelableExtra("data");
                        if (bitmap != null) {
                            if (bitmap.getWidth() > mIconSize) {
                                bitmap = Bitmap.createScaledBitmap(bitmap, mIconSize, mIconSize, true);
                            }
                            bitmap.setHasAlpha(true);
                        }
                        break;
                    case PICK_CUSTOM_ICON:
                        Uri photoUri = data.getData();
                        if (photoUri!=null)
                        try {
                            InputStream is = getContentResolver().openInputStream(photoUri);
                            BitmapFactory.Options opts = new BitmapFactory.Options();
                            opts.inJustDecodeBounds = true;
                            bitmap = BitmapFactory.decodeStream(is, null, opts);

                            BitmapFactory.Options ops2 = new BitmapFactory.Options();
                            int width = mIconSize;
                            float w = opts.outWidth;
                            //int scale = Math.round(w / width);
                            int scale = (int) (w / width);
                            ops2.inSampleSize = scale;
                            is = getContentResolver().openInputStream(photoUri);
                            bitmap = BitmapFactory.decodeStream(is, null, ops2);
                            if (bitmap != null) {
                                if (bitmap.getWidth() > mIconSize) {
                                    bitmap = Bitmap.createScaledBitmap(bitmap, mIconSize, mIconSize, true);
                                }
                                bitmap.setHasAlpha(true);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;

                }

                if (bitmap != null && mAppClicked != null) {
                    updateBitmap(bitmap);
                } else {
                    Log.d("custLaunch", "NULL1!!" + bitmap + " " + mAppClicked);
                }
            } catch (Exception|Error e) {
                Log.e("custLaunch", e.getMessage(), e);
            }
        }
    }

    private void setItemModified(View v, boolean modified) {
        if (modified) {
            v.setBackgroundColor(Color.parseColor("#99335533"));
        } else {
            v.setBackgroundColor(Color.TRANSPARENT);
        }
    }

    private void updateBitmap(Bitmap bitmap) {
        if (mAppClicked!=null && mClickedIconView!=null) {
            try {
                if (bitmap == null) {
                    SpecialIconStore.deleteBitmap(this, mAppClicked.getComponentName(), SpecialIconStore.IconType.Custom);

                    IconsHandler ich = GlobState.getIconsHandler(this);

                    Drawable icon = ich.getDrawableIconForPackage(mAppClicked);

                    mClickedIconView.setImageDrawable(icon);


                } else {
                    SpecialIconStore.saveBitmap(this, mAppClicked.getComponentName(), bitmap, SpecialIconStore.IconType.Custom);
                    mClickedIconView.setImageDrawable(new BitmapDrawable(this.getResources(), bitmap));
                }

                setItemModified(mClickedIconView, bitmap != null);

                AppLauncher.removeAppLauncher(mAppClicked.getComponentName());
                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                int num = prefs.getInt("icon-update", 0);
                prefs.edit().putInt("icon-update", num + 1).apply();
            } catch (Exception|Error e) {
                Log.e("custLaunch", e.getMessage(), e);
            }
        } else {
            Log.d("custLaunch", "NULL!!");
        }
    }

    class IconTypeDialog implements DialogInterface.OnClickListener,
            DialogInterface.OnCancelListener, DialogInterface.OnDismissListener,
            DialogInterface.OnShowListener {

        private ArrayAdapter<String> mAdapter;


        Dialog createDialog() {
            mAdapter = new ArrayAdapter<>(CustomizeLaunchersActivity.this, R.layout.add_list_item);
            mAdapter.add(getString(R.string.custom_icon_select_picture));
            mAdapter.add(getString(R.string.custom_icon_icon_packs));
            if (SpecialIconStore.hasBitmap(CustomizeLaunchersActivity.this, mAppClicked.getComponentName(), SpecialIconStore.IconType.Custom)) {
                mAdapter.add(getString(R.string.custom_icon_clear_icon));
            }

            final AlertDialog.Builder builder = new AlertDialog.Builder(CustomizeLaunchersActivity.this);
            builder.setTitle(R.string.custom_icon_select_icon_type);
            builder.setAdapter(mAdapter, this);

            //builder.setInverseBackgroundForced(false);

            AlertDialog dialog = builder.create();
            dialog.setOnCancelListener(this);
            dialog.setOnDismissListener(this);
            dialog.setOnShowListener(this);
            return dialog;
        }
        public void onCancel(DialogInterface dialog) {
            cleanup();
        }
        public void onDismiss(DialogInterface dialog) {
        }
        private void cleanup() {
        }
        public void onClick(DialogInterface dialog, int which) {
            pickingIcon = true;
            switch (which) {
                case 0:
                    //Select icon
                    Intent pickerIntent=new Intent(Intent.ACTION_PICK);
                    pickerIntent.setType("image/*");
                    startActivityForResult(Intent.createChooser(pickerIntent, getString(R.string.custom_icon_select_icon_type)), PICK_CUSTOM_ICON);
                    break;
                case 1:
                    Intent packIntent=new Intent(CustomizeLaunchersActivity.this, ChooseIconFromPackActivity.class);
                    startActivityForResult(packIntent, PICK_FROM_ICON_PACK);
                    break;
                case 2:
                    updateBitmap(null);
                    break;
                default:
                    break;
            }
            cleanup();
        }
        public void onShow(DialogInterface dialog) {
        }
    }


}