package be.msyben.vinylManager.gui.list.leftList;

import be.msyben.vinylManager.data.Data;
import be.msyben.vinylManager.entities.Album;
import be.msyben.vinylManager.properties.Language;
import be.msyben.vinylManager.properties.Preferences;
import be.msyben.vinylManager.tools.Sort;
import be.msyben.vinylManager.tools.internalEntities.TreeSortColumn;
import be.msyben.vinylManager.tools.internalEntities.TreeSortColumnEnum;
import be.msyben.vinylManager.tools.swing.MyJList;
import java.awt.Component;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**
 * Liste pour un champs choisi dans les préférences.
 *
 * @author Mathieu Syben
 */
public class SelectionnableFieldList extends AbstractLeftList {
    private static final long serialVersionUID = 73532846634353L;
    /**
     * La sélection courante
     */
    private DisplayElem currentSelection = null;
    /**
     * La liste
     */
    private final JList<DisplayElem> list = new MyJList<>();
    /**
     * Le scrollpanel
     */
    private JScrollPane panel;

    /**
     * Constructeur.
     */
    public SelectionnableFieldList() {
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (list.isSelectionEmpty()) {
                    selection(new ArrayList<>());
                } else {
                    currentSelection = (DisplayElem) list.getSelectedValue();
                    selection(getAlbums());
                }
            }
        });
        panel = new JScrollPane(list);
    }

    @Override
    public void updateList() {
        updateList(null);
    }

    @Override
    public void updateList(Album selectedAlbum) {
        int colId = getColId();
        list.setListData(getAllDatas().toArray(new DisplayElem[0]));
        double position;
        if (selectedAlbum == null) {
            currentSelection = null;
            list.clearSelection();
            position = 0.0;
        } else {
            int idx = -1;
            for (int i = 0; i < list.getModel().getSize(); i++) {

                String value = TreeSortColumn.getValueForSorting(selectedAlbum, colId).toLowerCase();
                if (((DisplayElem) list.getModel().getElementAt(i)).getForSort().toLowerCase().equals(value)) {
                    idx = i;
                    break;
                }
            }
            if (idx >= 0) {
                currentSelection = new DisplayElem(selectedAlbum.getArtisteForList(), selectedAlbum.getArtisteForSorting());
                list.setSelectedIndex(idx);
                position = (idx * 1.0) / (list.getModel().getSize() * 1.0);
            } else {
                currentSelection = null;
                list.clearSelection();
                position = 0.0;
            }
        }
        int positionNeeded = (int) (panel.getVerticalScrollBar().getMaximum() * position);
        panel.getVerticalScrollBar().setValue(positionNeeded);
    }

    /**
     * Renvoie la liste de toutes les données du champs choisi.
     *
     * @return la liste de toutes les données du champs choisi.
     */
    private List<DisplayElem> getAllDatas() {
        int colId = getColId();
        if (Data.getInstance().getCollection() == null) {
            return new ArrayList<>();
        }

        List<Album> all = Data.getInstance().getCollection().getAlbums();
        Sort.sort(all, Preferences.getInstance().get(Preferences.SORT_ARTIST_DESC, "N").equals("Y"), true, TreeSortColumn.getFieldNameForSorting(colId));

        List<DisplayElem> elems = new ArrayList<>();
        String last = null;
        for (Album a : all) {
            String value = TreeSortColumn.getDisplay(a, colId);
            String toDis = (value != null && !value.isEmpty()) ? value : "/";
            if (Preferences.getInstance().get(Preferences.STANDARD_NAME_UPPER_CASE, "Y").equals("Y")) {
                toDis = toDis.toUpperCase();
            }
            if (last == null) {
                last = value;
                elems.add(new DisplayElem(toDis, TreeSortColumn.getValueForSorting(a, colId)));
            } else {
                if (!last.toLowerCase().equals(value.toLowerCase())) {
                    last = value;
                    elems.add(new DisplayElem(toDis, TreeSortColumn.getValueForSorting(a, colId)));
                }
            }
        }


        return elems;
    }

    /**
     * Récupère la liste des albums.
     *
     * @return la liste des albums
     */
    private java.util.List<Album> getAlbums() {
        int colId = getColId();
        if (Data.getInstance().getCollection() == null) {
            return new ArrayList<>();
        }

        java.util.List<Album> albs = Data.getInstance().getCollection().getAlbums();
        java.util.List<Album> albsNeeded = new ArrayList<>();

        String artList = currentSelection.getForSort().toLowerCase();

        for (Album al : albs) {
            if (TreeSortColumn.getValueForSorting(al, colId).toLowerCase().equals(artList)) {
                albsNeeded.add(al);
            }
        }
        return albsNeeded;
    }

    @Override
    public void updateListAfterDeleteAlbum(Album deletedAlbum) {
        updateList(deletedAlbum);
    }

    @Override
    public Component getComponent() {
        return panel;
    }

    @Override
    public void setEnabled(boolean enabled) {
        panel.setEnabled(enabled);
        list.setEnabled(enabled);
    }

    @Override
    public String getTitle() {
        return Language.getInstance().get(TreeSortColumnEnum.getTreeSortColumnEnum(getColId()).getName());
    }

    private int getColId() {
        int ret = 1;
        try {
            ret = Integer.parseInt(Preferences.getInstance().get(Preferences.SELECTIONNABLE_CRITERE, "1"));
        } catch (NumberFormatException ex) {
        }
        if (ret < 1) {
            ret = 1;
        }
        return ret;
    }

    private static class DisplayElem {

        private String toShow, forSort;

        private DisplayElem() {
        }

        public DisplayElem(String toShow, String forSort) {
            this.toShow = toShow;
            this.forSort = forSort;
        }

        @Override
        public String toString() {
            return toShow;
        }

        public String getForSort() {
            return forSort;
        }
    }
}
