#include"draw_ampl.h"
#include"crt.h"
#include<strings.h>

static int XX,YY;
static int cHeight,cWidth;

typedef struct { int x,y;}  position;

int amplitudeFrameX(int nin, int nout)
{
 cWidth=tg_textwidth("H");

XX=15*cWidth;

return XX;

}

int amplitudeFrameY(int nin, int nout)
{
  cHeight=tg_textheight("H");
  YY=8*cHeight;
  return YY;
}

static void getPositions(vampl* diagr, position * vertexPos, position *edgePos)
{
 int i,j;
 int nIn=0;

 for(i=0;i<diagr->outno;i++) 
 { edgeinvert *v=&diagr->vertlist[diagr->outer[i].vno][diagr->outer[i].edno];
   if(v->prop==IN_PRTCL) nIn++;
 }     

 for(i=0;i<nIn;i++)
 { edgePos[i].x=1+2*cWidth; 
   edgePos[i].y=YY/(nIn+1)+i*YY/(nIn+1); 
 }
 
 for(i=nIn;i<diagr->outno;i++)
 { edgePos[i].x=XX-1-3*cWidth; 
   edgePos[i].y=YY/( diagr->outno-nIn+1)+(i-nIn)*YY/(diagr->outno-nIn+1); 
 }

 for(i=0;i<diagr->size;i++)
 { vertexPos[i].x=XX/2;
   vertexPos[i].y= (1+i)*YY/(1+diagr->size);
 }

}


static void super_outtextxy(int x, int y, char *name)
{ 
   if (name[0]=='~')
   { int cHeight=tg_textheight("H");
     tg_outtextxy(x,y,name+1);
     if(strlen(name+1)==2) tg_outtextxy(x,y-cHeight/2 ,"~~");
           else            tg_outtextxy(x,y-cHeight/2 ,"~");
   }else tg_outtextxy(x,y,name);
}


static void drawPropagator(int x1,int y1,int x2, int y2, int particle, int virtual)
{
  int spin2=prtclbase[particle-1].spin;
  int anti=prtclbase[particle-1].anti;
  int ln;
  int arrow=0;
 
  switch(spin2)
  { 
   case 0: ln = DottedLn;   break;
   case 1: ln = SolidLn;    break;
   case 2: ln = DashedLn;   break;
  }
  tg_setlinestyle(ln, NormWidth); 
  
  
  if(particle < anti)  arrow=1;
  else if(particle > anti) { arrow=-1; particle=anti;}     
  

  switch(arrow)
  {
    case  0:  tg_line(x1,y1,x2,y2); break;
    case  1:  tg_arrowline(x1,y1,x2,y2);break;
    case -1:  tg_arrowline(x2,y2,x1,y1);break;
 } 

 if(virtual)
 { int xj=LeftText;
   int yj=BottomText;
   int xShift=1;
   int yShift=1;
   char name[10];
       
   if(x1==x2) { yj=CenterText; if(arrow) xShift= cWidth/3+1;} else 
   if(y1==y2) { xj=CenterText; if(arrow) yShift= cHeight/3+1;}  else
              { if(arrow) yShift= cHeight/4+1;xShift= cWidth/4+1;}
   tg_settextjustify(xj,yj);
   super_outtextxy((x1+x2)/2+xShift,(y1+y2)/2-yShift,prtclbase[particle-1].name);  
 }

      
}


void drawAmpitudeDiagram(vampl* diagr, int x, int y)
{
  int i,j;
  position vertexPos[maxvert], edgePos[MAXINOUT]; 

  cHeight=tg_textheight("H");
  cWidth=tg_textwidth("H");
       
  getPositions(diagr, vertexPos,edgePos);

  for(i=0;i<diagr->size;i++) 
  { position in=vertexPos[i];
    for(j=0;j<diagr->valence[i];j++)
    { edgeinvert *v=&diagr->vertlist[i][j];
      position out;
      if(v->link.vno==nullvert) 
      { out=edgePos[v->link.edno];
        drawPropagator(x+in.x,y+in.y,x+out.x,y+out.y,v->partcl,0);
        if(v->prop&IN_PRTCL) 
        { tg_settextjustify(RightText,CenterText);
          tg_outtextxy(x+out.x,y+out.y,prtclbase[prtclbase[v->partcl-1].anti -1].name); 
        }else 
        { char num[10];
          tg_settextjustify(LeftText,CenterText); 
          super_outtextxy(x+out.x,y+out.y,prtclbase[v->partcl-1].name);
          sprintf(num,"%d",v->link.edno+1);
          tg_outtextxy(x+out.x+2*cWidth,y+out.y+cHeight/3,num);
        }
      }   
      else if(i<v->link.vno)
      {  out=vertexPos[v->link.vno];
         drawPropagator(x+in.x,y+in.y,x+out.x,y+out.y,v->partcl,1);  
      }
    }
  }
}
