/**
 * ThisTime 2.0 (2008-03-30)
 * Copyright 2007 Zach Scrivena
 * zachscrivena@gmail.com
 * http://thistime.sourceforge.net/
 *
 * Simple clock and timer program.
 *
 * TERMS AND CONDITIONS:
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package thistime;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.AbstractListModel;


/**
 * List model that supports a "quick find" feature.
 */
class QuickFindListModel
        extends AbstractListModel
{
    /** timer refresh interval */
    private static final long TIMER_REFRESH_INTERVAL_MILLISECONDS = 200L;

    /** queue of "quick find" terms */
    private final Queue<String> quickFindTerms = new ArrayDeque<String>();

    /** timer for the "quick find" feature */
    private final Timer timer;

    /** master list of contents */
    private final String[] masterList;

    /** upper-case version of the master list of contents */
    private final String[] masterListUpperCase;

    /** active list of contents that satisfy the current "quick find" term */
    private final List<String> activeList;


    /**
    * Constructor.
    *
    * @param contents
    *      list contents
    */
    QuickFindListModel(
            final String[] contents)
    {
        /*********************
        * INITIALIZE FIELDS *
        *********************/

        masterList = contents;
        masterListUpperCase = new String[contents.length];
        activeList = new ArrayList<String>(contents.length);

        for (int i = 0; i < contents.length; i++)
        {
            masterListUpperCase[i] = masterList[i].toUpperCase();
            activeList.add(masterList[i]);
        }

        /***************************
        * INITIALIZE TIMER THREAD *
        ***************************/

        timer = new Timer("Quick-Find-List-Model-Timer", true);

        timer.schedule(new TimerTask()
        {
            /**
            * Refresh list contents for the given "quick find" term.
            */
            @Override
            public void run()
            {
                String term;

                synchronized (quickFindTerms)
                {
                    term = quickFindTerms.poll();
                }

                if (term == null)
                {
                    return;
                }

                /* shortlist contents that contain the specified term */
                int activeContentsSize;
                term = term.toUpperCase();

                synchronized (activeList)
                {
                    activeList.clear();

                    for (int i = 0; i < masterList.length; i++)
                    {
                        if (masterListUpperCase[i].contains(term))
                        {
                            activeList.add(masterList[i]);
                        }
                    }

                    activeContentsSize = activeList.size();
                }

                /* refresh the list, if this is the latest "quick find" term */
                final boolean refreshList;

                synchronized (quickFindTerms)
                {
                    refreshList = quickFindTerms.isEmpty();
                }

                if (refreshList)
                {
                    fireContentsChanged(QuickFindListModel.this, 0, activeContentsSize - 1);
                }
            }
        }, 0L, QuickFindListModel.TIMER_REFRESH_INTERVAL_MILLISECONDS);
    }


    /**
    * Refresh list contents with the specified "quick find" term.
    *
    * @param term
    *      "quick find" term
    */
    void quickFind(
            final String term)
    {
        synchronized (quickFindTerms)
        {
            quickFindTerms.clear();
            quickFindTerms.add(term);
        }
    }


    public int getSize()
    {
        synchronized (activeList)
        {
            return activeList.size();
        }
    }


    public Object getElementAt(
            int index)
    {
        synchronized (activeList)
        {
            if ((index >= 0) && (index < activeList.size()))
            {
                return activeList.get(index);
            }
            else
            {
                return null;
            }
        }
    }
}