/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in 
 * compliance with the License.  You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is Protege-2000.
 *
 * The Initial Developer of the Original Code is Stanford University. Portions
 * created by Stanford University are Copyright (C) 2007.  All Rights Reserved.
 *
 * Protege was developed by Stanford Medical Informatics
 * (http://www.smi.stanford.edu) at the Stanford University School of Medicine
 * with support from the National Library of Medicine, the National Science
 * Foundation, and the Defense Advanced Research Projects Agency.  Current
 * information about Protege can be obtained at http://protege.stanford.edu.
 *
 */

package edu.stanford.smi.protegex.util;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import edu.stanford.smi.protege.model.Frame;
import edu.stanford.smi.protege.resource.Icons;
import edu.stanford.smi.protege.ui.Finder;
import edu.stanford.smi.protege.util.FrameWithBrowserText;
import edu.stanford.smi.protege.util.LabeledComponent;
import edu.stanford.smi.protege.util.Log;
import edu.stanford.smi.protege.util.SelectableList;
import edu.stanford.smi.protege.util.SimpleStringMatcher;
import edu.stanford.smi.protege.util.StringMatcher;

public class PagedFrameList extends LabeledComponent {
    private static final long serialVersionUID = 8889044179950621525L;
    private static final transient Logger log = Log.getLogger(PagedFrameList.class);
    
    private int pageSize = 50;
    private List<FrameWithBrowserText> allFrames;
    private int pageLocation;
    private SelectableList framesList;
    private JButton scrollBack;
    private JButton scrollForward;
    
    public PagedFrameList(String title) {
        super(title, new JScrollPane());
        JScrollPane scrollable = (JScrollPane) getCenterComponent();
        framesList = new SelectableList() {
            @Override
            public Collection getSelection() {
                // TODO Auto-generated method stub
                return super.getSelection();
            }
        };
        scrollable.setViewportView(framesList);
        setFooterComponent(makeFooter());
    }
    
    private JComponent makeFooter() {
        JPanel footer = new JPanel();
        footer.setLayout(new BoxLayout(footer, BoxLayout.X_AXIS));
        scrollBack = new JButton(Icons.getBackIcon());
        scrollBack.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                setPageLocation(pageLocation - pageSize);
            }
            
        });
        scrollBack.setEnabled(false);
        footer.add(scrollBack);
        
        footer.add(new Finder("Find") {
            @Override
            protected int getBestMatch(List matches, String text) {
                return 0;
            }
            
            @Override
            protected List<Frame> getMatches(String text, int maxMatches) {
                StringMatcher matcher = new SimpleStringMatcher("*" + text + "*");
                int counter = 0;
                List<Frame> results = new ArrayList<Frame>(); 
                for (FrameWithBrowserText frame : allFrames) {
                    if (matcher.isMatch(frame.getBrowserText())) {
                        results.add(frame.getFrame());
                        if (maxMatches > 0 && ++counter >= maxMatches) {
                            return results;
                        }
                    }
                }
                return results;
            }
            
            @Override
            protected void select(Object o) {
                int i = 0;
                for (FrameWithBrowserText frame : allFrames) {
                    if (frame.getFrame().equals(o)) {
                        break;
                    }
                    i++;
                }
                if (i < allFrames.size()) {
                    setPageLocation(i);
                    int selection = i - pageLocation;
                    framesList.setSelectedIndex(selection);
                }
            }
        });
        
        scrollForward = new JButton(Icons.getForwardIcon());
        scrollForward.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent e) {
               setPageLocation(pageLocation + pageSize);
            } 
        });
        scrollForward.setEnabled(false);
        footer.add(scrollForward);
        
        return footer;
    }
    
    public void setPageLocation(int pageLocation) {
        if (pageLocation < 0) {
            pageLocation = 0;
        }
        else if (pageSize >= allFrames.size()) {
            pageLocation = 0;
        }
        else if (pageLocation >= allFrames.size()) {
            pageLocation = allFrames.size() - pageSize + 1;
        }
        this.pageLocation = pageLocation;
        
        int startOfNextPage = pageLocation + pageSize;
        if (startOfNextPage >= allFrames.size()) {
            startOfNextPage = allFrames.size();
        }
        List<FrameWithBrowserText> frames = allFrames.subList(pageLocation, startOfNextPage);
        framesList.setListData(frames.toArray());
        scrollForward.setEnabled(pageLocation + pageSize < allFrames.size());
        scrollBack.setEnabled(pageLocation > 0);
    }
    
    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
        setPageLocation(pageLocation);
    }

    public List<FrameWithBrowserText> getAllFrames() {
        return allFrames;
    }

    public void setAllFrames(List<FrameWithBrowserText> allFrames) {
        this.allFrames = allFrames;
        setPageLocation(0);
    }
    
    public SelectableList getSelectableList() {
        return framesList;
    }


    
}
