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

#include "DGraph.h"

DGArc *newArc(DGNode *tl,DGNode *hd){
  DGArc *ar=(DGArc *)malloc(sizeof(DGArc));
  ar->tail=tl;
  ar->head=hd;
  return ar;
}
void arcShow(DGArc *ar){
  DGNode *tl=(DGNode *)ar->tail,
         *hd=(DGNode *)ar->head;
  fprintf(stderr,"%d. |%s ->%s\n",ar->id,tl->name,hd->name);
}

DGNode *newNode(char *nm){
  DGNode *nd=(DGNode *)malloc(sizeof(DGNode));
  nd->attribute=0;
  nd->color=0;
  nd->inDegree=0;
  nd->outDegree=0;
  nd->maxInDegree=SMALL_BLOCK_SIZE;
  nd->maxOutDegree=SMALL_BLOCK_SIZE;
  nd->inArc=(DGArc **)malloc(nd->maxInDegree*sizeof(DGArc*));
  nd->outArc=(DGArc **)malloc(nd->maxOutDegree*sizeof(DGArc*));
  nd->name=strdup(nm);
  nd->feat=NULL;
  return nd;
}
void nodeShow(DGNode* nd){
  fprintf( stderr,"%3d.%s: (%d,%d)\n",
	           nd->id,nd->name,nd->inDegree,nd->outDegree);
/*
  if(nd->verified==1) fprintf(stderr,"%ld.%s\t: usable.",nd->id,nd->name);
  else if(nd->verified==0)  fprintf(stderr,"%ld.%s\t: unusable.",nd->id,nd->name);
  else  fprintf(stderr,"%ld.%s\t: notverified.",nd->id,nd->name);   
*/
}

