/**
 * SphericalLib.PovWriter
 * 
 * SphericalLib is a .NET library to deal with geometry on the unit sphere.
 * It is intented to be used for complex survey footprint descriptions in
 * standalone applications as well as in web services and perhaps Yukon.
 * 
 * Written by Tamas Budavari (budavari@pha.jhu.edu)
 * See bottom of file for revision history
 * 
 * Current revision:
 *   ID:          $Id: PovWriter.cs,v 1.1.1.1 2006/11/14 02:56:46 gupchup Exp $
 *   Revision:    $Revision: 1.1.1.1 $
 *   Date:        $Date: 2006/11/14 02:56:46 $
 */
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Spherical;

namespace hcalc
{
    /// <summary>
    /// Minimalist class to write POV-Ray files that can be rendered
    /// </summary>
    public class PovWriter
    {
        private TextWriter text;
        private List<Cartesian> colors;

        public List<Cartesian> Colors
        {
            get { return colors; }
        }

        /// <summary>
        /// Create writer with output path
        /// </summary>
        /// <param name="path"></param>
        public PovWriter(string path)
        {
            if (!path.EndsWith(".pov")) path = path + ".pov";
            FileStream output = new FileStream(path, FileMode.Create);
            text = new StreamWriter(output);
            colors = new List<Cartesian>();
            this.InitColors();
        }

        /// <summary>
        /// Create writer with output stream
        /// </summary>
        /// <param name="output"></param>
        public PovWriter(Stream output)
        {
            text = new StreamWriter(output);
            colors = new List<Cartesian>();
            this.InitColors();
        }

        /// <summary>
        /// Create from TextWriter
        /// </summary>
        /// <param name="writer"></param>
        public PovWriter(TextWriter writer)
        {
            text = writer;
            colors = new List<Cartesian>();
            this.InitColors();
        }

        /// <summary>
        /// Clore text writer
        /// </summary>
        public void Close()
        {
            this.text.Close();
        }

        /// <summary>
        /// Default colors of convexes
        /// </summary>
        private void InitColors()
        {
            colors.Add(new Cartesian(1, 0, 0, false));
            colors.Add(new Cartesian(0, 1, 0, false));
            colors.Add(new Cartesian(0, 0, 1, false));
            colors.Add(new Cartesian(1, 1, 0, false));
            colors.Add(new Cartesian(1, 0, 1, false));
            colors.Add(new Cartesian(0, 1, 1, false));
            colors.Add(new Cartesian(0, 0, 0, false));
        }

        /// <summary>
        /// Point representation in POV format
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static string Repr(Cartesian p)
        {
            return String.Format("<{0},{1},{2}>", p.X, p.Y, p.Z);
        }

        /// <summary>
        /// Write a convex
        /// </summary>
        /// <param name="c"></param>
        public void Write(Convex c, int index)
        {
            text.WriteLine("#declare convex{0} = intersection {{", index);
            foreach (Halfspace h in c.HalfspaceList)
                text.WriteLine("    object {{ plane {{ {0}, {1} inverse }}}}", 
                    PovWriter.Repr(h.Vector), h.Cos0);
            text.WriteLine("};");
        }

        /// <summary>
        /// Write a barebone region (no environment written, e.g. camera)
        /// </summary>
        /// <param name="region"></param>
        public void Write(Region region)
        {
            text.WriteLine("// convexes are pure geometry");
            for (int i = 0; i < region.ConvexList.Count; i++)
                this.Write(region.ConvexList[i], i);
        }

        /// <summary>
        /// Write region, camera and basic environment - output can be rendered
        /// </summary>
        /// <param name="region"></param>
        /// <param name="camera"></param>
        public void Write(Region region, Cartesian camera, double angle)
        {
            // dump geometry
            this.Write(region);

            // spheres are the look
            text.WriteLine("\n// spheres have the look");
            for (int i=0; i < region.ConvexList.Count; i++)
                text.WriteLine("#declare sphere{0} = sphere {{0,1 pigment {{rgb {1}}}}};", 
                    i, PovWriter.Repr(this.colors[i % this.colors.Count]));
            // rest of the sphere
            text.WriteLine
                ("#declare sphere{0} = sphere {{0,1 pigment {{rgb <1.5,1.5,1>}}}};", 
                region.ConvexList.Count);

            // region def
            text.WriteLine("\n// region definition");
            text.WriteLine("#declare region = union {");
            for (int i=0; i < region.ConvexList.Count; i++)
                text.WriteLine
                    ("    intersection {{object {{sphere{0}}} object {{convex{0}}}}}", i);
            text.WriteLine("};");

            // object to render
            text.WriteLine("\n// object to render");
            text.WriteLine("union {{object {{region}} difference {{object {{sphere{0}}}", 
                region.ConvexList.Count);
            for (int i=0; i < region.ConvexList.Count; i++)
                text.WriteLine("    object {{convex{0}}}", i);
            text.WriteLine("}}");

            // other scene params
            text.WriteLine("\n// camera, light and background");
            text.WriteLine("#declare cam = {0};", PovWriter.Repr(camera));
            text.Write("camera { location cam look_at 0 angle ");
            text.Write("{0}", angle);
            text.WriteLine("}");
            text.WriteLine("light_source { cam rgb <1,1,1> }");
            text.WriteLine("background {rgb <0.5,0.5,0.5>}");
        }

        /// <summary>
        /// Revision from CVS
        /// </summary>
        public static string Revision
        {
            get { return "$Revision: 1.1.1.1 $"; }
        }
    }
}

#region Revision History
/* Revision History

        $Log: PovWriter.cs,v $
        Revision 1.1.1.1  2006/11/14 02:56:46  gupchup
        no message

        Revision 1.1  2006/05/18 20:09:57  gyuri
        Interim checkim

        Revision 1.1  2006/02/28 16:36:59  budavari
        Module has IO related classes

        Revision 1.1  2006/01/24 15:56:05  budavari
        Re-structured directory layout to accommodate more projects

        Revision 1.2  2006/01/05 10:09:29  budavari
        A first working version

        Revision 1.1  2005/12/29 14:24:30  budavari
        Not functional placeholder

*/
#endregion