// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2012 Thomas Klose & Torsten Schache, Hiperscan GmbH Dresden, Germany
//
//    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 3 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 details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.


using System;


namespace Hiperscan.GtkExtensions.Compiler
{
	
	public class GraphicsCompiler
	{
		public GraphicsCompiler(GraphicsObject visual_tree, GenericGraphicCompiler translator)
		{
			this.Translator = translator;
			this.VisualTree = visual_tree;
		}
		
		public void TraverseVisualTree()
		{
			this.TraverseVisualTree(this.VisualTree);
		}
		
		private void TraverseVisualTree(GraphicsObject graphics)
		{
			if (graphics is GraphicsGroup)
				this.HandleGraphicsGroup(graphics as GraphicsGroup);
			else if (graphics is GraphicsText)
				this.HandleGraphicsText(graphics as GraphicsText);
			else if (graphics is GraphicsTextParagraph)
				this.HandleGraphicsTextParagraph(graphics as GraphicsTextParagraph);
			else if (graphics is GraphicsImage)
				this.HandleGraphicsImage(graphics as GraphicsImage);
			else if (graphics is GraphicsShape)
				this.HandleGraphicsShape(graphics as GraphicsShape);
		}
		
		private void HandleGraphicsGroup(GraphicsGroup group)
		{
			this.Translator.SaveContext();
			this.Translator.PushAlpha(group.Opacity);
			this.Translator.SetTransformations(group.TransformGroup);
			
			foreach(GraphicsObject graphics in group.Children)
			{
				this.TraverseVisualTree(graphics);
			}
			
			this.Translator.SetClip(group.ClipRegion);
			this.Translator.PopAlpha();
			this.Translator.RestoreContext();
		}
		
		private void HandleGraphicsText(GraphicsText text)
		{
			this.Translator.DrawText(text);
		}
		
		private void HandleGraphicsTextParagraph(GraphicsTextParagraph paragraph)
		{
			this.Translator.DrawTextParagraph(paragraph);
		}
		
		private void HandleGraphicsImage(GraphicsImage image)
		{
			this.Translator.DrawImage(image);
		}
		
		private void HandleGraphicsShape(GraphicsShape shape)
		{
			this.Translator.NewPath();
			
			if(shape.Brush != null || shape.Pen != null)
			{
				this.Translator.NewPath();
				
				if(shape is GraphicsShapeLine)
					this.Translator.DrawLine(shape as GraphicsShapeLine);
				else if (shape is GraphicsShapeRectangle)
					this.Translator.DrawRectangle(shape as GraphicsShapeRectangle);
				else if (shape is GraphicsShapeCircle)
					this.Translator.DrawCircle(shape as GraphicsShapeCircle);
				else if (shape is GraphicsShapePolygone)
					this.Translator.DrawPolygone(shape as GraphicsShapePolygone);
				else if (shape is GraphicsShapeArc)
					this.Translator.DrawArc(shape as GraphicsShapeArc);
				
				
				if (shape.IsClosed == true)
					this.Translator.ClosePath();	
				
				this.Translator.SaveContext();
				if(shape.Brush == null && shape.Pen != null)
				{
					this.Translator.SetStroke(shape.Pen);
					this.Translator.Stroke();
				}
				else 
				{
					if(shape.Brush != null && shape.Pen != null)
					{
						this.Translator.SetStroke(shape.Pen);
						this.Translator.StrokePreverse();
						this.Translator.SetFill(shape.Brush);
						this.Translator.Fill();
					}
					else
					{
						this.Translator.SetFill(shape.Brush);
						this.Translator.Fill();
					}
				}
				this.Translator.RestoreContext();
				
			}
		}
		
		private GraphicsObject VisualTree    {get;set;}
		private GenericGraphicCompiler Translator {get;set;}
	}
}

