package fanch.multijeu.findwords.data;

import java.util.ArrayList;

import fanch.multijeu.common.core.Word;

public class WordSet extends ArrayList<WordPair>  {


    protected int m_found=0;


    public WordSet()
    {

    }

    public WordSet(ArrayList<Word> res)
    {
        for(int i=0; i<res.size(); i++)
            add(res.get(i));
    }

    public WordSet(Word[] res)
    {
        for(int i=0; i<res.length; i++)
            add(res[i]);
    }

    public WordSet(ArrayList<Word> res, int min)
    {
        for(int i=0; i<res.size(); i++)
        {
            Word s = res.get(i);
            if(s.length()>=min)
                add(s);
        }
    }

    public WordSet(ArrayList<Word> res, int min, int max)
    {
        for (Word s : res)
        {
            if(s.length()>=min && s.length()<=max)
                add(s);
        }
    }

    public synchronized void setMin(int min)
    {
        for (int i=size()-1; i>=0; i--) {
            if(get(i).first.length()<min)
                remove(get(i));
        }
    }


    public synchronized void setMax(int max)
    {
        for (int i=size()-1; i>=0; i--) {
            if(get(i).first.length()>max)
                remove(get(i));
        }
    }

    public synchronized void setMinMax(int min, int max)
    {
        for (int i=size()-1; i>=0; i--) {
            if(get(i).first.length()>max || get(i).first.length()<min)
                remove(get(i));
        }
    }

    public synchronized boolean add(Word s)
    {
        if(contains(s)) return false;
        super.add(new WordPair(s, WordState.NOT_FOUND));
        return true;
    }

    public synchronized boolean add(Word s, WordState x)
    {
        if(contains(s)) return false;
        super.add(new WordPair(s, x));
        return true;
    }

    public synchronized boolean contains(Word s, boolean accentSensitive)
    {
        return getPair(s, accentSensitive)!=null;
    }

    protected synchronized boolean set(Word s, WordState value)
    {
        for (WordPair t : this) {
            if(t.first.equals(s)) {
                t = new WordPair(s, value);
                return true;
            }
        }
        return false;
    }

    public int countFound(){return m_found;}
    public int countNotFound(){return size()-m_found;}

    public synchronized WordState get(Word s, boolean accentSensitive)
    {
        WordPair p = getPair(s, accentSensitive);
        if(p!=null) return p.second;
        return WordState.ERROR;
    }

    public synchronized ArrayList<WordPair> getAll(Word s, boolean accentSensitive)
    {
        ArrayList<WordPair> p = new ArrayList<>();
        for (WordPair t : this) {
            if( t.first.equals(s, false, accentSensitive))
                p.add(t);
        }
        return p;
    }



    public synchronized boolean found(Word s, boolean accentSensitive)
    {
        WordPair p = getPair(s,  accentSensitive);
        if(p!=null)
        {
            if(p.second.equals(WordState.NOT_FOUND)) m_found++;
            p.second=WordState.FOUND;
            return true;
        }
        return false;
    }

    public synchronized ArrayList<String> keys()
    {
        ArrayList<String> out = new ArrayList<String>();
        for (WordPair t : this)
            out.add(t.first.toString());
        return out;
    }

    public synchronized ArrayList values()
    {
        ArrayList out = new ArrayList();
        for (WordPair t : this)
            out.add(t.second);
        return out;
    }


    public synchronized void exclude(WordSet toExclude)
    {
        for(WordPair t:toExclude)
            remove(t.first);
    }

    public synchronized void include(WordSet inc)
    {
        for(WordPair t:inc)
            add(t.first, t.second);
    }

    private synchronized void remove(Word s, boolean accentSensitive)
    {
        for (WordPair t : this) {
            if(t.first.equals(s, false, accentSensitive))
                remove(t);
        }
    }

    protected synchronized WordPair getPair(Word s, boolean accentSensitive)
    {
        for (WordPair t : this) {
            if( t.first.equals(s, false, accentSensitive))
                return t;
        }
        return null;
    }

    public String toString()
    {
        StringBuilder builder = new StringBuilder();
        builder.append("{");
        for(int i=0; i<size(); i++) {
            if(i>0)builder.append(", ");
            builder.append(get(i));
        }
        return builder.toString();
    }

}
