package org.intermine.bio.web.displayer;

/*
 * Copyright (C) 2002-2011 FlyMine
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  See the LICENSE file for more
 * information or http://www.gnu.org/copyleft/lesser.html.
 *
 */

import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import org.intermine.api.InterMineAPI;
import org.intermine.model.InterMineObject;
import org.intermine.web.displayer.ReportDisplayer;
import org.intermine.web.logic.config.ReportDisplayerConfig;
import org.intermine.web.logic.results.ReportObject;

/**
 * Display pathway for this gene, plus the count of the other genes on this pathway
 *
 * @author Julie Sullivan
 */
public class PathwaysDisplayer extends ReportDisplayer
{

    private Map<InterMineObject, Integer> pathways = new HashMap<InterMineObject, Integer>();
    private Map<InterMineObject, Map<InterMineObject, Integer>> cache
        = new HashMap<InterMineObject, Map<InterMineObject, Integer>>();

    /**
     * Construct with config and the InterMineAPI.
     *
     * @param config to describe the report displayer
     * @param im the InterMine API
     */
    public PathwaysDisplayer(ReportDisplayerConfig config, InterMineAPI im) {
        super(config, im);
    }

    @Override
    public void display(HttpServletRequest request, ReportObject reportObject) {
        InterMineObject gene = reportObject.getObject();
        if (cache.get(gene) != null) {
            pathways = cache.get(gene);
        } else {
            try {
                Collection col = (Collection) gene.getFieldValue("pathways");
                for (Object item : col) {
                    InterMineObject pathway = (InterMineObject) item;
                    if (pathway != null) {
                        Collection genes = (Collection) pathway.getFieldValue("genes");
                        pathways.put(pathway, genes.size());
                    }
                }
                cache.put(gene, pathways);
            } catch (IllegalAccessException e) {
                // oops
            }
        }
        if (pathways.isEmpty()) {
            request.setAttribute("noPathwayResults", "No pathways found");
        } else {
            SortedMap sortedPathways = new TreeMap<InterMineObject, Integer>(
                    new ValueComparator(pathways));
            sortedPathways.putAll(pathways);
            request.setAttribute("pathways", sortedPathways);
        }
    }
}

/**
 * sorting pathway gene counts descending
 *
 * @author Julie
 */
class ValueComparator implements Comparator
{
    Map base;

    /**
     * @param base map
     */
    public ValueComparator(Map base) {
        this.base = base;
    }

    @Override
    public int compare(Object a, Object b) {
        // sort descending
        int i = ((Integer) base.get(a)).compareTo((Integer) base.get(b));

        // gene counts are the same, sort by name ascending
        if (i == 0) {
            InterMineObject aObject = (InterMineObject) a;
            InterMineObject bObject = (InterMineObject) b;

            try {
                String aName = (String) aObject.getFieldValue("name");
                String bName = (String) bObject.getFieldValue("name");
                return aName.compareTo(bName);
            } catch (IllegalAccessException e) {
                // bad pathway, return zero
            }
        }
        return i;
    }
}


@@ -492,16 +492,63 @@
 TreeMap;
+%0Aimport java.util.concurrent.ConcurrentHashMap;
 %0A%0Aimport
@@ -1041,113 +1041,11 @@
 Inte
-rMineObject, Integer%3E pathways = new HashMap%3CInterMineObject, Integer%3E();%0A    private Map%3CInterMineObject
+ger
 , Ma
@@ -1082,23 +1082,33 @@
 ache
-%0A
  
+=%0A
        
-=
  new 
+Concurrent
 Hash
@@ -1115,27 +1115,19 @@
 Map%3CInte
-rMineObject
+ger
 , Map%3CIn
@@ -1594,78 +1594,546 @@
     
-if (cache.get(gene) != null) %7B%0A            pathways = cache.get(
+Map%3CInterMineObject, Integer%3E pathways = getPathways(gene);%0A        if (pathways.isEmpty()) %7B%0A            request.setAttribute(%22noPathwayResults%22, %22No pathways found%22);%0A        %7D else %7B%0A            SortedMap%3CInterMineObject, Integer%3E sortedPathways =%0A                new TreeMap%3CInterMineObject, Integer%3E(new ValueComparator(pathways));%0A            sortedPathways.putAll(pathways);%0A            request.setAttribute(%22pathways%22, sortedPathways);%0A        %7D%0A    %7D%0A%0A    private Map%3CInterMineObject, Integer%3E getPathways(InterMineObject 
 gene)
-;
+ %7B
 %0A   
@@ -2141,34 +2141,163 @@
     
-%7D else %7B%0A            try %7B
+if (!cache.containsKey(gene.getId())) %7B%0A            try %7B%0A                Map%3CInterMineObject, Integer%3E pathways = new HashMap%3CInterMineObject, Integer%3E();
 %0A   
@@ -2745,16 +2745,24 @@
 put(gene
+.getId()
 , pathwa
@@ -2875,372 +2875,39 @@
     
-if (pathways.isEmpty()) %7B%0A            request.setAttribute(%22noPathwayResults%22, %22No pathways found%22);%0A        %7D else %7B%0A            SortedMap sortedPathways = new TreeMap%3CInterMineObject, Integer%3E(%0A                    new ValueComparator(pathways));%0A            sortedPathways.putAll(pathways);%0A            request.setAttribute(%22pathways%22, sortedPathways);%0A        %7D
+return cache.get(gene.getId());
 %0A   

Fix caching issue that displayed pathways on wrong gene pages.