(**  
                   VertexHandling.m  

(utility for CreateFeynAmp.m)
**)

BeginPackage["VertexHandling`","FeynArts`"]

VertexHandling::usage ="
applied to an inserted topology constructs vertices of the form \n
Vertex[ vertexname , { {in1,mom1} , {in2,mom2} , ... } ] . If there \n
are SpinorChains, the vertices are put in the right places."

Begin["`Private`"]

Vertices[ tt:Topology[_][___] ] :=
  Module[{flat,three,four},
	 flat = Flatten[ tt/.{Topology[_]->List,
			      SpinorChain->List,Propagator[_]->List} ];
         three = Cases[ flat, v3[_] ];
	 four = Cases[ flat, v4[_] ];
	 Union[ three,four ]
       ]

ppOne[ h_[ nr_ , one_ , two_ , three_ , four_ ] ] := h[nr,one,three]
ppTwo[ h_[ nr_ , one_ , two_ , three_ , four_ ] ] := h[nr,two,four]
ppOne[ h_[ nr_ , one_ , two_ ] ] := h[nr,one]
ppTwo[ h_[ nr_ , one_ , two_ ] ] := h[nr,two]
ppOne[ x_ ] := x
ppTwo[ x_ ] := x

TakeIn[ vert_ , Propagator[_][ vert_ , _ , part_ , mom_ ] ] := 
	     {{AntiParticle[CreateFeynAmp`Private`WorkingModel][
		   ppOne[part]],Expand[-mom]}}

TakeIn[ vert_ , Propagator[_][ _ , vert_ , part_ , mom_ ] ] :=
	     {{ppTwo[part],mom }}

TakeIn[ vert_ , Propagator[_][ vert_ , vert_ , part_ , mom_] ] :=
             {{AntiParticle[CreateFeynAmp`Private`WorkingModel][
	       ppOne[part]],Expand[-mom]},
	      {ppTwo[part],mom}}

ConstVert[ vv_ , wl_List ] :=
     Vertex[ vv ,
             Flatten[
                     TakeIn[ vv , # ]& /@ 
        	             Select[ wl , !FreeQ[ #, vv ]& ] ,
                     1 ]
	   ]

ConstructVertices[ tt:Topology[_][___] ] :=
  Module[{worklist,outlist},
	worklist = Flatten[ tt/.{Topology[_]->List,SpinorChain->List}];
	outlist = ConstVert[ # , worklist ]& /@ Vertices[tt] ;
	Return[ outlist ]
       ]

VPositionRules = {
 Topology[s_][ { listofvert__ } , otherstuff__ 
             ] :> 
      Topology[s][ listofvert , otherstuff ] ,
 Topology[s_][ a___, Vertex[ thev_ , vv_List ], b___ ,
               SpinorChain[ pa___,p:Propagator[_][_,thev_,__], pb___ ],
	       c___ 
	     ] :>
      Topology[s][ a , b , SpinorChain[pa,p,Vertex[thev,vv],pb] , c ]
   }

VertexHandling[ Topology[ s_ ][ elements__ ] ] :=
   Topology[s][ ConstructVertices[ Topology[s][elements] ] ,
		elements ] //.VPositionRules

End[]

EndPackage[]
