package org.fenixedu.a3es.domain;

import java.util.Locale;
import java.util.Objects;

import org.fenixedu.academic.domain.CurricularCourse;
import org.fenixedu.bennu.core.util.CoreConfiguration;
import org.fenixedu.commons.i18n.LocalizedString;

import com.google.common.base.Strings;

public class CurricularUnitFile extends CurricularUnitFile_Base {

    protected CurricularUnitFile(DegreeFile degreeFile, CurricularCourse curricularCourse, LocalizedString curricularUnitName) {
        Objects.requireNonNull(degreeFile);
        Objects.requireNonNull(curricularUnitName);
        setDegreeFile(degreeFile);
        setCurricularCourse(curricularCourse);
        setFileName(curricularUnitName.getContent(Locale.forLanguageTag(CoreConfiguration.getConfiguration().defaultLocale())));
        setCurricularUnitName(curricularUnitName);
    }

    public static CurricularUnitFile create(DegreeFile degreeFile, CurricularCourse curricularCourse, LocalizedString curricularUnitName) {
        return new CurricularUnitFile(degreeFile, curricularCourse, curricularUnitName);
    }

    public void edit(String scientificArea, String courseRegime, String workingHours, String contactHours, String ects,
            LocalizedString observations, String responsibleTeacherAndTeachingHours, String otherTeachersAndTeachingHours,
            LocalizedString learningOutcomes, LocalizedString syllabus, LocalizedString syllabusDemonstration,
            LocalizedString teachingMethodologies, LocalizedString teachingMethodologiesDemonstration,
            String bibliographicReferences) {
        setScientificArea(scientificArea);
        setCourseRegime(courseRegime);
        setWorkingHours(workingHours);
        setContactHours(contactHours);
        setEcts(ects);
        setObservations(observations);
        setResponsibleTeacherAndTeachingHours(responsibleTeacherAndTeachingHours);
        setOtherTeachersAndTeachingHours(otherTeachersAndTeachingHours);
        setLearningOutcomes(learningOutcomes);
        setSyllabus(syllabus);
        setSyllabusDemonstration(syllabusDemonstration);
        setTeachingMethodologies(teachingMethodologies);
        setTeachingMethodologiesDemonstration(teachingMethodologiesDemonstration);
        setBibliographicReferences(bibliographicReferences);
    }

    @Override
    public LocalizedString getCurricularUnitName() {
        return super.getCurricularUnitName();
    }

    @Override
    public String getScientificArea() {
        return super.getScientificArea();
    }

    @Override
    public String getCourseRegime() {
        return super.getCourseRegime();
    }

    @Override
    public String getWorkingHours() {
        return super.getWorkingHours();
    }

    @Override
    public String getContactHours() {
        return super.getContactHours();
    }

    @Override
    public String getEcts() {
        return super.getEcts();
    }

    @Override
    public LocalizedString getObservations() {
        return super.getObservations();
    }

    @Override
    public String getResponsibleTeacherAndTeachingHours() {
        return super.getResponsibleTeacherAndTeachingHours();
    }

    @Override
    public String getOtherTeachersAndTeachingHours() {
        return super.getOtherTeachersAndTeachingHours();
    }

    @Override
    public LocalizedString getLearningOutcomes() {
        return super.getLearningOutcomes();
    }

    @Override
    public LocalizedString getSyllabus() {
        return super.getSyllabus();
    }

    @Override
    public LocalizedString getSyllabusDemonstration() {
        return super.getSyllabusDemonstration();
    }

    @Override
    public LocalizedString getTeachingMethodologies() {
        return super.getTeachingMethodologies();
    }

    @Override
    public LocalizedString getTeachingMethodologiesDemonstration() {
        return super.getTeachingMethodologiesDemonstration();
    }

    @Override
    public String getBibliographicReferences() {
        return super.getBibliographicReferences();
    }

    public void delete() {
        getTeacherFileSet().forEach(tf -> tf.removeCurricularUnitFile(this));
        setDegreeFile(null);
        setResponsibleGroup(null);
        setCurricularCourse(null);
        super.deleteDomainObject();
    }

    @Override
    public AccreditationProcess getAccreditationProcess() {
        return getDegreeFile().getAccreditationProcess();
    }

    public boolean isFilledAndValid() {
        return !Strings.isNullOrEmpty(getResponsibleTeacherAndTeachingHours()) && !isFilledForAllLanguages(getLearningOutcomes())
                && !isFilledForAllLanguages(getSyllabus()) && !isFilledForAllLanguages(getSyllabusDemonstration())
                && !isFilledForAllLanguages(getTeachingMethodologies())
                && !isFilledForAllLanguages(getTeachingMethodologiesDemonstration())
                && !Strings.isNullOrEmpty(getBibliographicReferences())
                && hasValidSize(getResponsibleTeacherAndTeachingHours(), 100) && hasValidSize(getLearningOutcomes(), 1000)
                && hasValidSize(getSyllabus(), 1000) && hasValidSize(getSyllabusDemonstration(), 1000)
                && hasValidSize(getTeachingMethodologies(), 1000) && hasValidSize(getTeachingMethodologiesDemonstration(), 3000)
                && hasValidSize(getBibliographicReferences(), 1000);
    }

    private boolean isFilledForAllLanguages(LocalizedString localizedString) {
        if (localizedString != null) {
            for (Locale locale : CoreConfiguration.supportedLocales()) {
                if (Strings.isNullOrEmpty(localizedString.getContent(locale))) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean isUserAllowedToView() {
        return super.isUserAllowedToView() || getDegreeFile().isUserAllowedToView();
    }
}

@@ -134,16 +134,127 @@
 Course;%0A
+import org.fenixedu.academic.domain.degreeStructure.DegreeModule;%0Aimport org.fenixedu.bennu.core.domain.Bennu;%0A
 import o
@@ -351,16 +351,75 @@
 tring;%0A%0A
+import pt.ist.fenixframework.dml.runtime.RelationAdapter;%0A%0A
 import c
@@ -517,16 +517,544 @@
 Base %7B%0A%0A
+    public static class CurricularCourseListener extends RelationAdapter%3CBennu, DegreeModule%3E %7B%0A%0A        @Override%0A        public void beforeRemove(final Bennu bennu, final DegreeModule degreeModule) %7B%0A            if (bennu != null && degreeModule instanceof CurricularCourse) %7B%0A                ((CurricularCourse) degreeModule).getCurricularUnitFileSet().clear();%0A            %7D%0A        %7D%0A    %7D%0A%0A    static %7B%0A        CurricularCourse.getRelationRootDomainObjectDegreeModule().addListener(new CurricularCourseListener());%0A    %7D%0A%0A
     prot
@@ -1632,32 +1632,44 @@
 urricularCourse,
+%0A           
  LocalizedString

Remove curricularUnitFiles when deleting curricularUnit