/* FichothequeLib_API - Copyright (c) 2010-2022 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 java.io.File;
import java.text.ParseException;
import java.util.AbstractList;
import java.util.List;
import java.util.RandomAccess;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import net.fichotheque.album.AlbumConstants;
import net.fichotheque.album.Illustration;
import net.fichotheque.album.metadata.AlbumDim;
import net.mapeadores.util.exceptions.ShouldNotOccurException;


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

    private final static Pattern ALBUMDIMNAME_PATTERN;
    private final static Pattern IMAGENAME_PATTERN;

    static {
        try {
            ALBUMDIMNAME_PATTERN = Pattern.compile("^[a-z][a-z0-9_]*$");
            IMAGENAME_PATTERN = Pattern.compile("^[-_a-zA-Z0-9.]+$");
        } catch (PatternSyntaxException pse) {
            throw new ShouldNotOccurException(pse);
        }
    }

    private AlbumUtils() {
    }

    public static short formatTypeToShort(String typeString) {
        typeString = typeString.toLowerCase();
        switch (typeString) {
            case "png":
                return AlbumConstants.PNG_FORMATTYPE;
            case "jpg":
            case "jpeg":
                return AlbumConstants.JPG_FORMATTYPE;
            default:
                throw new IllegalArgumentException();
        }
    }

    public static String formatTypeToString(short type) {
        switch (type) {
            case AlbumConstants.PNG_FORMATTYPE:
                return "png";
            case AlbumConstants.JPG_FORMATTYPE:
                return "jpg";
            default:
                throw new IllegalArgumentException("unknown type " + type);
        }
    }


    public static String checkDimType(String dimType) {
        switch (dimType) {
            case AlbumConstants.FIXEDWIDTH_DIMTYPE:
            case AlbumConstants.FIXEDHEIGHT_DIMTYPE:
            case AlbumConstants.MAXWIDTH_DIMTYPE:
            case AlbumConstants.MAXHEIGHT_DIMTYPE:
            case AlbumConstants.MAXDIM_DIMTYPE:
                return dimType;
            default:
                throw new IllegalArgumentException("unknown type " + dimType);
        }
    }

    public static String getMimeType(short type) {
        switch (type) {
            case AlbumConstants.PNG_FORMATTYPE:
                return "image/png";
            case AlbumConstants.JPG_FORMATTYPE:
                return "image/jpeg";
            default:
                throw new IllegalArgumentException("unknown type " + type);
        }
    }

    public static boolean isValidImageType(short type) {
        switch (type) {
            case AlbumConstants.PNG_FORMATTYPE:
            case AlbumConstants.JPG_FORMATTYPE:
                return true;
            default:
                return false;
        }
    }


    public static boolean needWidth(String dimType) {
        switch (dimType) {
            case AlbumConstants.FIXEDWIDTH_DIMTYPE:
            case AlbumConstants.MAXWIDTH_DIMTYPE:
            case AlbumConstants.MAXDIM_DIMTYPE:
                return true;
            default:
                return false;
        }
    }

    public static boolean needHeight(String dimType) {
        switch (dimType) {
            case AlbumConstants.FIXEDHEIGHT_DIMTYPE:
            case AlbumConstants.MAXHEIGHT_DIMTYPE:
            case AlbumConstants.MAXDIM_DIMTYPE:
                return true;
            default:
                return false;
        }
    }

    public static boolean isValidImageName(String s) {
        Matcher matcher = IMAGENAME_PATTERN.matcher(s);
        return matcher.matches();
    }

    public static void testAlbumDimName(String albumDimName) throws ParseException {
        Matcher matcher = ALBUMDIMNAME_PATTERN.matcher(albumDimName);
        if (!matcher.matches()) {
            throw new ParseException(albumDimName, 0);
        }
    }

    public static boolean isValidAlbumDimName(String albumDimName) {
        Matcher matcher = ALBUMDIMNAME_PATTERN.matcher(albumDimName);
        return matcher.matches();
    }

    public static String specialDimToString(short specialDim) {
        switch (specialDim) {
            case AlbumConstants.ORIGINAL_SPECIALDIM:
                return AlbumConstants.ORIGINAL_DIMNAME;
            case AlbumConstants.MINI_SPECIALDIM:
                return AlbumConstants.MINI_DIMNAME;
            default:
                throw new IllegalArgumentException("Unknown specialDim : " + specialDim);
        }
    }

    public static List<AlbumDim> wrap(AlbumDim[] array) {
        return new AlbumDimList(array);
    }

    public static List<Illustration> wrap(Illustration[] array) {
        return new IllustrationList(array);
    }

    public static String getExtension(File file) {
        return getExtension(file.getName());
    }

    public static String getExtension(String fileName) {
        int idx = fileName.lastIndexOf('.');
        return fileName.substring(idx + 1);
    }

    public static String checkExtension(String fileName) {
        int idx = fileName.lastIndexOf(".");
        if (idx == -1) {
            return null;
        }
        String extension = fileName.substring(idx + 1).toLowerCase();
        switch (extension) {
            case "png":
            case "bmp":
            case "gif":
                return extension;
            case "jpeg":
            case "jpg":
                return "jpg";
            default:
                return null;
        }
    }

    public static boolean isPngConvertible(String extension) {
        switch (extension) {
            case "gif":
            case "bmp":
                return true;
            default:
                return false;
        }
    }


    private static class IllustrationList extends AbstractList<Illustration> implements RandomAccess {

        private final Illustration[] array;

        private IllustrationList(Illustration[] array) {
            this.array = array;
        }

        @Override
        public int size() {
            return array.length;
        }

        @Override
        public Illustration get(int index) {
            return array[index];
        }

    }


    private static class AlbumDimList extends AbstractList<AlbumDim> implements RandomAccess {

        private final AlbumDim[] array;

        private AlbumDimList(AlbumDim[] array) {
            this.array = array;
        }

        @Override
        public int size() {
            return array.length;
        }

        @Override
        public AlbumDim get(int index) {
            return array[index];
        }

    }

}
