/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Oembedler Inc. and Contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 *  documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 *  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
 *  persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.embedler.moon.jtxt2img;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import sun.nio.ch.FileChannelImpl;

import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Pattern;

public enum CoreHelper {
    ;
    public static final String DEFAULT_CHARSET_NAME = "UTF-8";
    public static final Charset DEFAULT_CHARSET = Charset.forName(DEFAULT_CHARSET_NAME);
    public static final Locale DEFAULT_LOCALE = Locale.ENGLISH;
    public static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("GMT");

    public static final String SIZE_REGEXP_STR = "(\\d{1,5})(x)?(\\d{1,5})?(\\.(png|jpg|jpeg|gif))?";
    public static final Pattern SIZE_REGEXP = Pattern.compile(SIZE_REGEXP_STR);
    public static final String COLOR_REGEXP_STR = "([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})(\\.(png|jpg|jpeg|gif))?";
    public static final Pattern COLOR_REGEXP = Pattern.compile(COLOR_REGEXP_STR);

    public static final String DEF_PLACEHOLDER_FORMAT = "png";
    public static final String DEF_PLACEHOLDER_BGCOLOR = "ffffff";
    public static final String DEF_PLACEHOLDER_FGCOLOR = "000000";
    public static final Color DEF_PLACEHOLDER_BGCOLOR_PARSED = hex2Rgb(DEF_PLACEHOLDER_BGCOLOR);
    public static final Color DEF_PLACEHOLDER_FGCOLOR_PARSED = hex2Rgb(DEF_PLACEHOLDER_FGCOLOR);
    public static final Integer DEF_PLACEHOLDER_WIDTH = 300;
    public static final Integer DEF_PLACEHOLDER_HEIGHT = 250;
    public static final Integer DEF_PLACEHOLDER_MAX_WIDTH = 3500;
    public static final Integer DEF_PLACEHOLDER_MAX_HEIGHT = 3500;
    public static final Integer DEF_PLACEHOLDER_MIN_WIDTH = 1;
    public static final Integer DEF_PLACEHOLDER_MIN_HEIGHT = 1;

    public static final int DEF_PLACEHOLDER_FONT_SIZE = 700;
    public static final Font DEF_PLACEHOLDER_FONT = new Font("Courier New Bold", Font.BOLD, DEF_PLACEHOLDER_FONT_SIZE);

    public static Color hex2Rgb(String colorStr) {
        Validate.notBlank(colorStr, "Color string must not be null");
        String _color = StringUtils.rightPad(StringUtils.removeStart(colorStr, "#"), 6, colorStr.charAt(colorStr.length() - 1));
        return new Color(
                Integer.valueOf(_color.substring(0, 2), 16),
                Integer.valueOf(_color.substring(2, 4), 16),
                Integer.valueOf(_color.substring(4, 6), 16));
    }

