/* FichothequeLib_API - Copyright (c) 2007-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.fichotheque.utils;

import net.fichotheque.Subset;
import net.fichotheque.corpus.fiche.AmountItem;
import net.fichotheque.corpus.fiche.Code;
import net.fichotheque.corpus.fiche.CountryItem;
import net.fichotheque.corpus.fiche.DateItem;
import net.fichotheque.corpus.fiche.Div;
import net.fichotheque.corpus.fiche.EmailItem;
import net.fichotheque.corpus.fiche.FicheBlock;
import net.fichotheque.corpus.fiche.FicheBlocks;
import net.fichotheque.corpus.fiche.FicheItem;
import net.fichotheque.corpus.fiche.FicheItems;
import net.fichotheque.corpus.fiche.GeopointItem;
import net.fichotheque.corpus.fiche.ImageItem;
import net.fichotheque.corpus.fiche.Item;
import net.fichotheque.corpus.fiche.LanguageItem;
import net.fichotheque.corpus.fiche.Li;
import net.fichotheque.corpus.fiche.LinkItem;
import net.fichotheque.corpus.fiche.Ln;
import net.fichotheque.corpus.fiche.NumberItem;
import net.fichotheque.corpus.fiche.P;
import net.fichotheque.corpus.fiche.ParaItem;
import net.fichotheque.corpus.fiche.PersonItem;
import net.fichotheque.corpus.fiche.S;
import net.fichotheque.corpus.fiche.Table;
import net.fichotheque.corpus.fiche.Td;
import net.fichotheque.corpus.fiche.TextContent;
import net.fichotheque.corpus.fiche.Tr;
import net.fichotheque.corpus.fiche.Ul;
import net.fichotheque.corpus.fiche.ZoneBlock;
import net.fichotheque.corpus.metadata.CorpusField;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.pointeurs.FichePointeur;
import net.fichotheque.pointeurs.SubsetItemPointeur;
import net.fichotheque.selection.SelectionContext;
import net.fichotheque.sphere.Redacteur;
import net.mapeadores.util.conditions.TextTestEngine;
import net.mapeadores.util.models.EmailCore;
import net.mapeadores.util.models.PersonCore;


/**
 *
 * @author Vincent Calame
 */
public final class PointeurUtils {

    private PointeurUtils() {
    }

    public static SubsetItemPointeur checkMasterPointeur(FichePointeur fichePointeur, boolean master) {
        if (master) {
            Subset masterSubset = fichePointeur.getCorpus().getMasterSubset();
            if (masterSubset != null) {
                return fichePointeur.getParentagePointeur(masterSubset.getSubsetKey());
            } else {
                return fichePointeur;
            }
        } else {
            return fichePointeur;
        }
    }

    public static void testContent(SelectionContext selectionContext, TextTestEngine textTestEngine, Object obj) {
        if (obj instanceof Integer) {
            textTestEngine.addString(obj.toString());
        } else if (obj instanceof String) {
            textTestEngine.addString(obj.toString());
        } else if (obj instanceof FicheItem) {
            testFicheItemContent(selectionContext, textTestEngine, (FicheItem) obj);
        } else if (obj instanceof FicheItems) {
            for (FicheItem ficheItem : (FicheItems) obj) {
                testFicheItemContent(selectionContext, textTestEngine, ficheItem);
                if (textTestEngine.canStop()) {
                    return;
                }
            }
        } else if (obj instanceof FicheBlocks) {
            testFicheBlocksContent(textTestEngine, (FicheBlocks) obj);
        }
    }

