/*
 * 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.wicket.pages;

import java.util.List;

import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;

import com.gitblit.models.PathModel;
import com.gitblit.servlet.RawServlet;
import com.gitblit.utils.ByteFormat;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.CacheControl.LastModified;
import com.gitblit.wicket.MarkupProcessor;
import com.gitblit.wicket.MarkupProcessor.MarkupDocument;
import com.gitblit.wicket.MarkupProcessor.MarkupSyntax;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.LinkPanel;

@CacheControl(LastModified.REPOSITORY)
public class DocsPage extends RepositoryPage {

	public DocsPage(PageParameters params) {
		super(params);

		MarkupProcessor processor = new MarkupProcessor(app().settings(), app().xssFilter());

		Repository r = getRepository();
		RevCommit head = JGitUtils.getCommit(r, null);
		final String commitId = getBestCommitId(head);
		List<String> extensions = processor.getAllExtensions();
		List<PathModel> paths = JGitUtils.getDocuments(r, extensions);

		List<MarkupDocument> roots = processor.getRootDocs(r, repositoryName, commitId);
		Fragment fragment = null;
		if (roots.isEmpty()) {
			// no identified root documents
			fragment = new Fragment("docs", "noIndexFragment", this);
			setResponsePage(NoDocsPage.class, params);
		} else {
			// root documents, use tabbed ui of index/root and document list
			fragment = new Fragment("docs", "tabsFragment", this);
			ListDataProvider<MarkupDocument> docDp = new ListDataProvider<MarkupDocument>(roots);

			// tab titles
			DataView<MarkupDocument> tabTitles = new DataView<MarkupDocument>("tabTitle", docDp) {
				private static final long serialVersionUID = 1L;
				int counter;

				@Override
				public void populateItem(final Item<MarkupDocument> item) {
					MarkupDocument doc = item.getModelObject();
					String file = StringUtils.getLastPathElement(doc.documentPath);
					file = StringUtils.stripFileExtension(file);
					String name = file.replace('_', ' ').replace('-',  ' ');

					ExternalLink link = new ExternalLink("link", "#" + file);
					link.add(new Label("label", name.toUpperCase()).setRenderBodyOnly(true));
					item.add(link);
					if (counter == 0) {
						counter++;
						item.add(new SimpleAttributeModifier("class", "active"));
					}
				}
			};
			fragment.add(tabTitles);

			// tab content
			DataView<MarkupDocument> tabsView = new DataView<MarkupDocument>("tabContent", docDp) {
				private static final long serialVersionUID = 1L;
				int counter;

				@Override
				public void populateItem(final Item<MarkupDocument> item) {
					MarkupDocument doc = item.getModelObject();
					// document page links
					item.add(new BookmarkablePageLink<Void>("blameLink", BlamePage.class,
							WicketUtils.newPathParameter(repositoryName, commitId, doc.documentPath)));
					item.add(new BookmarkablePageLink<Void>("historyLink", HistoryPage.class,
							WicketUtils.newPathParameter(repositoryName, commitId, doc.documentPath)));
					String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, commitId, doc.documentPath);
					item.add(new ExternalLink("rawLink", rawUrl));

					// document content
					String file = StringUtils.getLastPathElement(doc.documentPath);
					file = StringUtils.stripFileExtension(file);
					Component content = new Label("content", doc.html)
						.setEscapeModelStrings(false);
					if (!MarkupSyntax.PLAIN.equals(doc.syntax)) {
						content.add(new SimpleAttributeModifier("class", "markdown"));
					}
					item.add(content);
					item.add(new SimpleAttributeModifier("id", file));
					if (counter == 0) {
						counter++;
						item.add(new SimpleAttributeModifier("class", "tab-pane active"));
					}
				}
			};
			fragment.add(tabsView);
		}

		// document list
		final String id = getBestCommitId(head);
		final ByteFormat byteFormat = new ByteFormat();
		Fragment docs = new Fragment("documents", "documentsFragment", this);
		ListDataProvider<PathModel> pathsDp = new ListDataProvider<PathModel>(paths);
		DataView<PathModel> pathsView = new DataView<PathModel>("document", pathsDp) {
			private static final long serialVersionUID = 1L;
			int counter;

			@Override
			public void populateItem(final Item<PathModel> item) {
				PathModel entry = item.getModelObject();
				item.add(WicketUtils.newImage("docIcon", "file_world_16x16.png"));
				item.add(new Label("docSize", byteFormat.format(entry.size)));
				item.add(new LinkPanel("docName", "list", StringUtils.stripFileExtension(entry.name),
						DocPage.class, WicketUtils.newPathParameter(repositoryName, id, entry.path)));

				// links
				item.add(new BookmarkablePageLink<Void>("view", DocPage.class, WicketUtils
						.newPathParameter(repositoryName, id, entry.path)));
				String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, id, entry.path);
				item.add(new ExternalLink("raw", rawUrl));
				item.add(new BookmarkablePageLink<Void>("blame", BlamePage.class, WicketUtils
						.newPathParameter(repositoryName, id, entry.path)));
				item.add(new BookmarkablePageLink<Void>("history", HistoryPage.class, WicketUtils
						.newPathParameter(repositoryName, id, entry.path)));
				WicketUtils.setAlternatingBackground(item, counter);
				counter++;
			}
		};
		docs.add(pathsView);
		fragment.add(docs);
		add(fragment);
	}

	@Override
	protected String getPageName() {
		return getString("gb.docs");
	}
}
