// Rascal, the Advanced Scientific CALculator
// Copyright (C) 2001, Sebastian Ritterbusch (Rascal@Ritterbusch.de)
//
// This program 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 2
// of the License, or (at your option) any later version.
//
// This program 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 detauls.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

#include <stdio.h>
#include <fstream.h>
#include <unistd.h>
#include <string.h>

string gnuplot_output_file="";

string set_gnuplot_output_file(string b)
{
   return gnuplot_output_file=b;
}

#ifdef WEB_VERSION
   int web_plot_no=0;
#endif

string gnuplot(const valuematrix & a)
{
#ifdef STANDALONE_VALUE
   return "plotting not supported in standalone version";
#else
   if(!cell(a,1).isSYMREC())
   {
      return "Usage: plot(<function>,<minx>,<maxx>,<stepsize>)";
   }
   symrec *f((symrec*)cell(a,1).asSYMREC());
  
   char buffer[1024];
   char buffer2[1024];
   
   tmpnam(buffer); //  I know that I mustn't use this function :)
   tmpnam(buffer2); // but the man-pages don't tell me how I can avoid it!
                    // I need to know the file name! Help is appreciated!  
                        
   ofstream out(buffer);

   value xstart(-5.),xend(5.),xstep(1/32.);
   
   if(a.N>1 || a.M>1)
      xstart=cell(a,2)*1.;
   if(a.N>2 || a.M>2)
      xend=cell(a,3);
   if(a.N>3 || a.M>3)
      xstep=cell(a,4);
   
   int lines=1;
   
   for(value x=xstart;x<=xend;x=x+xstep)
   {
      out << output(x).asSTRING();
      value y=evaluate(f,x);
      if(y.isMATRIX())
      {
         valuematrix Y(y.asMATRIX());
         int i1,i2;
         lines=0;
         for(i1=0;i1<Y.N;i1++)
            for(i2=0;i2<Y.M;i2++)
            {
               out << "\t" << output(Y(i1,i2)).asSTRING();
               lines++;
            }
         out << endl;             
      } else
      {
         out << "\t" << output(y).asSTRING() << endl;
      }
   }
   out.close();
   
   ofstream out2(buffer2);
   
#ifdef WEB_VERSION
   {
      char f[80];
      sprintf(f,"plotimg/%d.png",web_plot_no++);
      gnuplot_output_file=f;
   }
#endif
   
   if(gnuplot_output_file!="")
   {
      if(gnuplot_output_file.find(".png",0)!=-1)
      {
         out2 << "set terminal png medium color" << endl;
         out2 << "set output \""<< gnuplot_output_file <<"\"" << endl;
      } else
      {
         out2 << "set terminal postscript" << endl;
         out2 << "set output \""<< gnuplot_output_file <<"\"" << endl;
         out2 << "set size .8,.8" << endl;
      }
   }
   
   if(lines==1)
      out2 << "plot \"" << buffer << "\" title \"" << f->name << "\" with lines" << endl;
   else if(lines>1)
   {
      int i;
      out2 << "plot \"" << buffer << "\" title \"" << f->name << " 1\" with lines";

      for(i=1;i<lines;i++)
      {
         out2 << " ,\"" << buffer << "\" using 1:" << i+2 << " title \"" << f->name << " " << i+1 <<  "\" with lines";
      }
      out2 << endl;
   }
   
   out2.close();
   
   char buffer3[1024];
   sprintf(buffer3,"gnuplot -persist %s",buffer2);
   
   system(buffer3);

#ifdef WEB_VERSION
   cout << endl << "<img src=\"/" << gnuplot_output_file << "\" align=center>" << endl;
#endif
   
   unlink(buffer);
   unlink(buffer2);
   return "ok";
#endif
}

