package de.duehl.swing.ui.start.filter.project.gateway;

/*
 * Copyright 2020 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import de.duehl.swing.ui.filter.exceptions.FilterException;
import de.duehl.swing.ui.filter.method.FilterMethodFabricable;
import de.duehl.swing.ui.filter.method.Method;
import de.duehl.swing.ui.filter.method.MethodAll;
import de.duehl.swing.ui.start.filter.project.gateway.generics.GenericType2Concrete;
import de.duehl.swing.ui.start.filter.project.method.TestMethodCriticalCodes;
import de.duehl.swing.ui.start.filter.project.method.TestMethodOneCode;
import de.duehl.swing.ui.start.filter.project.method.TestMethodShortText;

/**
 * Diese Klasse stellt eine Fabrik dar, die je nach dem übergebenen Filter-Typ eine entsprechende
 * Filter-Methoden-Klasse herstellt.
 *
 * @version 1.01     2020-11-05
 * @author Christian Dühl
 */

public class TestFilterMethodFabric<Data, Type>
        implements FilterMethodFabricable<Data, Type> {

    /*
     * Wenn Java 16 da ist und das nicht mehr experimentell ist,
     *     @SuppressWarnings("preview")
     * und ggf. notwendige Einstellungen am Jarify-Projekt zurücknehmen!
     *
     * https://nipafx.dev/enable-preview-language-features/
     *
     *     javac --enable-preview
     *
     * Muss vielleicht in Jarify als Option ans Projekt und beim kompilieren dann gesetzt werden.
     *
     * Auch beim laufen offenbar:
     *
     *     java --enable-preview
     *
     * Alternativ verzichte ich darauf und caste hier hässlich herum. DAS ist aber auch sehr
     * unschön.
     */

    /**
     * Eigentliche Fabrikmethode für die einfachen Filter.
     *
     * @param type
     *            Typ des Filters.
     * @return Filtermethode.
     * @throws FilterException
     *             Falls der Typ des Filters unbekannt oder kein einfacher Filtertyp ist.
     */
    @Override
    public Method<Data> buildMethod(Type type) {
        TestFilterType filterType = new GenericType2Concrete<Type>().generic2Concrete(type);
        return buildMethod(filterType);
    }

    private Method<Data> buildMethod(TestFilterType type) {
        switch (type) {
            case ALL:
                return new MethodAll<>();
            case ONE_CODE:
                return new TestMethodOneCode<>();
            case SHORT_TEXT:
                return new TestMethodShortText<>();
            case CRITICAL_CODES:
                return new TestMethodCriticalCodes<>();
            /*
            case NO_WORKING_CODE:
                return new MethodNoWorkingCode();
            case WORKING_CODE_ZERO:
                return new MethodWorkingCodeZero();
            case WORKING_CODE_ONE:
                return new MethodWorkingCodeOne();
            case WORKING_CODE_TWO:
                return new MethodWorkingCodeTwo();
            case WORKING_CODE_THREE:
                return new MethodWorkingCodeThree();
            case NO_CODES:
                return new MethodNoCodes();
            case ONE_CODE:
                return new MethodOneCode();
            case TWO_CODES:
                return new MethodTwoCodes();
            case THREE_CODES:
                return new MethodThreeCodes();
            case FOUR_CODES:
                return new MethodFourCodes();
            case FIVE_CODES:
                return new MethodFiveCodes();
            case SHORT_TEXT:
                return new MethodShortText();
            case FEW_HITS:
                return new MethodFewHits();
            case CRITICAL_CODES:
                return new MethodCriticalCodes(resourceManager);
            case ONE_UNKNOWN:
                return new MethodOneSentenceUnknown();
            case ONE_SHORT_UNKNOWN:
                return new MethodOneShortUnknown();
            case ENTRY_TYPE_CANDIDATES:
                return new MethodEntryTypeCandidates();
            */

            default:
                throw new FilterException("Falscher Filter-Methoden-Typ '" + type + "'.");
        }
    }

    /**
     * Fabrikmethode für die Filter mit Suchtext.
     *
     * @param type
     *            Typ des Filters.
     * @param searchForMe
     *            Der zu suchende Text.
     * @return Filtermethode.
     * @throws FilterException
     *             Falls der Typ des Filters unbekannt oder kein Filtertyp mit Eingabe ist.
     */
    @Override
    public Method<Data> buildInputMethod(Type type, String searchForMe) {
        TestFilterType filterType = new GenericType2Concrete<Type>().generic2Concrete(type);
        return buildInputMethod(filterType);
    }

    private Method<Data> buildInputMethod(TestFilterType type) {
        switch (type) {
            /*
            case WITH_TEXT:
                return new MethodWithText(searchForMe);
            case WITH_CODE:
                return new MethodWithCode(searchForMe);
            case DOKNR_STARTS_WITH:
                return new MethodWithDoknr(searchForMe, true);
            case DOKNR_ENDS_WITH:
                return new MethodWithDoknr(searchForMe, false);
            */

            default:
                throw new FilterException("Falscher Filter-Methoden-Typ '" + type + "'.");
        }
    }

}
