package com.xixun.xixunplayer;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Choreographer;
import android.view.Gravity;
import android.widget.ImageView;
import android.widget.LinearLayout;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.TimeZone;

import gnph.android.LinearBox;
import gnph.util.JSList;
import gnph.util.JSMap;
import gnph.util.NumFmts;

@SuppressLint("ViewConstructor")
public class SrcDigiClock extends LinearBox implements Choreographer.FrameCallback {

    static final String[] weeks = {"SUN", "MON","TUE","WED","THU","FRI","SAT"};
    HashMap<String, Bitmap> imgs = new HashMap<>();
    ImageView[] yearComps = {new ImageView(getContext()), new ImageView(getContext()), new ImageView(getContext()), new ImageView(getContext())};
    ImageView[] monthComps = {new ImageView(getContext()), new ImageView(getContext())};
    ImageView[] dayComps = {new ImageView(getContext()), new ImageView(getContext())};
    ImageView weekComp = new ImageView(getContext()), ampmComp = new ImageView(getContext());
    ImageView[] hourComps = {new ImageView(getContext()), new ImageView(getContext())};
    ImageView[] minComps = {new ImageView(getContext()), new ImageView(getContext())};
    ImageView[] secComps = {new ImageView(getContext()), new ImageView(getContext())};

    Calendar calendar;
    boolean multiline, weekly, isSingleMD, isHour12, isSingleHour;

    public SrcDigiClock(Prog prog, JSMap json) {
        super(prog.getContext());
        setGravity(Gravity.CENTER);
        var timeZoneStr = json.str("timeZone");
        //if(timeZoneStr!=null) timeZone = ZoneId.of(timeZoneStr);
        var timeZone = timeZoneStr==null ? null : TimeZone.getTimeZone(timeZoneStr);
        calendar = timeZone==null ? Calendar.getInstance() : Calendar.getInstance(timeZone);
        var spaceWidth = json.dbl("spaceWidth");
        JSList<JSMap> pics = json.jslist("arrayPics");
        if(pics!=null && ! pics.isEmpty() && pics.get(0).containsKey("startX")) {
            var big = BitmapFactory.decodeFile(Util.programDir+"/"+json.stnn("id"));
            for(var pic : pics) {
                var startX = pic.intg("startX");
                var startY = pic.intg("startY");
                imgs.put(pic.str("name"), Bitmap.createBitmap(big, startX, startY, pic.intg("endX")-startX, pic.intg("endY")-startY));
            }
        } else for(var pic : pics) imgs.put(pic.str("name"), BitmapFactory.decodeFile(Util.programDir+"/"+pic.stnn("id")));
        int dateStyle = json.intg("dateStyle");
        isSingleMD = dateStyle==1||dateStyle==2||dateStyle==4||dateStyle==6||dateStyle==8||dateStyle==10||dateStyle==12;
        isSingleHour = json.intg("timeStyle") != 0;
        var timeSep = imgs.get("maohao");
        weekly = json.bool("weekly");
        isHour12 = json.bool("hour12");
        var AmPm = isHour12 && json.bool("AmPm");
        var hour = json.bool("hour");
        var min = json.bool("min");
        var sec = json.bool("sec");
        multiline = json.bool("multiline");
        addStretch();
        if(multiline) {
            vertical();
            var hBox = new LinearBox(this).horizontal();
            hBox.addStretch();
            addDate(dateStyle, json, hBox);
            hBox.addStretch();
            if(weekly) {
                hBox = new LinearBox(this).horizontal();
                hBox.addStretch();
                hBox.addView(weekComp);
                hBox.addStretch();
            }
            hBox = new LinearBox(this).horizontal();
            hBox.addStretch();
            if(AmPm) {
                hBox.addView(ampmComp);
                hBox.addSpacing((int)spaceWidth);
            }
            if(hour) {
                hBox.addView(hourComps[0]);
                hBox.addView(hourComps[1]);
            }
            if(hour&&min) hBox.addView(newImgView(timeSep));
            if(min) {
                hBox.addView(minComps[0]);
                hBox.addView(minComps[1]);
            }
            if(min&&sec) hBox.addView(newImgView(timeSep));
            if(sec) {
                hBox.addView(secComps[0]);
                hBox.addView(secComps[1]);
            }
            hBox.addStretch();
        } else {
            setOrientation(HORIZONTAL);
            addDate(dateStyle, json, this);
            if(getChildCount()>1) addSpacing((int)spaceWidth*2);
            if(weekly) {
                addView(weekComp);
                addSpacing((int)spaceWidth*2);
            }
            if(AmPm) {
                addView(ampmComp);
                addSpacing((int)spaceWidth);
            }
            if(hour) {
                addView(hourComps[0]);
                addView(hourComps[1]);
            }
            if(hour&&min) addView(newImgView(timeSep));
            if(min) {
                addView(minComps[0]);
                addView(minComps[1]);
            }
            if(min&&sec) addView(newImgView(timeSep));
            if(sec) {
                addView(secComps[0]);
                addView(secComps[1]);
            }
        }
        addStretch();
        prog.calls.add(this);
    }

