/*-
 * #%L
 * This file is part of "Apromore Community".
 *
 * Copyright (C) 2015 - 2017 Queensland University of Technology.
 * %%
 * Copyright (C) 2018 - 2020 The University of Melbourne.
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program 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 Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
 * #L%
 */

package org.apromore.plugin.portal.bpmnminer;

import com.raffaeleconforti.foreignkeydiscovery.functionaldependencies.NoEntityException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zul.Button;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Window;

import java.io.IOException;
import java.util.List;

/**
 * Created by conforti on 9/04/15.
 */
public class CandidatesEntitiesController {

    private static final long serialVersionUID = 1L;
    private BPMNMinerController bpmnMinerController;
    private Window candidateEntitiesW;
    private Listbox candidates;
    private Button cancelButton;
    private Button nextButton;

    private List<String> listCandidates;
    private boolean[] selected;

    public CandidatesEntitiesController(BPMNMinerController bpmnMinerController, List<String> listCandidates) throws IOException {
        this.bpmnMinerController = bpmnMinerController;
        this.selected = new boolean[listCandidates.size()];
        this.listCandidates = listCandidates;

        this.candidateEntitiesW = (Window) bpmnMinerController.portalContext.getUI().createComponent(getClass().getClassLoader(), "zul/candidateEntities.zul", null, null);
        this.candidateEntitiesW.setTitle("Select Candidate Entities");

        this.candidates = (Listbox) this.candidateEntitiesW.getFellow("list");
        for(String candidate : listCandidates) {
            Listitem listItem = new Listitem();
            listItem.setLabel(candidate);
            this.candidates.appendChild(listItem);
            listItem.setSelected(false);
        }

        this.cancelButton = (Button) this.candidateEntitiesW.getFellow("entityCancelButton");
        this.nextButton = (Button) this.candidateEntitiesW.getFellow("entityNextButton");

        updateActions();

        this.candidates.addEventListener("onSelect", new EventListener<Event>() {
            public void onEvent(Event event) throws Exception {
                updateActions();
            }
        });
        this.cancelButton.addEventListener("onClick", new EventListener<Event>() {
            public void onEvent(Event event) throws Exception {
                cancel();
            }
        });
        this.nextButton.addEventListener("onClick", new EventListener<Event>() {
            public void onEvent(Event event) throws Exception {
                next();
            }
        });

        if(listCandidates != null && listCandidates.size() > 0) {
            this.candidateEntitiesW.doModal();
        }else {
            next();
        }
    }

    protected void cancel() {
        this.candidateEntitiesW.detach();
    }

    protected void next() {
        this.candidateEntitiesW.detach();
        try {
            this.bpmnMinerController.setSelectedCandidatesEntities(listCandidates, selected);
        } catch (IOException | NoEntityException e) {
            this.bpmnMinerController.noEntityException();
        }
    }

    protected void updateActions() {
        for(int i = 0; i < selected.length; i++) {
            boolean done = false;
            for(Listitem listItem : candidates.getSelectedItems()) {
                if(listCandidates.get(i).equals(listItem.getLabel())) {
                    selected[i] = true;
                    done = true;
                    break;
                }
            }
            if(!done) selected[i] = false;
        }
    }
}
