// (C) Copyright 2007-2009 Andrew Sutton
//
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0 (See accompanying file
// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_GRAPH_CLUSTERING_COEFFICIENT_HPP
#define BOOST_GRAPH_CLUSTERING_COEFFICIENT_HPP

#include <boost/utility.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <boost/graph/lookup_edge.hpp>

namespace boost
{
namespace detail
{
    template <class Graph>
    inline typename graph_traits<Graph>::degree_size_type
    possible_edges(const Graph& g, std::size_t k, directed_tag)
    {
        function_requires< GraphConcept<Graph> >();
        typedef typename graph_traits<Graph>::degree_size_type T;
        return T(k) * (T(k) - 1);
    }

    template <class Graph>
    inline typename graph_traits<Graph>::degree_size_type
    possible_edges(const Graph& g, size_t k, undirected_tag)
    {
        // dirty little trick...
        return possible_edges(g, k, directed_tag()) / 2;
    }

    // This template matches directedS and bidirectionalS.
    template <class Graph>
    inline typename graph_traits<Graph>::degree_size_type
    count_edges(const Graph& g,
                typename Graph::vertex_descriptor u,
                typename Graph::vertex_descriptor v,
                directed_tag)

    {
        function_requires< AdjacencyMatrixConcept<Graph> >();
        return (lookup_edge(u, v, g).second ? 1 : 0) +
                (lookup_edge(v, u, g).second ? 1 : 0);
    }

    // This template matches undirectedS
    template <class Graph>
    inline typename graph_traits<Graph>::degree_size_type
    count_edges(const Graph& g,
                typename Graph::vertex_descriptor u,
                typename Graph::vertex_descriptor v,
                undirected_tag)
    {
        function_requires< AdjacencyMatrixConcept<Graph> >();
        return lookup_edge(u, v, g).second ? 1 : 0;
    }
}

template <typename Graph, typename Vertex>
inline typename graph_traits<Graph>::degree_size_type
num_paths_through_vertex(const Graph& g, Vertex v)
{
    function_requires< AdjacencyGraphConcept<Graph> >();
    typedef typename graph_traits<Graph>::directed_category Directed;
    typedef typename graph_traits<Graph>::adjacency_iterator AdjacencyIterator;

    // TODO: There should actually be a set of neighborhood functions
    // for things like this (num_neighbors() would be great).

    AdjacencyIterator i, end;
    boost::tie(i, end) = adjacent_vertices(v, g);
    std::size_t k = std::distance(i, end);
    return detail::possible_edges(g, k, Directed());
}

template <typename Graph, typename Vertex>
inline typename graph_traits<Graph>::degree_size_type
num_triangles_on_vertex(const Graph& g, Vertex v)
{
    function_requires< IncidenceGraphConcept<Graph> >();
    function_requires< AdjacencyGraphConcept<Graph> >();
    typedef typename graph_traits<Graph>::degree_size_type Degree;
    typedef typename graph_traits<Graph>::directed_category Directed;
    typedef typename graph_traits<Graph>::adjacency_iterator AdjacencyIterator;

    // TODO: I might be able to reduce the requirement from adjacency graph
    // to incidence graph by using out edges.

    Degree count(0);
    AdjacencyIterator i, j, end;
    for(boost::tie(i, end) = adjacent_vertices(v, g); i != end; ++i) {
        for(j = boost::next(i); j != end; ++j) {
            count += detail::count_edges(g, *i, *j, Directed());
        }
    }
    return count;
} /* namespace detail */

template <typename T, typename Graph, typename Vertex>
inline T
clustering_coefficient(const Graph& g, Vertex v)
{
    T zero(0);
    T routes = T(num_paths_through_vertex(g, v));
    return (routes > zero) ?
        T(num_triangles_on_vertex(g, v)) / routes : zero;
}

template <typename Graph, typename Vertex>
inline double
clustering_coefficient(const Graph& g, Vertex v)
{ return clustering_coefficient<double>(g, v); }

template <typename Graph, typename ClusteringMap>
inline typename property_traits<ClusteringMap>::value_type
all_clustering_coefficients(const Graph& g, ClusteringMap cm)
{
    function_requires< VertexListGraphConcept<Graph> >();
    typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
    typedef typename graph_traits<Graph>::vertex_iterator VertexIterator;
    function_requires< WritablePropertyMapConcept<ClusteringMap,Vertex> >();
    typedef typename property_traits<ClusteringMap>::value_type Coefficient;

    Coefficient sum(0);
    VertexIterator i, end;
    for(boost::tie(i, end) = vertices(g); i != end; ++i) {
        Coefficient cc = clustering_coefficient<Coefficient>(g, *i);
        put(cm, *i, cc);
        sum += cc;
    }
    return sum / Coefficient(num_vertices(g));
}

template <typename Graph, typename ClusteringMap>
inline typename property_traits<ClusteringMap>::value_type
mean_clustering_coefficient(const Graph& g, ClusteringMap cm)
{
    function_requires< VertexListGraphConcept<Graph> >();
    typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
    typedef typename graph_traits<Graph>::vertex_iterator VertexIterator;
    function_requires< ReadablePropertyMapConcept<ClusteringMap,Vertex> >();
    typedef typename property_traits<ClusteringMap>::value_type Coefficient;

    Coefficient cc(0);
    VertexIterator i, end;
    for(boost::tie(i, end) = vertices(g); i != end; ++i) {
        cc += get(cm, *i);
    }
    return cc / Coefficient(num_vertices(g));
}

} /* namespace boost */

#endif