    public static String rgb2hex(Color color) {
        Validate.notNull(color, "Color must not be null");
        return String.format("#%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue());
    }

    public static void fastChannelCopy(final InputStream src, final OutputStream dest) throws IOException {
        try (ReadableByteChannel inputChannel = Channels.newChannel(src);
             WritableByteChannel outputChannel = Channels.newChannel(dest)) {
            fastChannelCopy(inputChannel, outputChannel);
        }
    }

    public static void fastChannelCopy(final ReadableByteChannel src, final WritableByteChannel dest) throws IOException {
        final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
        while (src.read(buffer) != -1) {
            // prepare the buffer to be drained
            buffer.flip();
            // write to the channel, may block
            dest.write(buffer);
            // If partial transfer, shift remainder down
            // If buffer is empty, same as doing clear()
            buffer.compact();
        }
        // EOF will leave buffer in fill state
        buffer.flip();
        // make sure the buffer is fully drained.
        while (buffer.hasRemaining()) {
            dest.write(buffer);
        }
    }

    public static void unmap(final MappedByteBuffer buffer) {
        if (null == buffer) {
            return;
        }
        try {
            final Method method = FileChannelImpl.class.getDeclaredMethod("unmap", MappedByteBuffer.class);
            method.setAccessible(true);
            method.invoke(null, buffer);
        } catch (final Exception ex) {
            //fails silently
        }
    }

    public static Calendar getCalendar() {
        return Calendar.getInstance(DEFAULT_TIMEZONE);
    }

    public static String getCurrentMonth() {
        return new SimpleDateFormat("MMM").format(getCalendar().getTime());
    }

    public static Date getCurrentDate() {
        return getCalendar().getTime();
    }

    public static long getCurrentTime() {
        return getCalendar().getTimeInMillis();
    }

}

@@ -1273,899 +1273,90 @@
 te;%0A
-import sun.nio.ch.FileChannelImpl;%0A%0Aimport java.awt.*;%0Aimport java.io.IOException;%0Aimport java.io.InputStream;%0Aimport java.io.OutputStream;%0Aimport java.lang.reflect.Method;%0Aimport java.nio.ByteBuffer;%0Aimport java.nio.MappedByteBuffer;%0Aimport java.nio.channels.Channels;%0Aimport java.nio.channels.ReadableByteChannel;%0Aimport java.nio.channels.WritableByteChannel;%0Aimport java.nio.charset.Charset;%0Aimport java.text.SimpleDateFormat;%0Aimport java.util.Calendar;%0Aimport java.util.Date;%0Aimport java.util.Locale;%0Aimport java.util.TimeZone;%0Aimport java.util.regex.Pattern;%0A%0Apublic enum CoreHelper %7B%0A    ;%0A    public static final String DEFAULT_CHARSET_NAME = %22UTF-8%22;%0A    public static final Charset DEFAULT_CHARSET = Charset.forName(DEFAULT_CHARSET_NAME);%0A    public static final Locale DEFAULT_LOCALE = Locale.ENGLISH;%0A    public static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone(%22GMT%22)
+%0Aimport java.awt.*;%0Aimport java.util.regex.Pattern;%0A%0Apublic enum CoreHelper %7B%0A    
 ;%0A%0A 
@@ -3367,1924 +3367,6 @@
   %7D%0A
-%0A    public static void fastChannelCopy(final InputStream src, final OutputStream dest) throws IOException %7B%0A        try (ReadableByteChannel inputChannel = Channels.newChannel(src);%0A             WritableByteChannel outputChannel = Channels.newChannel(dest)) %7B%0A            fastChannelCopy(inputChannel, outputChannel);%0A        %7D%0A    %7D%0A%0A    public static void fastChannelCopy(final ReadableByteChannel src, final WritableByteChannel dest) throws IOException %7B%0A        final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);%0A        while (src.read(buffer) != -1) %7B%0A            // prepare the buffer to be drained%0A            buffer.flip();%0A            // write to the channel, may block%0A            dest.write(buffer);%0A            // If partial transfer, shift remainder down%0A            // If buffer is empty, same as doing clear()%0A            buffer.compact();%0A        %7D%0A        // EOF will leave buffer in fill state%0A        buffer.flip();%0A        // make sure the buffer is fully drained.%0A        while (buffer.hasRemaining()) %7B%0A            dest.write(buffer);%0A        %7D%0A    %7D%0A%0A    public static void unmap(final MappedByteBuffer buffer) %7B%0A        if (null == buffer) %7B%0A            return;%0A        %7D%0A        try %7B%0A            final Method method = FileChannelImpl.class.getDeclaredMethod(%22unmap%22, MappedByteBuffer.class);%0A            method.setAccessible(true);%0A            method.invoke(null, buffer);%0A        %7D catch (final Exception ex) %7B%0A            //fails silently%0A        %7D%0A    %7D%0A%0A    public static Calendar getCalendar() %7B%0A        return Calendar.getInstance(DEFAULT_TIMEZONE);%0A    %7D%0A%0A    public static String getCurrentMonth() %7B%0A        return new SimpleDateFormat(%22MMM%22).format(getCalendar().getTime());%0A    %7D%0A%0A    public static Date getCurrentDate() %7B%0A        return getCalendar().getTime();%0A    %7D%0A%0A    public static long getCurrentTime() %7B%0A        return getCalendar().getTimeInMillis();%0A    %7D%0A%0A
 %7D%0A

remove unused files