/*
 * Copyright (c) 2014 - 2024 askanimus@gmail.com
 *
 * This File is part of "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) 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.
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) 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.
 * You should have received a copy of the GNU General Public License
 * along with "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).  If not, see <http://www.gnu.org/licenses/>.
 * Diese Datei ist Teil von "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) ist Freie Software: Sie können es unter den Bedingungen
 * der GNU General Public License, wie von der Free Software Foundation,
 * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
 * veröffentlichten Version, weiter verteilen und/oder modifizieren.
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) wird in der Hoffnung, dass es nützlich sein wird, aber
 * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
 * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
 * Siehe die GNU General Public License für weitere Details.
 * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
 * Programm erhalten haben. Wenn nicht, siehe <https://www.gnu.org/licenses/>.
 */

/* This File is part of "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) 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.
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).  If not, see <http://www.gnu.org/licenses/>.
 *
 * Diese Datei ist Teil von "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) ist Freie Software: Sie können es unter den Bedingungen
 * der GNU General Public License, wie von der Free Software Foundation,
 * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
 * veröffentlichten Version, weiter verteilen und/oder modifizieren.
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) wird in der Hoffnung, dass es nützlich sein wird, aber
 * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
 * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
 * Siehe die GNU General Public License für weitere Details.
 *
 * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
 * Programm erhalten haben. Wenn nicht, siehe <https://www.gnu.org/licenses/>.
 */
package askanimus.arbeitszeiterfassung2.arbeitsschicht;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import askanimus.arbeitszeiterfassung2.R;
import askanimus.arbeitszeiterfassung2.Uhrzeit;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.einsatzort.Einsatzort;
import askanimus.arbeitszeiterfassung2.zusatzeintrag.IZusatzfeld;
import askanimus.arbeitszeiterfassung2.zusatzeintrag.ZusatzWertViewAdapter;

