# Copyright 2015 Kevin Ryde
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3, or (at your option) any later
# version.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with this file.  See the file COPYING.  If not, see
# <http://www.gnu.org/licenses/>.

package Graph::Maker::Beineke;
use 5.004;
use strict;
use Carp 'croak';
use base 'Graph::Maker';

use vars '$VERSION';
$VERSION = 4;

# uncomment this to run the ### lines
# use Smart::Comments;

my @data
  = (undef, # 0
     undef, # 1
     [
      # G2    a--\
      #      / \  \
      #     b---c  e
      #      \ /  /
      #       d--/
      # https://hog.grinvin.org/ViewGraphInfo.action?id=438
      [1,2],[1,3],[1,5],
      [2,3],[2,4],
      [3,4],
      [5,4],
     ],
     [
      # G3 = K5-e complete 5 less one edge
      #      a
      #     /|\
      #    / b \
      #   / /|\ \
      #  / / c \ \
      #  |/ / \ \ |
      #  d--------e
      # https://hog.grinvin.org/ViewGraphInfo.action?id=450
      #
      [1,2],[1,4],[1,5],
      [2,3],[2,4],[2,5],
      [3,4],[3,5],
      [4,5],
     ],
     [
      # G4   a----e
      #     / \
      #    b---c
      #     \ /
      #      d----f
      # https://hog.grinvin.org/ViewGraphInfo.action?id=922
      #
      [1,2],[1,3],[1,5],
      [2,3],[2,4],
      [3,4],
      [4,6],
     ],
     [
      # G5    a
      #      /|\
      #     / e \
      #    / / \ \
      #    b------c
      #     \    /
      #      \  /
      #       d----f
      # hog not
      #
      [1,2],[1,5],[1,3],
      [2,5],[2,3],[2,4],
      [3,4],[3,5],
      [4,6],
     ],
     [
      # G6    a
      #      /|\
      #     / e \
      #    / / \ \
      #    b-----c
      #    \ \ / /
      #     \ f /
      #      \|/
      #       d
      # https://hog.grinvin.org/ViewGraphInfo.action?id=744
      #
      [1,2],[1,5],[1,3],
      [2,5],
      [2,3],[2,6],[2,4],
      [3,5],[3,6],[3,4],
      [4,6],
     ],
     [
      # G7   a----e
      #     / \   |
      #    b---c  |
      #     \ /   |
      #      d----f
      # hog not
      #
      [1,2],[1,3],[1,5],
      [2,3],[2,4],
      [3,4],
      [4,6],
      [5,6],
     ],
     [
      # G8 a---b
      #    | / |
      #    c---d
      #    | / |
      #    e---f
      # hog not
      #
      [1,2],[1,3],
      [2,3],[2,4],
      [3,4],[3,5],
      [4,5],[4,6],
      [5,6],
     ],
    );

sub _default_graph_maker {
  require Graph;
  Graph->new(@_);
}

sub init {
  my ($self, %params) = @_;

  my $N = delete($params{'N'}) || 0;
  ### $N

  if ($N == 1) {
    # G1 = claw = star 3
    # https://hog.grinvin.org/ViewGraphInfo.action?id=204
    require Graph::Maker::Star;
    my $graph = Graph::Maker->new('star', N=>4, %params);
    $graph->set_graph_attribute (name => "Beineke G1");
    return $graph;
  }

  if ($N == 9) {
    # G9 = wheel 6
    #        2        6 vertices
    #      / | \     10 edges
    #    4---1---3
    #     \ / \  /
    #      5---6
    # https://hog.grinvin.org/ViewGraphInfo.action?id=204
    #
    require Graph::Maker::Wheel;
    my $graph = Graph::Maker->new('wheel', N=>6, %params);
    $graph->set_graph_attribute (name => "Beineke G9");
    return $graph;
  }

  my $edge_aref = $data[$N]
    || croak "Unrecognised N: ", $N;

  my $graph_maker = delete($params{'graph_maker'});
  $graph_maker ||= \&_default_graph_maker;
  my $graph = $graph_maker->(%params);

  $graph->set_graph_attribute (name => "Beineke G$N");
  my $directed = $graph->is_directed;

  foreach my $edge (@$edge_aref) {
    ### $edge
    $graph->add_edge(@$edge);
    if ($directed) { $graph->add_edge(reverse @$edge); }
  }
  return $graph;
}

Graph::Maker->add_factory_type('beineke' => __PACKAGE__);
1;