    public static void testFicheBlocksContent(TextTestEngine contentSelector, FicheBlocks ficheBlocks) {
        for (FicheBlock ficheBlock : ficheBlocks) {
            if (ficheBlock instanceof TextContent) {
                contentSelector.addString(toRawString((TextContent) ficheBlock));
            } else if (ficheBlock instanceof Ul) {
                for (Li li : (Ul) ficheBlock) {
                    testFicheBlocksContent(contentSelector, li);
                    if (contentSelector.canStop()) {
                        return;
                    }
                }
            } else if (ficheBlock instanceof ZoneBlock) {
                ZoneBlock zoneBlock = (ZoneBlock) ficheBlock;
                TextContent numero = zoneBlock.getNumero();
                if (!numero.isEmpty()) {
                    contentSelector.addString(toRawString(numero));
                    if (contentSelector.canStop()) {
                        return;
                    }
                }
                TextContent legende = zoneBlock.getLegende();
                if (!legende.isEmpty()) {
                    contentSelector.addString(toRawString(legende));
                    if (contentSelector.canStop()) {
                        return;
                    }
                }
                if (zoneBlock instanceof Code) {
                    for (Ln ln : (Code) zoneBlock) {
                        contentSelector.addString(toRawString(ln));
                        if (contentSelector.canStop()) {
                            return;
                        }
                    }
                } else if (zoneBlock instanceof Div) {
                    testFicheBlocksContent(contentSelector, ((Div) zoneBlock));
                } else if (zoneBlock instanceof Table) {
                    for (Tr tr : (Table) zoneBlock) {
                        for (Td td : tr) {
                            contentSelector.addString(toRawString(td));
                            if (contentSelector.canStop()) {
                                return;
                            }
                        }
                    }
                }
            }
            if (contentSelector.canStop()) {
                return;
            }
        }
    }

    public static void testFicheItemContent(SelectionContext selectionContext, TextTestEngine textTestEngine, FicheItem ficheItem) {
        if (ficheItem instanceof Item) {
            textTestEngine.addString(((Item) ficheItem).getValue());
            return;
        }
        if (ficheItem instanceof ParaItem) {
            textTestEngine.addString(((ParaItem) ficheItem).contentToString());
            return;
        }
        if (ficheItem instanceof CountryItem) {
            CountryItem countryItem = (CountryItem) ficheItem;
            textTestEngine.addString(countryItem.getCountry().toString());
            if (textTestEngine.canStop()) {
                return;
            }
            String message = selectionContext.getMessageLocalisationProvider().getMessageLocalisation(textTestEngine.getLang()).toString(countryItem.getCountry().toString());
            if (message != null) {
                textTestEngine.addString(message);
            }
            return;
        }
        if (ficheItem instanceof EmailItem) {
            EmailItem emailItem = (EmailItem) ficheItem;
            EmailCore emailCore = emailItem.getEmailCore();
            textTestEngine.addString(emailCore.getAddrSpec());
            if (textTestEngine.canStop()) {
                return;
            }
            String realName = emailCore.getRealName();
            if (realName.length() > 0) {
                textTestEngine.addString(realName);
            }
            return;
        }
        if (ficheItem instanceof LanguageItem) {
            LanguageItem languageItem = (LanguageItem) ficheItem;
            String code = languageItem.getLang().toString();
            textTestEngine.addString(code);
            if (textTestEngine.canStop()) {
                return;
            }
            String message = selectionContext.getMessageLocalisationProvider().getMessageLocalisation(textTestEngine.getLang()).toString(code);
            if (message != null) {
                textTestEngine.addString(message);
            }
            return;
        }
        if (ficheItem instanceof GeopointItem) {
            GeopointItem geopoint = (GeopointItem) ficheItem;
            textTestEngine.addString(geopoint.getLatitude().toString());
            if (textTestEngine.canStop()) {
                return;
            }
            textTestEngine.addString(geopoint.getLongitude().toString());
            return;
        }
        if (ficheItem instanceof AmountItem) {
            AmountItem amountItem = (AmountItem) ficheItem;
            textTestEngine.addString(amountItem.getDecimal().toString());
            if (textTestEngine.canStop()) {
                return;
            }
            textTestEngine.addString(amountItem.getCurrency().getCurrencyCode());
            return;
        }
        if (ficheItem instanceof PersonItem) {
            PersonItem personItem = (PersonItem) ficheItem;
            String userGlobalId = personItem.getRedacteurGlobalId();
            if (userGlobalId != null) {
                Redacteur redacteur = selectionContext.getFichothequeQuestioner().getRedacteurByGlobalId(userGlobalId);
                if (redacteur != null) {
                    textTestEngine.addString(redacteur.getBracketStyle());
                }
            } else {
                PersonCore personCore = personItem.getPersonCore();
                String surname = personCore.getSurname();
                if (surname.length() > 0) {
                    textTestEngine.addString(surname);
                    if (textTestEngine.canStop()) {
                        return;
                    }
                }
                String forename = personCore.getForename();
                if (forename.length() > 0) {
                    textTestEngine.addString(forename);
                    if (textTestEngine.canStop()) {
                        return;
                    }
                }
                String nonlatin = personCore.getNonlatin();
                if (nonlatin.length() > 0) {
                    textTestEngine.addString(nonlatin);
                    if (textTestEngine.canStop()) {
                        return;
                    }
                }
                String organism = personItem.getOrganism();
                if ((organism != null) && (organism.length() > 0)) {
                    textTestEngine.addString(organism);
                }
            }
            return;
        }
        if (ficheItem instanceof LinkItem) {
            LinkItem link = (LinkItem) ficheItem;
            String href = link.getHref();
            if (href.length() > 0) {
                textTestEngine.addString(href);
                if (textTestEngine.canStop()) {
                    return;
                }
            }
            String title = link.getTitle();
            if (title.length() > 0) {
                textTestEngine.addString(title);
                if (textTestEngine.canStop()) {
                    return;
                }
            }
            String comment = link.getComment();
            if (comment.length() > 0) {
                textTestEngine.addString(comment);
            }
            return;
        }
        if (ficheItem instanceof ImageItem) {
            ImageItem image = (ImageItem) ficheItem;
            String src = image.getSrc();
            if (src.length() > 0) {
                textTestEngine.addString(src);
                if (textTestEngine.canStop()) {
                    return;
                }
            }
            String alt = image.getAlt();
            if (alt.length() > 0) {
                textTestEngine.addString(alt);
                if (textTestEngine.canStop()) {
                    return;
                }
            }
            String title = image.getTitle();
            if (title.length() > 0) {
                textTestEngine.addString(title);
            }
            return;
        }
        if (ficheItem instanceof DateItem) {
            textTestEngine.addString(((DateItem) ficheItem).getDate().toString());
            return;
        }
        if (ficheItem instanceof NumberItem) {
            textTestEngine.addString(((NumberItem) ficheItem).getDecimal().toString());
            return;
        }
    }

