/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") +  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openmeetings.data.record;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.Iterator;
import java.util.List;

import javax.swing.JTextArea;

import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.openmeetings.OpenmeetingsVariables;
import org.apache.openmeetings.data.basic.dao.ConfigurationDao;
import org.apache.openmeetings.utils.geom.ArrowStyle;
import org.apache.openmeetings.utils.geom.GeomPoint;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class BatikMethods {
	
	private static final Logger log = Red5LoggerFactory.getLogger(BatikMethods.class, OpenmeetingsVariables.webAppRootKey);
	@Autowired
	private ConfigurationDao configurationDao;

	public void paintTextByWidthHeight(SVGGraphics2D g2d, int x1, int y1, int width, int height,
			String text, int style, int size, Color fontColor) throws Exception {

		//String default_export_font = Configurationmanagement.getInstance().getConfKey(3,"default_export_font").getConf_value();
		
		this.drawTextByJTextArea(g2d, x1, y1, width, height, text, "Verdana", style, size, fontColor);

	}
	
	public void _paintTextByWidthHeight(SVGGraphics2D g2d, int x1, int y1, int width, int height,
			String text, int style, int size, Color fontColor) throws Exception {

		String default_export_font = configurationDao.getConfValue("default_export_font", String.class, "");
		
		this.drawTextByString(g2d, x1, y1, width, height, text, default_export_font, style, size, fontColor);

	}
	
	@SuppressWarnings("rawtypes")
	public void drawPointsObject(Graphics2D g2d, List pointsList, Color lineColor, int size, 
			double xObj, double yObj, float alpha) throws Exception {
		
		for (Iterator iter = pointsList.iterator();iter.hasNext();) {
			List point = (List) iter.next();
			
//			log.debug("POINT FROM TO :" +
//					Double.valueOf(point.get(1).toString()).doubleValue()+","+
//					Double.valueOf(point.get(2).toString()).doubleValue()+","+ 
//					Double.valueOf(point.get(3).toString()).doubleValue()+","+
//					Double.valueOf(point.get(4).toString()).doubleValue());
			
			this.drawThickLine2DPaint(g2d, Double.valueOf(point.get(1).toString()).doubleValue(), 
					Double.valueOf(point.get(2).toString()).doubleValue(), 
					Double.valueOf(point.get(3).toString()).doubleValue(), 
					Double.valueOf(point.get(4).toString()).doubleValue(),  
					size, lineColor, xObj, yObj, alpha);
		}
		
		
	}
	
	public void drawLine(Graphics2D g2d, Double x1, Double y1, Double x2, Double y2, Color lineColor, int size, 
			double xObj, double yObj, float alpha) throws Exception {
		
		this.drawThickLine2D(g2d, x1, y1, x2, y2,  
				size, lineColor, xObj, yObj, alpha);
		
	}
	
	public void paintEllipse2D(Graphics2D g2d, double x, double y, double width, double height, 
			Color linecoler, int thickness, Color fillColor, float alpha) throws Exception {
		
		g2d.setStroke(new BasicStroke(thickness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
		
		int[] rules = new int[8]; 
		
		//all possible Compositing Rules:
		rules[0] = AlphaComposite.SRC_OVER;
		rules[1] = AlphaComposite.DST_OVER;
		rules[2] = AlphaComposite.CLEAR;
		rules[3] = AlphaComposite.SRC;
		rules[4] = AlphaComposite.SRC_IN;
		rules[5] = AlphaComposite.DST_IN;
		rules[6] = AlphaComposite.SRC_OUT;
		rules[7] = AlphaComposite.DST_OUT;
		
		g2d.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC,alpha));
		
        //int x, int y, int width, int height
        
        if (linecoler != null) {
	        g2d.setPaint(linecoler);
	        g2d.draw(new Ellipse2D.Double(x,y,width,height));
        }
        
        if (fillColor != null) {
        	g2d.setPaint(fillColor);
            g2d.fill(new Ellipse2D.Double(x,y,width,height));
        }
        
    }
	
	public void paintRect2D(Graphics2D g2d, double x, double y, double width, double height, 
			Color linecoler, int thickness, Color fillColor, float alpha) throws Exception {
		
		g2d.setStroke(new BasicStroke(thickness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
		
		int[] rules = new int[8]; 
		
		//all possible Compositing Rules:
		rules[0] = AlphaComposite.SRC_OVER;
		rules[1] = AlphaComposite.DST_OVER;
		rules[2] = AlphaComposite.CLEAR;
		rules[3] = AlphaComposite.SRC;
		rules[4] = AlphaComposite.SRC_IN;
		rules[5] = AlphaComposite.DST_IN;
		rules[6] = AlphaComposite.SRC_OUT;
		rules[7] = AlphaComposite.DST_OUT;
		
		g2d.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC,alpha));
		
        //int x, int y, int width, int height
        
        if (linecoler != null) {
	        g2d.setPaint(linecoler);
	        g2d.draw(new Rectangle2D.Double(x,y,width,height));
        }
        
        if (fillColor != null) {
        	g2d.setPaint(fillColor);
            g2d.fill(new Rectangle2D.Double(x,y,width,height));
        }
        
    }
	
	public void paintRect(Graphics2D g2d, int x, int y, int width, int height, 
			Color linecoler, int thickness, Color fillColor) throws Exception {
		
		//int x, int y, int width, int height
        //g2d.fill(new Rectangle(x,y,width,height));
        
        g2d.setStroke(new BasicStroke(thickness));
        
        if (linecoler != null) {
	        g2d.setPaint(linecoler);
	        g2d.drawRect(x, y, width, height);
        }
        
        if (fillColor != null) {
        	g2d.setPaint(fillColor);
	        g2d.fillRect(x, y, width, height);
        }
        
    }
	
	public void paintLine(Graphics2D g2d, int x1, int y1, int x2, int y2, Color col) throws Exception {
		g2d.setPaint(col);
		g2d.drawLine(x1, y1, x2, y2);
	}
	
	public void drawThickLine2DPaint(Graphics2D g2d, double x1, double y1, double x2, double y2, 
			int width, Color c, double xObj, double yObj, float alpha) throws Exception {
		g2d.setPaint(c);
		
		int[] rules = new int[8]; 
		
		//all possible Compositing Rules:
		rules[0] = AlphaComposite.SRC_OVER;
		rules[1] = AlphaComposite.DST_OVER;
		rules[2] = AlphaComposite.CLEAR;
		rules[3] = AlphaComposite.SRC;
		rules[4] = AlphaComposite.SRC_IN;
		rules[5] = AlphaComposite.DST_IN;
		rules[6] = AlphaComposite.SRC_OUT;
		rules[7] = AlphaComposite.DST_OUT;
		
		g2d.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC,alpha));
		g2d.setStroke(new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
		Line2D line = new Line2D.Double(x1, y1, x2, y2);
	    g2d.draw(line);
	}

	
	public void drawThickLine2D(Graphics2D g2d, double x1, double y1, double x2, double y2, 
			int width, Color c, double xObj, double yObj, float alpha) throws Exception {
		g2d.setPaint(c);
		
		int[] rules = new int[8]; 
		
		//all possible Compositing Rules:
		rules[0] = AlphaComposite.SRC_OVER;
		rules[1] = AlphaComposite.DST_OVER;
		rules[2] = AlphaComposite.CLEAR;
		rules[3] = AlphaComposite.SRC;
		rules[4] = AlphaComposite.SRC_IN;
		rules[5] = AlphaComposite.DST_IN;
		rules[6] = AlphaComposite.SRC_OUT;
		rules[7] = AlphaComposite.DST_OUT;
		
		g2d.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC,alpha));
		g2d.setStroke(new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
		Line2D line = new Line2D.Double(x1+xObj, y1+yObj, x2+xObj, y2+yObj);
	    g2d.draw(line);
	}

	public void drawThickLine(Graphics2D g2d, int x1, int y1, int x2, int y2, int width, Color c) throws Exception {
		g2d.setPaint(c);
		g2d.setStroke(new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
	    g2d.drawLine(x1, y1, x2, y2);
	}	
	
	public void paintTextByWidthHeightAndDocument(SVGGraphics2D g2d, int x1, int y1, int width, int height,
			String text, int style, int size, Color fontColor, Document document) throws Exception {

		// String default_export_font =
		// Configurationmanagement.getInstance().getConfKey("default_export_font").getConf_value();
		
		this.drawText(g2d, x1, y1, width, height, text, "Verdana", style, size, fontColor, document);

	}

	public void drawText(SVGGraphics2D g2d, int x, int y, int width, int height, 
			String text, String default_export_font, int style, int size, Color fontColor,
			Document document) throws Exception {
		
//		g2d.setClip(x, y, width, height);
//		g2d.setColor(Color.black);
//		g2d.drawString(text, x, y+20);
		
		String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;

		// Get the root element (the 'svg' element).
		Element svgRoot = document.getDocumentElement();

		log.debug("svgNS DEBUG: "+svgNS);
		
		//Element textElement = g2d.getDOMFactory().createElementNS(svgNS,"text");
		Element rectangle = document.createElementNS(svgNS, "rect");
		rectangle.setAttributeNS(svgNS, "x", "10");
		rectangle.setAttributeNS(svgNS, "y", "20");
		rectangle.setAttributeNS(svgNS, "width", "100");
		rectangle.setAttributeNS(svgNS, "height", "50");
		rectangle.setAttributeNS(svgNS, "fill", "red");

		// Attach the rectangle to the root 'svg' element.
		svgRoot.appendChild(rectangle);


	}
	
	public void drawTextByString(SVGGraphics2D g2d, int x, int y, int width, int height, 
			String text, String default_export_font, int style, int size, Color fontColor) throws Exception {
		
		//g2d.setClip(x, y, width, height);
		g2d.setColor(Color.black);
		g2d.drawString(text, x, y);
		
		
	}

	public void drawTextByJTextArea(Graphics2D g2d, int x, int y, int width, int height, 
			String text, String default_export_font, int style, int size, Color fontColor) throws Exception {
		
//		g2d.setClip(x, y, width, height);
//		g2d.setColor(Color.black);
//		g2d.drawString(text, x, y+20);
		
		//Font font = new Font("Verdana", Font.PLAIN, 11);
		Font font = new Font(default_export_font, style, size);

		String[] stringsText = text.split("\r");
		//log.debug("TEXT: "+stringsText);
		//log.debug("TEXT: "+stringsText.length);
		
		String newText = "";
		
		for (int i=0;i<stringsText.length;i++) {
			newText += stringsText[i];
			if (i+1<stringsText.length) {
				newText += "\n";
			}
		}
		
		JTextArea n = new JTextArea( newText );
		n.setFont(font);
		n.setWrapStyleWord( true );
		n.setLineWrap( true );
		n.setForeground( fontColor );
		
		//log.debug("Text at: "+x+" "+y);
			//int x, int y, int width, int height
		n.setBounds( x, y , width, height );
		n.setOpaque( false );
		
		//Text
		SVGGraphics2D svgGenerator2 = (SVGGraphics2D) g2d.create(x, y, width, height);

		//svgGenerator2.create(x, y, width, height);
		//svgGenerator2.draw(.dra)
		n.paint( svgGenerator2 );
		
	}
	

	public void drawArrow(SVGGraphics2D g2d,
			GeomPoint start, GeomPoint end, float thickness, float alpha,
			Color linecoler, Color fillColor) {
		
		if (start.equals(end)) return;
		
		
//		(double edgeControlPosition, double edgeControlSize,
//				double headLength, double headWidth, double shaftControlPosition,
//				double shaftControlSize, float shaftPosition, double shaftThickness)
		ArrowStyle arrowStyle = new ArrowStyle(0.5, 0.5, thickness*5, 
				thickness*5, 0.5, 0.5, 0, thickness);
		
		GeomPoint fullVect = end.subtract(start);
		double halfWidth = (arrowStyle.headWidth != -1) ? arrowStyle.headWidth/2 : arrowStyle.headLength/2; 
		
		//Figure out the line start/end points
		GeomPoint startNorm = new GeomPoint();
		startNorm.setLocation(fullVect.getY(),-fullVect.getX());
		startNorm.normalize(arrowStyle.shaftThickness/2);
		GeomPoint start1 = start.add(startNorm);
		GeomPoint start2 = start.subtract(startNorm);
		GeomPoint end1 = end.add(startNorm);
		GeomPoint end2 = end.subtract(startNorm);
				
		//log.debug("startNorm: "+startNorm.toString());
        //log.debug("start1: "+start1.toString());
        //log.debug("start2: "+start2.toString());
        //log.debug("end1: "+end1.toString());
        //log.debug("end2: "+end2.toString());
		
		//figure out where the arrow head starts
		GeomPoint headPnt = fullVect.clone();
		//log.debug("headPnt 1: "+headPnt.toString());
		//log.debug("headPnt.length 1: "+headPnt.length());
		//log.debug("arrowStyle.headLength 1: "+arrowStyle.headLength);
		headPnt.normalize(headPnt.length()-arrowStyle.headLength);
		//log.debug("headPnt 2: "+headPnt.toString());
		headPnt = headPnt.add(start);
		//log.debug("headPnt 3: "+headPnt.toString());
		
		//calculate the arrowhead corners
		GeomPoint headPntNorm = startNorm.clone();
		//log.debug("headPntNorm ^^: "+headPntNorm.toString());
		//log.debug("halfWidth ^^: "+halfWidth);
		headPntNorm.normalize(halfWidth);
		//log.debug("headPntNorm: "+headPntNorm.toString());
		GeomPoint edge1 = headPnt.add(headPntNorm);
		GeomPoint edge2 = headPnt.subtract(headPntNorm);
		
		//log.debug("edge1: "+edge1.toString());
        //log.debug("edge2: "+edge2.toString());
		
		//Figure out where the arrow connects the the shaft, then calc the intersections
		GeomPoint shaftCenter = GeomPoint.interpolate(end,headPnt,arrowStyle.shaftPosition);
		//log.debug("end"+end.toString());
		//log.debug("headPnt: "+headPnt.toString());
		//log.debug("arrowStyle.shaftPosition: "+arrowStyle.shaftPosition);
		//log.debug("shaftCenter: "+shaftCenter);
		//log.debug("edge1: "+edge1);
		//shaftCenter.setLocation(185.857864376269, 185.857864376269);
		GeomPoint inter1 = GeomPoint.getLineIntersection(start1,end1,shaftCenter,edge1);
		GeomPoint inter2 = GeomPoint.getLineIntersection(start2,end2,shaftCenter,edge2);
		
		//log.debug("inter1: "+inter1.toString());
        //log.debug("inter2: "+inter2.toString());
		
		//Figure out the control points
		GeomPoint edgeCenter = GeomPoint.interpolate(end,headPnt,(float) arrowStyle.edgeControlPosition);
		GeomPoint edgeNorm = startNorm.clone();
		edgeNorm.normalize(halfWidth*arrowStyle.edgeControlSize);
		//log.debug("halfWidth*arrowStyle.edgeControlSize: "+(halfWidth*arrowStyle.edgeControlSize));
		//log.debug("edgeNorm: "+edgeNorm.toString());
		GeomPoint edgeCntrl1 = edgeCenter.add(edgeNorm);
		GeomPoint edgeCntrl2 = edgeCenter.subtract(edgeNorm);
		
		//log.debug("edgeCntrl1: "+edgeCntrl1.toString());
        //log.debug("edgeCntrl2: "+edgeCntrl2.toString());

		g2d.setPaint(new Color(255,0,0));
		
//		graphics.moveTo(start1.x,start1.y);
//		graphics.lineTo(inter1.x,inter1.y);
//		graphics.lineTo(edge1.x,edge1.y);
//		graphics.curveTo(edgeCntrl1.x,edgeCntrl1.y,end.x,end.y);
//		graphics.curveTo(edgeCntrl2.x,edgeCntrl2.y,edge2.x,edge2.y);
//		graphics.lineTo(inter2.x,inter2.y);
//		graphics.lineTo(start2.x,start2.y);
//		graphics.lineTo(start1.x,start1.y);
		
//		log.debug("moveTo"+start1.x+","+start1.y);
//		log.debug("lineTo"+inter1.x+","+inter1.y);
//		log.debug("lineTo"+edge1.x+","+edge1.y);
//		log.debug("quadTo"+edgeCntrl1.x+","+edgeCntrl1.y+","+end.x+","+end.y);
//		log.debug("quadTo"+edgeCntrl2.x+","+edgeCntrl2.y+","+edge2.x+","+edge2.y);
//		log.debug("lineTo"+inter2.x+","+inter2.y);
//		log.debug("lineTo"+start2.x+","+start2.y);
//		log.debug("lineTo"+start1.x+","+start1.y);
		
		GeneralPath graphics = new GeneralPath();
		graphics.moveTo(start1.x,start1.y);
		graphics.lineTo(inter1.x,inter1.y);
		graphics.lineTo(edge1.x,edge1.y);
		graphics.quadTo(edgeCntrl1.x,edgeCntrl1.y,end.x,end.y);
		graphics.quadTo(edgeCntrl2.x,edgeCntrl2.y,edge2.x,edge2.y);
		graphics.lineTo(inter2.x,inter2.y);
		graphics.lineTo(start2.x,start2.y);
		graphics.lineTo(start1.x,start1.y);
		graphics.closePath();
		
		int[] rules = new int[8]; 
		
		//all possible Compositing Rules:
		rules[0] = AlphaComposite.SRC_OVER;
		rules[1] = AlphaComposite.DST_OVER;
		rules[2] = AlphaComposite.CLEAR;
		rules[3] = AlphaComposite.SRC;
		rules[4] = AlphaComposite.SRC_IN;
		rules[5] = AlphaComposite.DST_IN;
		rules[6] = AlphaComposite.SRC_OUT;
		rules[7] = AlphaComposite.DST_OUT;
		
		g2d.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC,alpha));
		g2d.setStroke(new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
		
		if (linecoler != null) {
	        g2d.setPaint(linecoler);
	        g2d.draw(graphics);
        }
        
        if (fillColor != null) {
        	g2d.setPaint(fillColor);
	        g2d.fill(graphics);
        }
        
	}
	

	
	
	
	
	
	public String workAroundPixelErrorInSVG(String xmlDef) throws Exception {
		String resultingString = "";
        
        boolean byPassedFirst = false;
        
        while (xmlDef.indexOf("font-size:") != -1) {
        	
        	log.debug("xmlDef "+xmlDef);
        	int i = xmlDef.indexOf("font-size:");
        	
        	log.debug("Found i "+i);
        	if (byPassedFirst) {
        		log.debug("byPassedFirst DO PROCESS ");
	        	String start = xmlDef.substring(0, i+10);
	        	xmlDef = xmlDef.substring(i+10, xmlDef.length());
	        	log.debug("byPassedFirst FIRST PART Process "+start);
	        	log.debug("byPassedFirst END PART Process "+xmlDef);
	        	
	        	int firstSemicolon = xmlDef.indexOf(";");
	        	log.debug("firstSemicolon "+firstSemicolon);
	        	String fontSize = xmlDef.substring(0, firstSemicolon);
	        	log.debug("fontSize "+fontSize);
	        	
	        	xmlDef = xmlDef.substring(firstSemicolon, xmlDef.length());
	        	
	        	resultingString += start + fontSize + "px";
        	} else {
        		log.debug("byPassedFirst DO NOT PROCESS ");
        		String start = xmlDef.substring(0, i+10);
        		log.debug("byPassedFirst FIRST PART "+start);
        		xmlDef = xmlDef.substring(i+10, xmlDef.length());
        		log.debug("byPassedFirst END PART "+xmlDef);
        		resultingString += start;
        		byPassedFirst = true;
        	}
        }
        
        resultingString += xmlDef;
        
        log.debug("###################### ");
        log.debug("resultingString "+resultingString);
        
        return resultingString;
	}
	
}