    ImageView newImgView(Bitmap img) {
        var imgv = new ImageView(getContext());
        imgv.setImageBitmap(img);
        return imgv;
    }
    void addDate(int dateStyle, JSMap layer, LinearLayout tar) {
        if(dateStyle==0 || dateStyle==1) {
            addYear(layer, tar, imgs.get("YEAR"));
            if(layer.bool("month")) {
                tar.addView(monthComps[0]);
                tar.addView(monthComps[1]);
                tar.addView(newImgView(imgs.get("MONTH")));
            }
            if(layer.bool("day")) {
                tar.addView(dayComps[0]);
                tar.addView(dayComps[1]);
                tar.addView(newImgView(imgs.get("DAY")));
            }
        } else if(dateStyle==2 || dateStyle==3) {
            var sep = imgs.get("xiegang");
            if(layer.bool("month")) {
                tar.addView(monthComps[0]);
                tar.addView(monthComps[1]);
                tar.addView(newImgView(sep));
            }
            if(layer.bool("day")) {
                tar.addView(dayComps[0]);
                tar.addView(dayComps[1]);
                tar.addView(newImgView(sep));
            }
            addYear(layer, tar, null);
        } else if(dateStyle==4 || dateStyle==5) {
            var sep = imgs.get("xiegang");
            if(layer.bool("day")) {
                tar.addView(dayComps[0]);
                tar.addView(dayComps[1]);
                tar.addView(newImgView(sep));
            }
            if(layer.bool("month")) {
                tar.addView(monthComps[0]);
                tar.addView(monthComps[1]);
                tar.addView(newImgView(sep));
            }
            addYear(layer, tar, null);
        } else if(dateStyle==6 || dateStyle==7) {
            var sep = imgs.get("xiegang");
            addYear(layer, tar, sep);
            if(layer.bool("month")) {
                tar.addView(monthComps[0]);
                tar.addView(monthComps[1]);
                tar.addView(newImgView(sep));
            }
            if(layer.bool("day")) {
                tar.addView(dayComps[0]);
                tar.addView(dayComps[1]);
            }
        } else if(dateStyle==8 || dateStyle==9) {
            var sep = imgs.get("hengxian");
            if(layer.bool("month")) {
                tar.addView(monthComps[0]);
                tar.addView(monthComps[1]);
                tar.addView(newImgView(sep));
            }
            if(layer.bool("day")) {
                tar.addView(dayComps[0]);
                tar.addView(dayComps[1]);
                tar.addView(newImgView(sep));
            }
            addYear(layer, tar, null);
        } else if(dateStyle==10 || dateStyle==11) {
            var sep = imgs.get("hengxian");
            if(layer.bool("day")) {
                tar.addView(dayComps[0]);
                tar.addView(dayComps[1]);
                tar.addView(newImgView(sep));
            }
            if(layer.bool("month")) {
                tar.addView(monthComps[0]);
                tar.addView(monthComps[1]);
                tar.addView(newImgView(sep));
            }
            addYear(layer, tar, null);
        } else if(dateStyle==12 || dateStyle==13) {
            var sep = imgs.get("hengxian");
            addYear(layer, tar, sep);
            if(layer.bool("month")) {
                tar.addView(monthComps[0]);
                tar.addView(monthComps[1]);
                tar.addView(newImgView(sep));
            }
            if(layer.bool("day")) {
                tar.addView(dayComps[0]);
                tar.addView(dayComps[1]);
            }
        }
    }

