import "../../../../modsym/core.m": LiftToCosetRep;
import "../../../../modsym/analytic.m": PeriodIntegral;

forward LinearFractionalTransformation,
        Integral;

intrinsic CMPoint(E::CrvEll, alpha::FldPrElt, prec::RngIntElt) -> FldPrElt, FldPrElt
{}
   require E eq MinimalModel(E) : "Argument 1 must be minimal.";

   f := qEigenform(E,prec);
   N := Conductor(E);
   P1:= P1Classes(N);
   R := [LiftToCosetRep(x, N) : x in P1];
   r_of_alpha := [LinearFractionalTransformation(r,alpha) : r in R];
//   return r_of_alpha;
   z := &+ [ Integral(f, ralp) : ralp in r_of_alpha];  
   om1, om2 := Explode(Periods(E));
   z := z/om1;
   t := om2/om1;
   x := Real(z);
   y := Imaginary(z);
   return y/Imaginary(t), x - Real(t)*(y/Imaginary(t));

end intrinsic;

function Integral(f, alpha)
   return PeriodIntegral(f, PolynomialRing(Rationals())!1, alpha);
end function;

function LinearFractionalTransformation(r, alpha)
   return (r[1]*alpha + r[2])/(r[3]*alpha + r[4]);
end function;

intrinsic Go(E::CrvEll, prec::RngIntElt)
{}
   P := [p : p in [3..97] | IsPrime(p)];
   for p in P do
      if p mod 4 eq 1 then 
         alpha := Sqrt(-p);
      else
         alpha := (1+Sqrt(-p))/2;
      end if;
      CMPoint(E, alpha, prec);
   end for;
end intrinsic;