public class SchichtDefinitionViewAdapter
        extends RecyclerView.Adapter<SchichtDefinitionViewAdapter.ViewHolder> {
    private Context mContext;
    private Arbeitsplatz mArbeitsplatz;
    private SchichtDefaultListe mSchichten;
    private LayoutInflater mInflater;
    private ItemClickListener mClickListener;
    private int openPosition = -1;
    private ViewHolder openHolder = null;

    // Einstellungen zur Anzeige und Eingabe
    private Boolean isEinsatzort;

    //sind die Stundenwerte deziaml?
    private Boolean isDezimal;

    public void setUp(
            Context context,
            Arbeitsplatz arbeitsplatz,
            ItemClickListener clickListener
    ){
        mContext = context;
        mArbeitsplatz = arbeitsplatz;
        mInflater = LayoutInflater.from(context);
        mSchichten = mArbeitsplatz.getDefaultSchichten();
        mClickListener = clickListener;

        isEinsatzort = mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_WERT_EORT);
        isDezimal = mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL);
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.init_item_schicht, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull SchichtDefinitionViewAdapter.ViewHolder holder, int position) {
        if (position < getItemCount()) {

            SchichtDefault schicht = getItem(position);

            holder.mTitel.setText(schicht.getName());

            if (getItemCount() <= 1) {
                holder.mDelete.setVisibility(View.GONE);
            }

            // die Werte der Schicht anzeigen oder verbergen
            if (position == openPosition) {
                openHolder = holder;
                holder.mErweitert.setVisibility(View.VISIBLE);
                holder.iArrow.setImageResource(R.drawable.arrow_up);
                updateView(holder, position);
            }
        }
    }

    private void updateView(ViewHolder holder, int position){
        SchichtDefault mSchicht = getItem(position);

        if(mSchicht != null) {
            // Werte eintragen
            holder.wSchichtname.setText(mSchicht.getName());
            holder.wVon.setText(new Uhrzeit(mSchicht.getVon()).getUhrzeitString());
            holder.wBis.setText(new Uhrzeit(mSchicht.getBis()).getUhrzeitString());
            holder.wPause.setText(new Uhrzeit(mSchicht.getPause())
                    .getStundenString(true, isDezimal)
            );

            // den Optionelen Wert Einsatzort ein- oder ausblenden
            if (isEinsatzort) {
                if (mSchicht.getEinsatzOrt() > 0) {
                    Einsatzort eOrt = mArbeitsplatz.getEinsatzortListe().getOrt(mSchicht.getEinsatzOrt());
                    if (eOrt != null)
                        holder.wEinsatzort.setText(eOrt.getName());
                } else {
                    holder.wEinsatzort.setText("");
                }
            } else {
                holder.wEinsatzort.setVisibility(View.GONE);
            }

            // die Zusatzwerte ein- oder ausblenden
            if (mSchicht.getZusatzfelder().size() > 0) {
                holder.gZusatzwerte = holder.itemView.findViewById(R.id.I_view_zusatzwerte);
                ZusatzWertViewAdapter viewAdapter = new ZusatzWertViewAdapter(
                        mSchicht.getZusatzfelder().getListe(),
                        holder,
                        ZusatzWertViewAdapter.VIEW_EDIT
                );
                GridLayoutManager layoutManger = new GridLayoutManager(
                        mContext,
                        IZusatzfeld.MAX_COLUM
                );
                layoutManger.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                    @Override
                    public int getSpanSize(int position) {
                        return mSchicht.getZusatzfelder().get(position).getColums();
                    }
                });
                holder.gZusatzwerte.setLayoutManager(layoutManger);
                holder.gZusatzwerte.setAdapter(viewAdapter);
            } else {
                holder.gZusatzwerte.setVisibility(View.GONE);
            }



            //Klickhandler registrieren
            holder.wSchichtname.setOnClickListener(v -> mClickListener.onSchichtOpenPicker(
                    //openPosition,
                    Arbeitsschicht.WERT_NAME_SCHICHT)
            );
            holder.wVon.setOnClickListener(v -> mClickListener.onSchichtOpenPicker(
                    //openPosition,
                    Arbeitsschicht.WERT_VON)
            );
            holder.wBis.setOnClickListener(v -> mClickListener.onSchichtOpenPicker(
                    //openPosition,
                    Arbeitsschicht.WERT_BIS)
            );
            holder.wPause.setOnClickListener(v -> mClickListener.onSchichtOpenPicker(
                    //openPosition,
                    Arbeitsschicht.WERT_PAUSE)
            );


            if (isEinsatzort) {
                holder.wEinsatzort.setOnClickListener(v -> mClickListener.onSchichtOpenPicker(
                        // openPosition,
                        Arbeitsschicht.WERT_EORT)
                );
            }
        }
    }

    @Override
    public int getItemCount() {
        if(mSchichten != null) {
            return mSchichten.getSizeAktive();
        }
        return 0;
    }

    SchichtDefault getItem(int index) {
        if (index < getItemCount()) {
            return mSchichten.getAktive(index);
        }
        return null;
    }

    public int getOpenPosition(){
        return openPosition;
    }

    public SchichtDefault getOpenItem(){
        if(openPosition >= 0){
            return getItem(openPosition);
        }
        return null;
    }

    // öffne neu angelegte Abwesenheit (also die letzte in der Liste)
    public void openNew(){
        // die zuvor offene Abwesenheit schliessen
        if(openHolder != null){
           openHolder.mErweitert.setVisibility(View.GONE);
        }

        // neue Abwesenheit als geöffnet markieren
        openPosition = getItemCount()-1;
        mClickListener.onExpand(openPosition);
    }


    // die aufrufende Activity muss diese Listener impelmentieren
    public interface ItemClickListener {
        /**
         * Aufgerufen wenn sich Werte der Schicht geändert haben
         */
        void onSchichtDelete(int index);
        void onExpand(int position);

        // wenn ein Picker geöffnet werden soll
        void onSchichtOpenPicker(int wert);

        void onZusatzfeldOpenPicker(IZusatzfeld feld, int wert );
    }

    public class ViewHolder
            extends RecyclerView.ViewHolder
            implements ZusatzWertViewAdapter.ItemClickListener {
        TextView mTitel;
        ImageView mDelete;
        public ImageView iArrow;
        public RelativeLayout mErweitert;
        TextView wSchichtname;
        TextView wVon;
        TextView wBis;
        TextView wPause;
        TextView wEinsatzort;
        RecyclerView gZusatzwerte;

        ViewHolder(@NonNull View itemView) {
            super(itemView);

            mTitel = itemView.findViewById(R.id.I_kopf_name);
            mDelete = itemView.findViewById(R.id.I_kopf_button);
            iArrow = itemView.findViewById(R.id.I_arrow);
            mErweitert = itemView.findViewById(R.id.I_frame_schicht);
            wSchichtname = itemView.findViewById(R.id.I_wert_schichtname);
            wVon = itemView.findViewById(R.id.I_wert_von);
            wBis = itemView.findViewById(R.id.I_wert_bis);
            wPause = itemView.findViewById(R.id.I_wert_pause);
            wEinsatzort = itemView.findViewById(R.id.I_wert_eort);
            gZusatzwerte = itemView.findViewById(R.id.I_view_zusatzwerte);

            RelativeLayout bTitel = itemView.findViewById(R.id.I_kopf_frame);
            bTitel.setBackgroundColor(mArbeitsplatz.getFarbe_Tag());
            bTitel.setOnClickListener(v -> expand(getAdapterPosition()));

            if (mClickListener != null) {
                mDelete.setOnClickListener(v -> mClickListener.onSchichtDelete(getAdapterPosition()));
            }
        }


        void expand(int position) {
            if (mClickListener != null) {
                // den alten Inhalt schliessen
                if (openHolder != null) {
                    openHolder.mErweitert.setVisibility(View.GONE);
                    openHolder.iArrow.setImageResource(R.drawable.arrow_down);
                }
                // den neuen Inhalt öffnen, wenn der neue nicht der alte ist
                // wenn es der alte ist, dann diesen wierder schließen
                if (openHolder  == this) {
                    openHolder = null;
                    openPosition = -1;
                } else {
                    openPosition = position;
                    openHolder = this;
                    iArrow.setImageResource(R.drawable.arrow_up);

                    updateView(this, openPosition);

                    // Erweiterung öffnen
                    mErweitert.setVisibility(View.VISIBLE);
                    mClickListener.onExpand(position);
                }
            }
        }

        @Override
        public void onItemClick(View view, IZusatzfeld feld) {
            switch (feld.getDatenTyp()) {
                case IZusatzfeld.TYP_TEXT:
                    mClickListener.onZusatzfeldOpenPicker(
                            //getAdapterPosition(),
                            feld,
                            Arbeitsschicht.WERT_ZUSATZ_TEXT );
                    break;
                case IZusatzfeld.TYP_ZAHL:
                    mClickListener.onZusatzfeldOpenPicker(
                            //getAdapterPosition(),
                            feld,
                            Arbeitsschicht.WERT_ZUSATZ_ZAHL);
                    break;
                case IZusatzfeld.TYP_ZEIT:
                    mClickListener.onZusatzfeldOpenPicker(
                            //getAdapterPosition(),
                            feld,
                            Arbeitsschicht.WERT_ZUSATZ_ZEIT);
                    break;
                case IZusatzfeld.TYP_BEREICH_ZAHL:
                    if (view.getId() == R.id.ZW_wert_1)
                        mClickListener.onZusatzfeldOpenPicker(
                                //getAdapterPosition(),
                                feld,
                                Arbeitsschicht.WERT_ZUSATZ_ZAHL_VON);
                    else if (view.getId() == R.id.ZW_wert_2)
                        mClickListener.onZusatzfeldOpenPicker(
                                //getAdapterPosition(),
                                feld,
                                Arbeitsschicht.WERT_ZUSATZ_ZAHL_BIS);
                    break;
                case IZusatzfeld.TYP_BEREICH_ZEIT:
                    if (view.getId() == R.id.ZW_wert_1)
                        mClickListener.onZusatzfeldOpenPicker(
                                //getAdapterPosition(),
                                feld,
                                Arbeitsschicht.WERT_ZUSATZ_ZEIT_VON);
                    else if (view.getId() == R.id.ZW_wert_2)
                        mClickListener.onZusatzfeldOpenPicker(
                                //getAdapterPosition(),
                                feld,
                                Arbeitsschicht.WERT_ZUSATZ_ZEIT_BIS);
                    break;
            }

        }
    }
}