string gnupplot(const valuematrix & a)
{
#ifdef STANDALONE_VALUE
   return "plotting not supported in standalone version";
#else
   if(!cell(a,1).isSYMREC())
   {
      return "Usage: pplot(<2dfunction>,<mint>,<maxt>,<stepsize>,<minx>,<maxx>,<miny>,<maxy>)";
   }
   symrec *f((symrec*)cell(a,1).asSYMREC());
  
   char buffer[1024];
   char buffer2[1024];
   
   tmpnam(buffer); //  I know that I mustn't use this function :)
   tmpnam(buffer2); // but the man-pages don't tell me how I can avoid it!
                    // I need to know the file name! Help is appreciated!  
                        
   ofstream out(buffer);

   value tstart(0),tend(1),tstep(1/128.);
   value minx,maxx,miny,maxy;
   int   dosx=0,dosy=0;
   
   if(a.N>1 || a.M>1)
      tstart=cell(a,2)*1.;
   if(a.N>2 || a.M>2)
      tend=cell(a,3);
   if(a.N>3 || a.M>3)
      tstep=cell(a,4);
   if(a.N>4 || a.M>4)
   {
      dosx=1;minx=maxx=cell(a,5);
   }      
   if(a.N>5 || a.M>5)
   {
      dosx=1;maxx=cell(a,6);
   }      
   if(a.N>6 || a.M>6)
   {
      dosy=1;miny=maxy=cell(a,7);
   }      
   if(a.N>7 || a.M>7)
   {
      dosy=1;maxy=cell(a,8);
   }      
   
   int lines=1;
   
   for(value t=tstart;t<=tend;t=t+tstep)
   {
//      out << output(x).asSTRING();
      value y=evaluate(f,t);
      if(y.isMATRIX())
      {
         valuematrix Y(y.asMATRIX());
         int i1,i2;
         lines=0;
         for(i1=0;i1<Y.N;i1++)
            for(i2=0;i2<Y.M;i2++)
            {
               out << "\t" << output(Y(i1,i2)).asSTRING();
               lines++;
            }
         out << endl;             
      } else
      {
         out << output(t).asSTRING() << "\t" << output(y).asSTRING() << endl;
      }
   }
   out.close();
   
   ofstream out2(buffer2);
   
#ifdef WEB_VERSION
   {
      char f[80];
      sprintf(f,"plotimg/%d.png",web_plot_no++);
      gnuplot_output_file=f;
   }
#endif

   if(gnuplot_output_file!="")
   {
      if(gnuplot_output_file.find(".png",0)!=-1)
      {
         out2 << "set terminal png medium color" << endl;
         out2 << "set output \""<< gnuplot_output_file <<"\"" << endl;
      } else
      {
         out2 << "set terminal postscript" << endl;
         out2 << "set output \""<< gnuplot_output_file <<"\"" << endl;
         out2 << "set size .8,.8" << endl;
      }
   }
   
   if(lines==1 || lines==2)
   {
      out2 << "plot ";
      if(dosx)
      {
         out2 << "["<<output(minx).asSTRING()<<":"<<output(maxx).asSTRING()<<"] ";
         if(dosy)
            out2 << "["<<output(miny).asSTRING()<<":"<<output(maxy).asSTRING()<<"] ";
      }
      out2 << "\"" << buffer << "\" title \"" << f->name << "\" with lines" << endl;
   
   } else if(lines>2)
   {
      int i;
      out2 << "plot ";
      if(dosx)
      {
         out2 << "["<<output(minx).asSTRING()<<":"<<output(maxx).asSTRING()<<"] ";
         if(dosy)
            out2 << "["<<output(miny).asSTRING()<<":"<<output(maxy).asSTRING()<<"] ";
      }

      out2 << "\"" << buffer << "\" using 1:2 title \"" << f->name << " 1\" with lines";

      for(i=2;i<lines-1;i+=2)
      {
         out2 << " ,\"" << buffer << "\" using " << i+1 << ":" << i+2 << " title \"" << f->name << " " << i/2+1 <<  "\" with lines";
      }
      out2 << endl;
   }
   
   out2.close();
   
   char buffer3[1024];
   sprintf(buffer3,"gnuplot -persist %s",buffer2);
   
   system(buffer3);

#ifdef WEB_VERSION
   cout << endl << "<img src=\"/" << gnuplot_output_file << "\" align=center>" << endl;
#endif

   unlink(buffer);
   unlink(buffer2);
   return "ok";
#endif
}