    public static DateItem getDate(FichePointeur fichePointeur, CorpusField corpusField) {
        return getDate(fichePointeur, corpusField.getFieldKey());
    }

    public static DateItem getDate(FichePointeur fichePointeur, FieldKey fieldKey) {
        Object obj = fichePointeur.getValue(fieldKey);
        if (obj == null) {
            return null;
        }
        if (!(obj instanceof DateItem)) {
            return null;
        }
        return (DateItem) obj;
    }

    public static AmountItem getAmount(FichePointeur fichePointeur, CorpusField corpusField) {
        return getAmount(fichePointeur, corpusField.getFieldKey());
    }

    public static AmountItem getAmount(FichePointeur fichePointeur, FieldKey fieldKey) {
        Object obj = fichePointeur.getValue(fieldKey);
        if (obj == null) {
            return null;
        }
        if (!(obj instanceof AmountItem)) {
            return null;
        }
        return (AmountItem) obj;
    }

    public static NumberItem getNumber(FichePointeur fichePointeur, CorpusField corpusField) {
        return getNumber(fichePointeur, corpusField.getFieldKey());
    }

    public static NumberItem getNumber(FichePointeur fichePointeur, FieldKey fieldKey) {
        Object obj = fichePointeur.getValue(fieldKey);
        if (obj == null) {
            return null;
        }
        if (!(obj instanceof NumberItem)) {
            return null;
        }
        return (NumberItem) obj;
    }

    public static String toRawString(TextContent textContent) {
        StringBuilder buf = new StringBuilder();
        if (textContent instanceof P) {
            String source = ((P) textContent).getSource();
            if (source.length() > 0) {
                buf.append(source);
                buf.append(" : ");
            }
        }
        int size = textContent.size();
        for (int i = 0; i < size; i++) {
            Object obj = textContent.get(i);
            if (obj instanceof String) {
                buf.append((String) obj);
            } else if (obj instanceof S) {
                S s = (S) obj;
                buf.append(s.getValue());
            }
        }
        return buf.toString();
    }

}
