/*
 * 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);

		String objectId = WicketUtils.getObject(params);

		MarkupProcessor processor = new MarkupProcessor(app().settings(), app().xssFilter());

		Repository r = getRepository();
		RevCommit head = JGitUtils.getCommit(r, objectId);
		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 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, commitId, entry.path)));

				// links
				item.add(new BookmarkablePageLink<Void>("view", DocPage.class, WicketUtils
						.newPathParameter(repositoryName, commitId, entry.path)));
				String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, commitId, entry.path);
				item.add(new ExternalLink("raw", rawUrl));
				item.add(new BookmarkablePageLink<Void>("blame", BlamePage.class, WicketUtils
						.newPathParameter(repositoryName, commitId, entry.path)));
				item.add(new BookmarkablePageLink<Void>("history", HistoryPage.class, WicketUtils
						.newPathParameter(repositoryName, commitId, entry.path)));
				WicketUtils.setAlternatingBackground(item, counter);
				counter++;
			}
		};
		docs.add(pathsView);
		fragment.add(docs);
		add(fragment);
	}

	@Override
	protected String getPageName() {
		return getString("gb.docs");
	}

	@Override
	protected boolean isCommitPage() {
		return true;
	}

}