string gnusplot(const valuematrix & a)
{
#ifdef STANDALONE_VALUE
   return "plotting not supported in standalone version";
#else
   if(!cell(a,1).isSYMREC())
   {
      return "Usage: splot(<function>,<minx>,<maxx>,<miny>,<miny>,<stepx>,<stepy>)";
   }
   symrec *f((symrec*)cell(a,1).asSYMREC());
  
   char buffer[1024];
   char buffer2[1024];
   
   tmpnam(buffer); //  I know that I mustn't use this function :)
   tmpnam(buffer2); // but the man-pages don't tell me how I can avoid it!
                    // I need to know the file name! Help is appreciated!  
                        
   ofstream out(buffer);

   value xstart(-5.),xend(5.),xstep(1/4.);
   value ystart(-5.),yend(5.),ystep(1/4.);
   
   if(a.N>1 || a.M>1)
      xstart=cell(a,2)*1.;
   if(a.N>2 || a.M>2)
      xend=cell(a,3)*1.;
   if(a.N>3 || a.M>3)
      ystart=cell(a,4)*1.;
   if(a.N>4 || a.M>4)
      yend=cell(a,5)*1.;
   if(a.N>5 || a.M>5)
      xstep=cell(a,6);
   if(a.N>6 || a.M>6)
      ystep=cell(a,7);
   
   int lines=1;
   
   for(value x=xstart;x<=xend;x=x+xstep)
   {
      for(value y=ystart;y<=yend;y=y+ystep)
      {
         out << output(x).asSTRING() << "\t" << output(y).asSTRING();
         valuematrix X(2,1);
         X(0,0)=x;
         X(1,0)=y;
         value z=evaluate_n(f,X);
         if(z.isMATRIX())
         {
            valuematrix Z(z.asMATRIX());
            int i1,i2;
            lines=0;
            for(i1=0;i1<Z.N;i1++)
               for(i2=0;i2<Z.M;i2++)
               {
                  out << "\t" << output(Z(i1,i2)).asSTRING();
                  lines++;
               }
            out << endl;             
         } else
         {
            out << "\t" << output(z).asSTRING() << endl;
         }
      }
      out << endl;
   }
   out.close();
   
   ofstream out2(buffer2);
   
#ifdef WEB_VERSION
   {
      char f[80];
      sprintf(f,"plotimg/%d.png",web_plot_no++);
      gnuplot_output_file=f;
   }
#endif

   if(gnuplot_output_file!="")
   {
      if(gnuplot_output_file.find(".png",0)!=-1)
      {
         out2 << "set terminal png medium color" << endl;
         out2 << "set output \""<< gnuplot_output_file <<"\"" << endl;
      } else
      {
         out2 << "set terminal postscript" << endl;
         out2 << "set output \""<< gnuplot_output_file <<"\"" << endl;
         out2 << "set size .8,.8" << endl;
      }
   }
   
   out2 << "set contour" << endl;
             
   out2 << "set hidden3d" << endl;
                      
   out2 << "set grid" << endl;

   if(lines==1)
      out2 << "splot \"" << buffer << "\" title \"" << f->name << "\" with lines" << endl;
   else if(lines>1)
   {
      int i;
      out2 << "splot \"" << buffer << "\" title \"" << f->name << " 1\" with lines";

      for(i=1;i<lines;i++)
      {
         out2 << " ,\"" << buffer << "\" using 1:2:" << i+3 << " title \"" << f->name << " " << i+1 <<  "\" with lines";
      }
      out2 << endl;
   }
   
   out2.close();
   
   char buffer3[1024];
   sprintf(buffer3,"gnuplot -persist %s",buffer2);
   
   system(buffer3);
   
#ifdef WEB_VERSION
   cout << endl << "<img src=\"/" << gnuplot_output_file << "\" align=center>" << endl;
#endif

   unlink(buffer);
   unlink(buffer2);
   return "ok";
#endif
}


syntax highlighted by Code2HTML, v. 0.9.1