package kiyut.sketsa.modules.emoticonsymbol;

import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import kiyut.sketsa.canvas.VectorCanvas;
import kiyut.sketsa.undo.DOMUndoManager;
import kiyut.sketsa.util.ColorConvertion;
import kiyut.sketsa.util.DOMUtilities;
import kiyut.sketsa.util.SVGConstants;
import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGElement;
import org.w3c.dom.svg.SVGEllipseElement;
import org.w3c.dom.svg.SVGGElement;
import org.w3c.dom.svg.SVGPathElement;
import org.w3c.dom.svg.SVGPathSegCurvetoCubicAbs;
import org.w3c.dom.svg.SVGPathSegMovetoAbs;



/**
 * Emoticon Frown symbol implementation
 * @author Kiyut
 */
public class FrownSymbol extends EmoticonSymbol {
    /** Icon */ 
    protected Icon icon;
    
    /** Tooltip Text */ 
    protected String tooltipText;
    
    protected double rx;
    protected double ry;
    
    /** Creates a new instance of FrownSymbol */
    public FrownSymbol() {
    icon = new ImageIcon(getClass().getResource("/kiyut/sketsa/modules/emoticonsymbol/frown32.png"));
        tooltipText = "Emoticon Frown Symbol";
        rx = 20;
        ry = 20;
    }
    
    /** @{inheritDoc} */
    public Icon getIcon() {
        return icon;
    }
    
    /** @{inheritDoc} */
    public String getTooltipText() {
        return tooltipText;
    }
    
    /** @{inheritDoc} */
    public void insertSymbol(VectorCanvas canvas, Point location) {
        SVGElement elt = createSVGElement(canvas,location);
        SVGDocument doc = canvas.getSVGDocument();
        Element svgRoot = doc.getDocumentElement();
        
        DOMUndoManager undoManager = canvas.getUndoManager();
        undoManager.start("Add " + tooltipText);
        try {
            svgRoot.appendChild(elt);
        } finally {
            undoManager.end();
        }
        
        List<SVGElement> newList = new ArrayList<SVGElement>();
        newList.add(elt);
        
        canvas.getCanvasSelection().setSelectionList(newList);
        canvas.refresh();
    }
    
    /** Create SVGElement
     * @param canvas VectorCanvas
     * @param location The location where the insertion should take place
     * @return SVGElement
     */
    protected SVGElement createSVGElement(VectorCanvas canvas, Point location) {
        SVGDocument doc = canvas.getSVGDocument();
        
        double[] coords = new double[4];
        coords[0] = location.getX();
        coords[1] = location.getY();
        
        AffineTransform at = canvas.getTransform(true);
        try {
            at = at.createInverse();
        } catch (NoninvertibleTransformException e) {}
        at.transform(coords,0,coords,0,2);
        
        double cx = (float)coords[0];
        double cy = (float)coords[1];

        SVGGElement elt = (SVGGElement)doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_G_TAG);
        