DGraph* newDGraph(char* nm){
  DGraph *dg=(DGraph *)malloc(sizeof(DGraph));
  dg->numNodes=0;
  dg->numArcs=0;
  dg->maxNodes=BLOCK_SIZE;
  dg->maxArcs=BLOCK_SIZE;
  dg->node=(DGNode **)malloc(dg->maxNodes*sizeof(DGNode*));
  dg->arc=(DGArc **)malloc(dg->maxArcs*sizeof(DGArc*));
  dg->name=strdup(nm);
  return dg;
}
int AttachNode(DGraph* dg, DGNode* nd) {
  int i=0,j,len=0;
  DGNode **nds =NULL, *tmpnd=NULL;
  DGArc **ar=NULL;

	if (dg->numNodes == dg->maxNodes-1 ) {
	  dg->maxNodes += BLOCK_SIZE;
          nds =(DGNode **) calloc(dg->maxNodes,sizeof(DGNode*));
	  memcpy(nds,dg->node,(dg->maxNodes-BLOCK_SIZE)*sizeof(DGNode*));
	  free(dg->node);
	  dg->node=nds;
	}

        len = strlen( nd->name);
	for (i = 0; i < dg->numNodes; i++) {
	  tmpnd =dg->node[ i];
	  ar=NULL;
	  if ( strlen( tmpnd->name) != len ) continue;
	  if ( strncmp( nd->name, tmpnd->name, len) ) continue;
	  if ( nd->inDegree > 0 ) {
	    tmpnd->maxInDegree += nd->maxInDegree;
            ar =(DGArc **) calloc(tmpnd->maxInDegree,sizeof(DGArc*));
	    memcpy(ar,tmpnd->inArc,(tmpnd->inDegree)*sizeof(DGArc*));
	    free(tmpnd->inArc);
	    tmpnd->inArc=ar;
	    for (j = 0; j < nd->inDegree; j++ ) {
	      nd->inArc[ j]->head = tmpnd;
	    }
	    memcpy( &(tmpnd->inArc[ tmpnd->inDegree]), nd->inArc, nd->inDegree*sizeof( DGArc *));
	    tmpnd->inDegree += nd->inDegree;
	  } 	
	  if ( nd->outDegree > 0 ) {
	    tmpnd->maxOutDegree += nd->maxOutDegree;
            ar =(DGArc **) calloc(tmpnd->maxOutDegree,sizeof(DGArc*));
	    memcpy(ar,tmpnd->outArc,(tmpnd->outDegree)*sizeof(DGArc*));
	    free(tmpnd->outArc);
	    tmpnd->outArc=ar;
	    for (j = 0; j < nd->outDegree; j++ ) {
	      nd->outArc[ j]->tail = tmpnd;
	    }			
	    memcpy( &(tmpnd->outArc[tmpnd->outDegree]),nd->outArc,nd->outDegree*sizeof( DGArc *));
	    tmpnd->outDegree += nd->outDegree;
	  } 
	  free(nd); 
	  return i;
	}
	nd->id = dg->numNodes;
	dg->node[dg->numNodes] = nd;
	dg->numNodes++;
return nd->id;
}
int AttachArc(DGraph *dg,DGArc* nar){
int	arcId = -1;
int i=0,newNumber=0;
DGNode	*head = nar->head,
	*tail = nar->tail; 
DGArc **ars=NULL,*probe=NULL;
/*fprintf(stderr,"AttachArc %ld\n",dg->numArcs); */
	if ( !tail || !head ) return arcId;
	if ( dg->numArcs == dg->maxArcs-1 ) {
	  dg->maxArcs += BLOCK_SIZE;
          ars =(DGArc **) calloc(dg->maxArcs,sizeof(DGArc*));
	  memcpy(ars,dg->arc,(dg->maxArcs-BLOCK_SIZE)*sizeof(DGArc*));
	  free(dg->arc);
	  dg->arc=ars;
	}
	for(i = 0; i < tail->outDegree; i++ ) { /* parallel arc */
	  probe = tail->outArc[ i];
	  if(probe->head == head
	     &&
	     probe->length == nar->length
            ){
            free(nar);
	    return probe->id;   
	  }
	}
	
	nar->id = dg->numArcs;
	arcId=dg->numArcs;
	dg->arc[dg->numArcs] = nar;
	dg->numArcs++;
	
	head->inArc[ head->inDegree] = nar;
	head->inDegree++;
	if ( head->inDegree >= head->maxInDegree ) {
	  newNumber = head->maxInDegree + SMALL_BLOCK_SIZE;
          ars =(DGArc **) calloc(newNumber,sizeof(DGArc*));
	  memcpy(ars,head->inArc,(head->inDegree)*sizeof(DGArc*));
	  free(head->inArc);
	  head->inArc=ars;
	  head->maxInDegree = newNumber;
	}
	tail->outArc[ tail->outDegree] = nar;
	tail->outDegree++;
	if(tail->outDegree >= tail->maxOutDegree ) {
	  newNumber = tail->maxOutDegree + SMALL_BLOCK_SIZE;
          ars =(DGArc **) calloc(newNumber,sizeof(DGArc*));
	  memcpy(ars,tail->outArc,(tail->outDegree)*sizeof(DGArc*));
	  free(tail->outArc);
	  tail->outArc=ars;
	  tail->maxOutDegree = newNumber;
	}
/*fprintf(stderr,"AttachArc: head->in=%d tail->out=%ld\n",head->inDegree,tail->outDegree);*/
return arcId;
}
void graphShow(DGraph *dg,int DetailsLevel){
  int i=0,j=0;
  fprintf(stderr,"%d.%s: (%d,%d)\n",dg->id,dg->name,dg->numNodes,dg->numArcs);
  if ( DetailsLevel < 1) return;
  for (i = 0; i < dg->numNodes; i++ ) {
    DGNode *focusNode = dg->node[ i];
    if(DetailsLevel >= 2) {
      for (j = 0; j < focusNode->inDegree; j++ ) {
	fprintf(stderr,"\t ");
	nodeShow(focusNode->inArc[ j]->tail);
      }
    }
    nodeShow(focusNode);
    if ( DetailsLevel < 2) continue;
    for (j = 0; j < focusNode->outDegree; j++ ) {
      fprintf(stderr, "\t ");
      nodeShow(focusNode->outArc[ j]->head);
    }	
    fprintf(stderr, "---\n");
  }
  fprintf(stderr,"----------------------------------------\n");
  if ( DetailsLevel < 3) return;
}



