/*
 * Copyright 2011 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.client;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.gitblit.Constants;
import com.gitblit.models.FeedEntryModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.StringUtils;

/**
 * The search dialog allows searching of a repository branch. This matches the
 * search implementation of the site.
 *
 * @author James Moger
 *
 */
public class SearchDialog extends JFrame {

	private static final long serialVersionUID = 1L;

	private final boolean isSearch;

	private final GitblitClient gitblit;

	private FeedEntryTableModel tableModel;

	private HeaderPanel header;

	private JTable table;

	private JComboBox repositorySelector;

	private DefaultComboBoxModel branchChoices;

	private JComboBox branchSelector;

	private JComboBox searchTypeSelector;

	private JTextField searchFragment;

	private JComboBox maxHitsSelector;

	private int page;

	private JButton prev;

	private JButton next;

	public SearchDialog(GitblitClient gitblit, boolean isSearch) {
		super();
		this.gitblit = gitblit;
		this.isSearch = isSearch;
		setTitle(Translation.get(isSearch ? "gb.search" : "gb.log"));
		setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
		initialize();
		setSize(900, 550);
	}

	private void initialize() {

		prev = new JButton("<");
		prev.setToolTipText(Translation.get("gb.pagePrevious"));
		prev.setEnabled(false);
		prev.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				search(--page);
			}
		});

		next = new JButton(">");
		next.setToolTipText(Translation.get("gb.pageNext"));
		next.setEnabled(false);
		next.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				search(++page);
			}
		});

		final JButton search = new JButton(Translation.get(isSearch ? "gb.search" : "gb.refresh"));
		search.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				search(0);
			}
		});

		final JButton viewCommit = new JButton(Translation.get("gb.view"));
		viewCommit.setEnabled(false);
		viewCommit.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				viewCommit();
			}
		});

		final JButton viewCommitDiff = new JButton(Translation.get("gb.commitdiff"));
		viewCommitDiff.setEnabled(false);
		viewCommitDiff.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				viewCommitDiff();
			}
		});

		final JButton viewTree = new JButton(Translation.get("gb.tree"));
		viewTree.setEnabled(false);
		viewTree.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				viewTree();
			}
		});

		JPanel controls = new JPanel(new FlowLayout(FlowLayout.CENTER, Utils.MARGIN, 0));
		controls.add(viewCommit);
		controls.add(viewCommitDiff);
		controls.add(viewTree);

		NameRenderer nameRenderer = new NameRenderer();
		tableModel = new FeedEntryTableModel();
		header = new HeaderPanel(Translation.get(isSearch ? "gb.search" : "gb.log"),
				isSearch ? "search-icon.png" : "commit_changes_16x16.png");
		table = Utils.newTable(tableModel, Utils.DATE_FORMAT);

		String name = table.getColumnName(FeedEntryTableModel.Columns.Author.ordinal());
		table.getColumn(name).setCellRenderer(nameRenderer);
		name = table.getColumnName(FeedEntryTableModel.Columns.Repository.ordinal());
		table.getColumn(name).setCellRenderer(nameRenderer);

		name = table.getColumnName(FeedEntryTableModel.Columns.Branch.ordinal());
		table.getColumn(name).setCellRenderer(new BranchRenderer());

		name = table.getColumnName(FeedEntryTableModel.Columns.Message.ordinal());
		table.getColumn(name).setCellRenderer(new MessageRenderer());

		table.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() == 2) {
					if (e.isControlDown()) {
						viewCommitDiff();
					} else {
						viewCommit();
					}
				}
			}
		});

		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				if (e.getValueIsAdjusting()) {
					return;
				}
				boolean singleSelection = table.getSelectedRowCount() == 1;
				viewCommit.setEnabled(singleSelection);
				viewCommitDiff.setEnabled(singleSelection);
				viewTree.setEnabled(singleSelection);
			}
		});

		repositorySelector = new JComboBox(gitblit.getRepositories().toArray());
		repositorySelector.setRenderer(nameRenderer);
		repositorySelector.setForeground(nameRenderer.getForeground());
		repositorySelector.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent event) {
				// repopulate the branch list based on repository selection
				// preserve branch selection, if possible
				String selectedBranch = null;
				if (branchSelector.getSelectedIndex() > -1) {
					selectedBranch = branchSelector.getSelectedItem().toString();
				}
				updateBranches();
				if (StringUtils.isEmpty(selectedBranch)) {
					// do not select branch
					branchSelector.setSelectedIndex(-1);
				} else {
					if (branchChoices.getIndexOf(selectedBranch) > -1) {
						// select branch
						branchChoices.setSelectedItem(selectedBranch);
					} else {
						// branch does not exist, do not select branch
						branchSelector.setSelectedIndex(-1);
					}
				}
			}
		});

		branchChoices = new DefaultComboBoxModel();
		branchSelector = new JComboBox(branchChoices);
		branchSelector.setRenderer(new BranchRenderer());

		searchTypeSelector = new JComboBox(Constants.SearchType.values());
		searchTypeSelector.setSelectedItem(Constants.SearchType.COMMIT);

		maxHitsSelector = new JComboBox(new Integer[] { 25, 50, 75, 100 });
		maxHitsSelector.setSelectedIndex(0);

		searchFragment = new JTextField(25);
		searchFragment.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent event) {
				search(0);
			}
		});

		JPanel queryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, Utils.MARGIN, 0));
		queryPanel.add(new JLabel(Translation.get("gb.repository")));
		queryPanel.add(repositorySelector);
		queryPanel.add(new JLabel(Translation.get("gb.branch")));
		queryPanel.add(branchSelector);
		if (isSearch) {
			queryPanel.add(new JLabel(Translation.get("gb.type")));
			queryPanel.add(searchTypeSelector);
		}
		queryPanel.add(new JLabel(Translation.get("gb.maxHits")));
		queryPanel.add(maxHitsSelector);

		JPanel actionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, Utils.MARGIN, 0));
		actionsPanel.add(search);
		actionsPanel.add(prev);
		actionsPanel.add(next);

		JPanel northControls = new JPanel(new BorderLayout(Utils.MARGIN, Utils.MARGIN));
		northControls.add(queryPanel, BorderLayout.WEST);
		if (isSearch) {
			northControls.add(searchFragment, BorderLayout.CENTER);
		}
		northControls.add(actionsPanel, BorderLayout.EAST);

		JPanel northPanel = new JPanel(new BorderLayout(0, Utils.MARGIN));
		northPanel.add(header, BorderLayout.NORTH);
		northPanel.add(northControls, BorderLayout.CENTER);

		JPanel contentPanel = new JPanel() {

			private static final long serialVersionUID = 1L;

			@Override
			public Insets getInsets() {
				return Utils.INSETS;
			}
		};
		contentPanel.setLayout(new BorderLayout(Utils.MARGIN, Utils.MARGIN));
		contentPanel.add(northPanel, BorderLayout.NORTH);
		contentPanel.add(new JScrollPane(table), BorderLayout.CENTER);
		contentPanel.add(controls, BorderLayout.SOUTH);
		setLayout(new BorderLayout());
		add(contentPanel, BorderLayout.CENTER);
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowOpened(WindowEvent event) {
				if (isSearch) {
					searchFragment.requestFocus();
				} else {
					search(0);
				}
			}

			@Override
			public void windowActivated(WindowEvent event) {
				if (isSearch) {
					searchFragment.requestFocus();
				}
			}
		});
	}

	public void selectRepository(RepositoryModel repository) {
		repositorySelector.setSelectedItem(repository);
	}

	private void updateBranches() {
		String repository = null;
		if (repositorySelector.getSelectedIndex() > -1) {
			repository = repositorySelector.getSelectedItem().toString();
		}
		List<String> branches = gitblit.getBranches(repository);
		branchChoices.removeAllElements();
		for (String branch : branches) {
			branchChoices.addElement(branch);
		}
	}

	protected void search(final int page) {
		this.page = page;
		final String repository = repositorySelector.getSelectedItem().toString();
		final String branch = branchSelector.getSelectedIndex() > -1 ? branchSelector
				.getSelectedItem().toString() : null;
		final Constants.SearchType searchType = (Constants.SearchType) searchTypeSelector
				.getSelectedItem();
		final String fragment = isSearch ? searchFragment.getText() : null;
		final int maxEntryCount = maxHitsSelector.getSelectedIndex() > -1 ? ((Integer) maxHitsSelector
				.getSelectedItem()) : -1;

		if (isSearch && StringUtils.isEmpty(fragment)) {
			return;
		}
		setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
		SwingWorker<List<FeedEntryModel>, Void> worker = new SwingWorker<List<FeedEntryModel>, Void>() {
			@Override
			protected List<FeedEntryModel> doInBackground() throws IOException {
				if (isSearch) {
					return gitblit.search(repository, branch, fragment, searchType, maxEntryCount,
							page);
				} else {
					return gitblit.log(repository, branch, maxEntryCount, page);
				}
			}

			@Override
			protected void done() {
				setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
				try {
					List<FeedEntryModel> results = get();
					if (isSearch) {
						updateTable(true, fragment, results);
					} else {
						updateTable(true, branch == null ? "" : branch, results);
					}
				} catch (Throwable t) {
					Utils.showException(SearchDialog.this, t);
				}
			}
		};
		worker.execute();
	}

	protected void updateTable(boolean pack, String text, List<FeedEntryModel> entries) {
		tableModel.entries.clear();
		tableModel.entries.addAll(entries);
		tableModel.fireTableDataChanged();
		setTitle(Translation.get(isSearch ? "gb.search" : "gb.log")
				+ (StringUtils.isEmpty(text) ? "" : (": " + text)) + " (" + entries.size()
				+ (page > 0 ? (", pg " + (page + 1)) : "") + ")");
		header.setText(getTitle());
		if (pack) {
			Utils.packColumns(table, Utils.MARGIN);
		}
		table.scrollRectToVisible(new Rectangle(table.getCellRect(0, 0, true)));

		// update pagination buttons
		int maxHits = (Integer) maxHitsSelector.getSelectedItem();
		next.setEnabled(entries.size() == maxHits);
		prev.setEnabled(page > 0);
	}

	protected FeedEntryModel getSelectedSyndicatedEntry() {
		int viewRow = table.getSelectedRow();
		int modelRow = table.convertRowIndexToModel(viewRow);
		FeedEntryModel entry = tableModel.get(modelRow);
		return entry;
	}

	protected void viewCommit() {
		FeedEntryModel entry = getSelectedSyndicatedEntry();
		Utils.browse(entry.link);
	}

	protected void viewCommitDiff() {
		FeedEntryModel entry = getSelectedSyndicatedEntry();
		Utils.browse(entry.link.replace("/commit/", "/commitdiff/"));
	}

	protected void viewTree() {
		FeedEntryModel entry = getSelectedSyndicatedEntry();
		Utils.browse(entry.link.replace("/commit/", "/tree/"));
	}
}