        // draw face
        SVGEllipseElement faceElt = (SVGEllipseElement)doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_ELLIPSE_TAG);
        faceElt.setAttributeNS(null, SVGConstants.SVG_CX_ATTRIBUTE, Float.toString((float)cx));
        faceElt.setAttributeNS(null, SVGConstants.SVG_CY_ATTRIBUTE, Float.toString((float)cy));
        faceElt.setAttributeNS(null, SVGConstants.SVG_RX_ATTRIBUTE, Float.toString((float)rx));
        faceElt.setAttributeNS(null, SVGConstants.SVG_RY_ATTRIBUTE, Float.toString((float)ry));
        DOMUtilities.updateProperty(faceElt, null, SVGConstants.SVG_STROKE_ATTRIBUTE,ColorConvertion.toHexString(java.awt.Color.BLACK));
        DOMUtilities.updateProperty(faceElt, null, SVGConstants.SVG_FILL_ATTRIBUTE,ColorConvertion.toHexString(new java.awt.Color(192,192,255)));
        elt.appendChild(faceElt);

        // draw eye
        double cx1 = cx - (rx/2);
        double cy1 = cy - (ry/3);
        double cx2 = cx + (rx/2);
        double cy2 = cy - (ry/3);;
        double rxEye = 2;
        double ryEye = 4;
        
        SVGEllipseElement eye1Elt = (SVGEllipseElement)doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_ELLIPSE_TAG);
        SVGEllipseElement eye2Elt = (SVGEllipseElement)doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_ELLIPSE_TAG);
        
        eye1Elt.setAttributeNS(null, SVGConstants.SVG_CX_ATTRIBUTE, Float.toString((float)cx1));
        eye1Elt.setAttributeNS(null, SVGConstants.SVG_CY_ATTRIBUTE, Float.toString((float)cy1));
        eye1Elt.setAttributeNS(null, SVGConstants.SVG_RX_ATTRIBUTE, Float.toString((float)rxEye));
        eye1Elt.setAttributeNS(null, SVGConstants.SVG_RY_ATTRIBUTE, Float.toString((float)ryEye));
        
        eye2Elt.setAttributeNS(null, SVGConstants.SVG_CX_ATTRIBUTE, Float.toString((float)cx2));
        eye2Elt.setAttributeNS(null, SVGConstants.SVG_CY_ATTRIBUTE, Float.toString((float)cy2));
        eye2Elt.setAttributeNS(null, SVGConstants.SVG_RX_ATTRIBUTE, Float.toString((float)rxEye));
        eye2Elt.setAttributeNS(null, SVGConstants.SVG_RY_ATTRIBUTE, Float.toString((float)ryEye));
        
        DOMUtilities.updateProperty(eye1Elt, null, SVGConstants.SVG_STROKE_ATTRIBUTE,SVGConstants.SVG_NONE_VALUE);
        DOMUtilities.updateProperty(eye1Elt, null, SVGConstants.SVG_FILL_ATTRIBUTE,ColorConvertion.toHexString(java.awt.Color.BLACK));
        DOMUtilities.updateProperty(eye2Elt, null, SVGConstants.SVG_STROKE_ATTRIBUTE,SVGConstants.SVG_NONE_VALUE);
        DOMUtilities.updateProperty(eye2Elt, null, SVGConstants.SVG_FILL_ATTRIBUTE,ColorConvertion.toHexString(java.awt.Color.BLACK));
        
        elt.appendChild(eye1Elt);
        elt.appendChild(eye2Elt);
        
        // draw mouth
        double p1x = cx - (rx/2);
        double p1y = cy + (ry/3);
        double p2x = cx + (rx/2);
        double p2y = cy + (ry/3);
        double p2cp1x = cx - (rx/4);
        double p2cp1y = cy;
        double p2cp2x = cx + (rx/4);
        double p2cp2y = cy;
        
        SVGPathElement mouthElt = (SVGPathElement)doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_PATH_TAG);
        SVGPathSegMovetoAbs pathSeg1 = mouthElt.createSVGPathSegMovetoAbs((float)p1x,(float)p1y);
        SVGPathSegCurvetoCubicAbs pathSeg2 = mouthElt.createSVGPathSegCurvetoCubicAbs((float)p2x,(float)p2y,(float)p2cp1x,(float)p2cp1y,(float)p2cp2x,(float)p2cp2y);
        mouthElt.getPathSegList().appendItem(pathSeg1);
        mouthElt.getPathSegList().appendItem(pathSeg2);
        
        DOMUtilities.updateProperty(mouthElt, null, SVGConstants.SVG_STROKE_ATTRIBUTE,ColorConvertion.toHexString(java.awt.Color.BLACK));
        DOMUtilities.updateProperty(mouthElt, null, SVGConstants.SVG_FILL_ATTRIBUTE,SVGConstants.SVG_NONE_VALUE);
        elt.appendChild(mouthElt);
        
        return elt;
    }
}
