/*
 * Copyright 2017 By_syk
 *
 * Licensed 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.by_syk.nanoiconpack.lite;

import android.app.Activity;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import org.xmlpull.v1.XmlPullParser;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * 图标包简单图标列表界面
 *
 * v2.0
 * changelog
 * + 支持分类
 *
 * Created by By_syk on 2017-06-14.
 */

public class LiteIconActivityV2 extends Activity {
    private GridLayoutManager layoutManager;
    private IconAdapter adapter;

    private DisplayMetrics displayMetrics;

    private final int GRID_W_IN_DP = 72;
    private final int GRID_H_IN_DP = 64;
    private final int ICON_SIZE_IN_DP = 48;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        init();

        (new LoadIconTask()).execute();
    }

    private void init() {
        setTheme(android.R.style.Theme_DeviceDefault_Wallpaper);

        displayMetrics = getResources().getDisplayMetrics();

        adapter = new IconAdapter();

        layoutManager = new GridLayoutManager(this, calculateGridNum());
        layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                return adapter.isCate(position) ? layoutManager.getSpanCount() : 1;
            }
        });

        RecyclerView recyclerView = new RecyclerView(this);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);

        ViewGroup.LayoutParams lpRv = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        recyclerView.setLayoutParams(lpRv);
        recyclerView.setBackgroundColor(0x80808080); // 保证图标视觉

        setContentView(recyclerView);
    }

    private int calculateGridNum() {
        final int MIN_GRID_SIZE = (int) (GRID_W_IN_DP * displayMetrics.density);
        int totalWidth = displayMetrics.widthPixels;
        return totalWidth / MIN_GRID_SIZE;
    }

    private List<Cate> getIcons() {
        List<Cate> dataList = new ArrayList<>();
        Cate defCate = new Cate(null);
        XmlResourceParser parser = getResources().getXml(R.xml.drawable);
        try {
            int event = parser.getEventType();
            while (event != XmlPullParser.END_DOCUMENT) {
                if (event == XmlPullParser.START_TAG) {
                    switch (parser.getName()) {
                        case "category":
                            dataList.add(new Cate(parser.getAttributeValue(null, "title")));
                            break;
                        case "item":
                            String iconName = parser.getAttributeValue(null, "drawable");
                            if (dataList.isEmpty()) {
                                defCate.pushIcon(iconName);
                            } else {
                                dataList.get(dataList.size() - 1).pushIcon(iconName);
                            }
                            break;
                    }
                }
                event = parser.next();
            }
            if (!defCate.isEmpty()) {
                dataList.add(defCate);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataList;
    }

    private int getClickBg() {
        TypedArray typedArray = obtainStyledAttributes(new int[] {Build.VERSION.SDK_INT >= 21
                ? android.R.attr.selectableItemBackgroundBorderless
                : android.R.attr.selectableItemBackground
        });
        int resId = typedArray.getResourceId(0, 0);
        typedArray.recycle();
        return resId;
    }

    private class LoadIconTask extends AsyncTask<String, Integer, List<Icon>> {
        @Override
        protected List<Icon> doInBackground(String... params) {
            List<Icon> iconList = new ArrayList<>();
            List<Cate> cateList = getIcons();
            for (Cate cate : cateList) {
                iconList.add(new Icon(cate.getName()));
                for (String iconName : cate.listIcons()) {
                    iconList.add(new Icon(iconName, cate.getName()));
                }
            }
            if (cateList.size() == 1 && cateList.get(0).getName() == null) { // 无任何分类
                iconList.remove(0);
            }
            return iconList;
        }

        @Override
        protected void onPostExecute(List<Icon> list) {
            super.onPostExecute(list);

            adapter.refresh(list);
        }
    }

    private class IconAdapter extends RecyclerView.Adapter {
        private List<Icon> dataList = new ArrayList<>();

        private static final int ITEM_TYPE_CATE = 0;
        private static final int ITEM_TYPE_ICON = 1;

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if (viewType == ITEM_TYPE_CATE) {
                return new CateHolder(initCateView());
            }
            return new IconHolder(initIconView());
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            Icon icon = dataList.get(position);
            if (holder instanceof CateHolder) {
                CateHolder cateHolder = (CateHolder) holder;
                cateHolder.tvCate.setText(icon.getCate() != null ? icon.getCate() : "default");
            } else {
                IconHolder iconHolder = (IconHolder) holder;
                iconHolder.ivIcon.setImageResource(icon.getId());
            }
        }

        @Override
        public int getItemCount() {
            return dataList.size();
        }

        @Override
        public int getItemViewType(int position) {
            return isCate(position) ? ITEM_TYPE_CATE : ITEM_TYPE_ICON;
        }

        private View initCateView() {
            TextView tvCate = new TextView(LiteIconActivityV2.this);
            tvCate.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
            tvCate.setTypeface(Typeface.DEFAULT_BOLD);
            tvCate.setTextColor(Color.WHITE);
            tvCate.setSingleLine(true);
            int paddingH = (int) (displayMetrics.density * 16);
            tvCate.setPadding(paddingH, (int) (displayMetrics.density * 16),
                    paddingH, (int) (displayMetrics.density * 8));

            return tvCate;
        }

        private View initIconView() {
            FrameLayout contentView = new FrameLayout(LiteIconActivityV2.this);
            int gridW = (int) (displayMetrics.density * GRID_W_IN_DP);
            int gridH = (int) (displayMetrics.density * GRID_H_IN_DP);
            ViewGroup.LayoutParams lpCv = new ViewGroup.LayoutParams(gridW, gridH);
            contentView.setLayoutParams(lpCv);

            ImageView ivIcon = new ImageView(LiteIconActivityV2.this);
            ivIcon.setTag("iv");
            ivIcon.setScaleType(ImageView.ScaleType.FIT_CENTER);
            ivIcon.setClickable(true);
            ivIcon.setBackgroundResource(getClickBg());
            int iconSize = (int) (displayMetrics.density * ICON_SIZE_IN_DP);
            FrameLayout.LayoutParams lpIv = new FrameLayout.LayoutParams(iconSize, iconSize);
            lpIv.gravity = Gravity.CENTER;
            ivIcon.setLayoutParams(lpIv);
            contentView.addView(ivIcon);

            return contentView;
        }

        boolean isCate(int position) {
            return dataList.get(position).getName() == null;
        }

        void refresh(List<Icon> dataList) {
            this.dataList.clear();
            if (dataList != null) {
                this.dataList.addAll(dataList);
            }
            notifyDataSetChanged();
        }

        class CateHolder extends RecyclerView.ViewHolder {
            TextView tvCate;

            CateHolder(View itemView) {
                super(itemView);

                tvCate = (TextView) itemView;
            }
        }

        class IconHolder extends RecyclerView.ViewHolder {
            ImageView ivIcon;

            IconHolder(View itemView) {
                super(itemView);

                ivIcon = (ImageView) itemView.findViewWithTag("iv");
            }
        }
    }

    private class Cate {
        private String name; // 无名分类则置为 null
        private Set<String> iconSet;

        Cate(String name) {
            this.name = name;
            iconSet = new LinkedHashSet<>();
        }

        public String getName() {
            return name;
        }

        public void pushIcon(String iconName) {
            iconSet.add(iconName);
        }

        public boolean isEmpty() {
            return iconSet.isEmpty();
        }

        public List<String> listIcons() {
            List<String> list = new ArrayList<>(iconSet.size());
            list.addAll(iconSet);
            return list;
        }
    }

    private class Icon {
        // 0 为无效ID
        private int id;
        // 为 null 表示无效图标
        private String name;
        // 无所属分类则置为 null
        private String cate;

        Icon(String cate) {
            this.cate = cate;
        }

        Icon(String name, String cate) {
            this(cate);
            this.name = name;
            this.id = getResources().getIdentifier(name, "drawable", getPackageName());
        }

        public int getId() {
            return id;
        }

        public String getName() {
            return name;
        }

        public String getCate() {
            return cate;
        }
    }
}