    void addYear(JSMap layer, LinearLayout tar, Bitmap sep) {
        if(layer.bool("year")) {
            if(layer.bool("fullYear"))  {
                tar.addView(yearComps[0]);
                tar.addView(yearComps[1]);
            }
            tar.addView(yearComps[2]);
            tar.addView(yearComps[3]);
            if(sep != null) tar.addView(newImgView(sep));
        }
    }

    void cal() {
        //var dt = timeZone==null ? LocalDateTime.now() : LocalDateTime.now(timeZone);
        calendar.setTimeInMillis(lastSec*1000);
        var hour = calendar.get(Calendar.HOUR_OF_DAY);
        ampmComp.setImageBitmap(imgs.get(hour < 12 ? "AM":"PM"));
        var hh = NumFmts.zz().format(isHour12 ? Util.caseThen(calendar.get(Calendar.HOUR), 0, 12) : hour);
        hourComps[0].setImageBitmap(isSingleHour && hh.charAt(0)=='0' ? null : imgs.get(hh.substring(0,1)));
        hourComps[1].setImageBitmap(imgs.get(hh.substring(1,2)));
        var mm = NumFmts.zz().format(calendar.get(Calendar.MINUTE));
        minComps[0].setImageBitmap(imgs.get(mm.substring(0,1)));
        minComps[1].setImageBitmap(imgs.get(mm.substring(1,2)));
        var ss = NumFmts.zz().format(calendar.get(Calendar.SECOND));
        secComps[0].setImageBitmap(imgs.get(ss.substring(0,1)));
        secComps[1].setImageBitmap(imgs.get(ss.substring(1,2)));
        var day = calendar.get(Calendar.DAY_OF_MONTH);
        if(yearComps[0].getDrawable()==null || day!=lastDay) {
            lastDay = day;
            if(weekly) weekComp.setImageBitmap(imgs.get(weeks[calendar.get(Calendar.DAY_OF_WEEK) - 1]));
            var yyyy = NumFmts.zzzz().format(calendar.get(Calendar.YEAR));
            yearComps[0].setImageBitmap(imgs.get(yyyy.substring(0,1)));
            yearComps[1].setImageBitmap(imgs.get(yyyy.substring(1,2)));
            yearComps[2].setImageBitmap(imgs.get(yyyy.substring(2,3)));
            yearComps[3].setImageBitmap(imgs.get(yyyy.substring(3,4)));
            mm = NumFmts.zz().format(calendar.get(Calendar.MONTH)+1);
            monthComps[0].setImageBitmap(isSingleMD && mm.charAt(0)=='0' ? null : imgs.get(mm.substring(0,1)));
            monthComps[1].setImageBitmap(imgs.get(mm.substring(1,2)));
            var dd = NumFmts.zz().format(day);
            dayComps[0].setImageBitmap(isSingleMD && dd.charAt(0)=='0' ? null : imgs.get(dd.substring(0,1)));
            dayComps[1].setImageBitmap(imgs.get(dd.substring(1,2)));
        }
    }
    int lastDay;

    long lastSec;

    @Override
    public void doFrame(long ms) {
        if(! isShown()) return;
        var sec = ms / 1000;
        if(sec != lastSec) {
            lastSec = sec;
            cal();
        }
    }
}