/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2021 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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 org.jboss.installer.panels.frame;

import org.jboss.installer.common.FontResources;
import org.jboss.installer.common.UiResources;
import org.jboss.installer.core.Screen;
import org.jboss.installer.core.ScreenManager;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.MatteBorder;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.util.List;
import java.util.function.Consumer;

public class ProgressPanel extends JPanel implements Consumer<ScreenManager.ScreensState> {

    private static final ImageIcon CURRENT_ICON = new ImageIcon(ProgressPanel.class.getResource("/img/arrow-right.png"));
    private static final int INDENT_WITH = 20;
    private static final String HTML_LABEL_WRAPPING = "<html><div style=\"width:100px;\">%s</div></html>";
    private static final int LINE_GAP = 28;

    public ProgressPanel() {
        initPanel();
    }

    public void initPanel() {
        this.setBackground(UiResources.SIDE_NAV_BG_COLOR);
        this.setBorder(new MatteBorder(0, 0, 0, 1, Color.LIGHT_GRAY));
        final BoxLayout mgr = new BoxLayout(this, BoxLayout.Y_AXIS);
        this.setLayout(mgr);
        this.setAlignmentX(Component.LEFT_ALIGNMENT);
    }

    public void updatePanel(List<Screen> activeScreenTitles, Screen activeScreen) {
        this.removeAll();
        boolean beforeActiveScreen = true;
        final IndexGenerator indexGenerator = new IndexGenerator();

        for (Screen screen : activeScreenTitles) {
            String index = indexGenerator.nextScreen(screen);
            int level = index.split("\\.").length;

            final JLabel titleLabel = new JLabel(String.format(HTML_LABEL_WRAPPING, screen.getSideNavName()));

            // iconLabel holds either icon for current/completed element or position index
            final JLabel iconLabel;
            if (activeScreen.equals(screen)) {
                beforeActiveScreen = false;
                iconLabel = new JLabel(CURRENT_ICON);
            } else if (beforeActiveScreen) {
                iconLabel = new JLabel(UiResources.DONE_ICON);
            }  else {
                iconLabel = new JLabel(index);
                iconLabel.setEnabled(false);
                titleLabel.setEnabled(false);
            }

            this.add(wrap(level, titleLabel, iconLabel));
        }
        repaint();
    }

    private JPanel wrap(int level, JLabel titleLabel, JLabel iconLabel) {
        final JPanel line = new JPanel();
        line.setBackground(UiResources.SIDE_NAV_BG_COLOR);
        line.setAlignmentX(Component.LEFT_ALIGNMENT);
        line.setLayout(new BoxLayout(line, BoxLayout.X_AXIS));
        line.setBorder(BorderFactory.createEmptyBorder(5, 20, 0, 5));

        titleLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
        titleLabel.setFont(FontResources.getOpenSansRegular());
        iconLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
        iconLabel.setFont(FontResources.getOpenSansRegular());

        while (level-- > 1) {
            final Component box = Box.createRigidArea(new Dimension(INDENT_WITH, 0));
            line.add(box);
        }

        line.add(iconLabel);
        line.add(Box.createRigidArea(new Dimension(LINE_GAP - iconLabel.getPreferredSize().width, 0)));
        line.add(titleLabel);

        return line;
    }

    @Override
    public void accept(ScreenManager.ScreensState screens) {
        updatePanel(screens.getVisibleScreens(), screens.getCurrentScreen());
    }
}
