/*
 * Copyright (c) 2004-2017, by Alex Leigh.
 * All rights reserved.
 *
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE
 * The copyright notice above does not evidence any
 * actual or intended publication of such source code.
 */

package lc.mecha.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class VertiMap<V> {
    private final Map<String, V> data;

    public VertiMap(final Map<String, V> data) {
        this.data = data;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final VertiMap vertiMap = (VertiMap) o;

        return !(data != null ? !data.equals(vertiMap.data) : vertiMap.data != null);
    }

    @Override
    public int hashCode() {
        return data != null ? data.hashCode() : 0;
    }

    @Override
    public String toString() {
        return "VertiMap{" +
                "data=" + data +
                '}';
    }

    final ArrayList<String> find(final String pattern) {
        final ArrayList<String> output = new ArrayList<>();
        find(pattern, output);
        return output;
    }

    public final void find(final String pattern, final List<String> output) {
        final Pattern p = Pattern.compile(pattern);

        for (final String k : data.keySet()) {
            final Matcher m = p.matcher(k);
            if (m.matches())
                output.add(k);
        }
    }

    public final int count(final String pattern) {
        return find(pattern).size();
    }

    public final int sum(final String pattern) {
        int x = 0;

        for (final String key : find(pattern)) {
            final Integer z = (Integer) data.get(key);
            x += z;
        }

        return x;
    }

    public final int max(final String pattern) {
        boolean value = false;
        int x = 0;

        for (final String key : find(pattern)) {
            final Integer z = (Integer) data.get(key);
            if (!value) {
                value = true;
                x = z;
            } else {
                if (z > x)
                    x = z;
            }
        }
        return x;
    }

    public final int min(final String pattern) {
        boolean value = false;
        int x = 0;

        for (final String key : find(pattern)) {
            final Integer z = (Integer) data.get(key);
            if (!value) {
                value = true;
                x = z;
            } else {
                if (z < x)
                    x = z;
            }
        }
        return x;
    }
}