/*
 * Copyright 2011 Steven Gribble
 *
 *  This file is the solution to an exercise problem posed during
 *  one of the UW CSE 333 lectures (333exercises).
 *
 *  333exercises 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 of the License, or
 *  (at your option) any later version.
 *
 *  333exercises 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 333exercises.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "graphops.h"

// Here's the root of the collaboration graph.
Node *collabgraph = NULL;

static Collab *GetScientistEntry(char *scientist) {
  Node *tmp = collabgraph;

  // Do some sanity checking.
  assert(scientist != NULL);
  assert(strlen(scientist) > 0);

  // Loop through the main list of the collaboration graph
  // looking for scientist.
  while (tmp != NULL) {
    Collab *nextcollab = (Collab *) tmp->element;

    assert(nextcollab != NULL);
    if (strcmp(scientist, nextcollab->scientist) == 0) {
      return nextcollab;
    }
    tmp = tmp->next;
  }
  return NULL;
}

Node *GetCollaboratorList(char *scientist) {
  Collab *tmp = GetScientistEntry(scientist);

  if (tmp == NULL)
    return NULL;

  return (Node *) tmp->collaborators;
}

int TestIfCollaborator(char *scientist, char *collaborator) {
  Node *collablist = GetCollaboratorList(scientist);

  while (collablist != NULL) {
    char *collab = (char *) collablist->element;
    if (strcmp(collab, collaborator) == 0)
      return 1;
    collablist = collablist->next;
  }
  return 0;
}

void AddCollaboration(char *scientist, char *collaborator) {
  char *collabstr;
  Collab *collabptr;

  // If the collaborator is already listed for the scientist,
  // no need to add again.
  if (TestIfCollaborator(scientist, collaborator)) {
    return;
  }

  // See if the scientist exists in our main list yet.
  collabptr = GetScientistEntry(scientist);
  if (collabptr == NULL) {
    // Nope, so need to allocate a new Collab for this scientist
    // and add it on the main collabgraph list.
    collabptr = (Collab *) malloc(sizeof(Collab));
    assert(collabptr != NULL);
    collabptr->scientist = strdup(scientist);
    assert(collabptr->scientist != NULL);
    collabptr->collaborators = NULL;
    collabgraph = Push(collabgraph, (void *) collabptr);
    assert(collabgraph != NULL);
  }

  // add the collaborator to the scientist's collab list
  collabstr = strdup(collaborator);
  assert(collabstr != NULL);
  collabptr->collaborators = Push(collabptr->collaborators,
                                  (void *) collabstr);
  assert(collabptr->collaborators != NULL);
}