/*
 * Copyright 2013 Urs Wolfer
 *
 * 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.urswolfer.intellij.plugin.gerrit.ui.filter;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.inject.Inject;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Separator;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.util.Consumer;
import com.urswolfer.intellij.plugin.gerrit.git.GerritGitUtil;
import com.urswolfer.intellij.plugin.gerrit.util.UrlUtils;
import git4idea.GitRemoteBranch;
import git4idea.history.wholeTree.BasePopupAction;
import git4idea.repo.GitRepository;
import org.jetbrains.annotations.Nullable;

import java.util.Collections;
import java.util.List;

/**
 * @author Thomas Forrer
 */
public class BranchFilter extends AbstractChangesFilter {
    @Inject
    private GerritGitUtil gerritGitUtil;

    private Optional<GitRemoteBranch> value = Optional.absent();

    @Override
    public AnAction getAction(Project project) {
        return new BranchPopupAction(project, "Branch:", "Branch");
    }

    @Override
    @Nullable
    public String getSearchQueryPart() {
        if (value.isPresent()) {
            return String.format("branch:%s", value.get().getNameForRemoteOperations());
        } else {
            return null;
        }
    }

    public final class BranchPopupAction extends BasePopupAction {
        private final Project project;

        public BranchPopupAction(Project project, String labeltext, String asTextLabel) {
            super(project, labeltext, asTextLabel);
            this.project = project;
            myLabel.setText("All");
        }

        @Override
        protected void createActions(Consumer<AnAction> actionConsumer) {
            actionConsumer.consume(new DumbAwareAction("All") {
                @Override
                public void actionPerformed(AnActionEvent e) {
                    value = Optional.absent();
                    myLabel.setText("All");
                    setChanged();
                    notifyObservers(project);
                }
            });
            Iterable<GitRepository> repositories = gerritGitUtil.getRepositories(project);
            for (GitRepository repository : repositories) {
                DefaultActionGroup group = new DefaultActionGroup();
                group.add(new Separator(UrlUtils.stripGitExtension(repository.getRoot().getName())));
                List<GitRemoteBranch> branches = Lists.newArrayList(repository.getBranches().getRemoteBranches());
                Ordering<GitRemoteBranch> ordering = Ordering.natural().onResultOf(new Function<GitRemoteBranch, String>() {
                    @Override
                    public String apply(GitRemoteBranch branch) {
                        return branch.getNameForRemoteOperations();
                    }
                });
                Collections.sort(branches, ordering);
                for (final GitRemoteBranch branch : branches) {
                    if (!branch.getNameForRemoteOperations().equals("HEAD")) {
                        group.add(new DumbAwareAction(branch.getNameForRemoteOperations()) {
                            @Override
                            public void actionPerformed(AnActionEvent e) {
                                value = Optional.of(branch);
                                myLabel.setText(branch.getNameForRemoteOperations());
                                setChanged();
                                notifyObservers(project);
                            }
                        });
                    }
                }
                actionConsumer.consume(group);
            }
        }
    }
}

@@ -641,16 +641,70 @@
 ilter;%0A%0A
+import java.util.Collections;%0Aimport java.util.List;%0A%0A
 import c
@@ -731,24 +731,24 @@
 e.Function;%0A
-
 import com.g
@@ -1534,62 +1534,8 @@
 e;%0A%0A
-import java.util.Collections;%0Aimport java.util.List;%0A%0A
 /**%0A
@@ -1696,31 +1696,32 @@
 ptional%3C
-GitRemoteBranch
+BranchDescriptor
 %3E value 
@@ -2020,29 +2020,143 @@
 at(%22
-branch:%25s%22, value.get
+project:%25s+branch:%25s%22,%0A                    getNameForRepository(value.get().getRepository()),%0A                    value.get().getBranch
 ().g
@@ -3134,16 +3134,22 @@
    for (
+final 
 GitRepos
@@ -3296,65 +3296,39 @@
 tor(
-UrlUtils.stripGitExtension(repository.getRoot().getName()
+getNameForRepository(repository
 )));
@@ -4229,23 +4229,57 @@
 onal.of(
+new BranchDescriptor(repository, 
 branch)
+)
 ;%0A      
@@ -4607,16 +4607,16 @@
 group);%0A
-
         
@@ -4636,11 +4636,656 @@
  %7D%0A    %7D
+%0A%0A    private String getNameForRepository(GitRepository repository) %7B%0A        return UrlUtils.stripGitExtension(repository.getRoot().getName());%0A    %7D%0A%0A    private static final class BranchDescriptor %7B%0A        private final GitRepository repository;%0A        private final GitRemoteBranch branch;%0A%0A        private BranchDescriptor(GitRepository repository, GitRemoteBranch branch) %7B%0A            this.repository = repository;%0A            this.branch = branch;%0A        %7D%0A%0A        public GitRepository getRepository() %7B%0A            return repository;%0A        %7D%0A%0A        public GitRemoteBranch getBranch() %7B%0A            return branch;%0A        %7D%0A    %7D
 %0A%7D%0A

Add project to filter query