/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
/**
 * Class: mxStencil
 *
 * Implements a generic shape which is based on a XML node as a description.
 * 
 * shape:
 * 
 * The outer element is *shape*, that has attributes:
 * 
 * - "name", string, required. The stencil name that uniquely identifies the shape.
 * - "w" and "h" are optional decimal view bounds. This defines your co-ordinate
 * system for the graphics operations in the shape. The default is 100,100.
 * - "aspect", optional string. Either "variable", the default, or "fixed". Fixed
 * means always render the shape with the aspect ratio defined by the ratio w/h.
 * Variable causes the ratio to match that of the geometry of the current vertex.
 * - "strokewidth", optional string. Either an integer or the string "inherit".
 * "inherit" indicates that the strokeWidth of the cell is only changed on scaling,
 * not on resizing. Default is "1".
 * If numeric values are used, the strokeWidth of the cell is changed on both
 * scaling and resizing and the value defines the multiple that is applied to
 * the width.
 * 
 * connections:
 * 
 * If you want to define specific fixed connection points on the shape use the
 * *connections* element. Each *constraint* element within connections defines
 * a fixed connection point on the shape. Constraints have attributes:
 * 
 * - "perimeter", required. 1 or 0. 0 sets the connection point where specified
 * by x,y. 1 Causes the position of the connection point to be extrapolated from
 * the center of the shape, through x,y to the point of intersection with the
 * perimeter of the shape.
 * - "x" and "y" are the position of the fixed point relative to the bounds of
 * the shape. They can be automatically adjusted if perimeter=1. So, (0,0) is top
 * left, (0.5,0.5) the center, (1,0.5) the center of the right hand edge of the
 * bounds, etc. Values may be less than 0 or greater than 1 to be positioned
 * outside of the shape.
 * - "name", optional string. A unique identifier for the port on the shape.
 * 
 * background and foreground:
 * 
 * The path of the graphics drawing is split into two elements, *foreground* and
 * *background*. The split is to define which part any shadow applied to the shape
 * is derived from (the background). This, generally, means the background is the
 * line tracing of the outside of the shape, but not always.
 * 
 * Any stroke, fill or fillstroke of a background must be the first element of the
 * foreground element, they must not be used within *background*. If the background
 * is empty, this is not required.
 * 
 * Because the background cannot have any fill or stroke, it can contain only one
 * *path*, *rect*, *roundrect* or *ellipse* element (or none). It can also not
 * include *image*, *text* or *include-shape*.
 * 
 * Note that the state, styling and drawing in mxGraph stencils is very close in
 * design to that of HTML 5 canvas. Tutorials on this subject, if you're not
 * familiar with the topic, will give a good high-level introduction to the
 * concepts used.
 * 
 * State:
 * 
 * Rendering within the foreground and background elements has the concept of
 * state. There are two types of operations other than state save/load, styling
 * and drawing. The styling operations change the current state, so you can save
 * the current state with <save/> and pull the last saved state from the state
 * stack using <restore/>.
 * 
 * Styling:
 * 
 * The elements that change colors within the current state all take a hash
 * prefixed hex color code ("#FFEA80").
 * 
 * - *strokecolor*, this sets the color that drawing paths will be rendered in
 * when a stroke or fillstroke command is issued.
 * - *fillcolor*, this sets the color that the inside of closed paths will be
 * rendered in when a fill or fillstroke command is issued.
 * - *fontcolor*, this sets the color that fonts are rendered in when text is drawn.
 * 
 * *alpha* defines the degree of transparency used between 1.0 for fully opaque
 * and 0.0 for fully transparent.
 * 
 * *strokewidth* defines the integer thickness of drawing elements rendered by
 * stroking. Use fixed="1" to apply the value as-is, without scaling.
 * 
 * *dashed* is "1" for dashing enabled and "0" for disabled.
 * 
 * When *dashed* is enabled the current dash pattern, defined by *dashpattern*,
 * is used on strokes. dashpattern is a sequence of space separated "on, off"
 * lengths that define what distance to paint the stroke for, then what distance
 * to paint nothing for, repeat... The default is "3 3". You could define a more
 * complex pattern with "5 3 2 6", for example. Generally, it makes sense to have
 * an even number of elements in the dashpattern, but that's not required.
 * 
 * *linejoin*, *linecap* and *miterlimit* are best explained by the Mozilla page
 * on Canvas styling (about halfway down). The values are all the same except we
 * use "flat" for linecap, instead of Canvas' "butt".
 * 
 * For font styling there are.
 * 
 * - *fontsize*, an integer,
 * - *fontstyle*, an ORed bit pattern of bold (1), italic (2) and underline (4),
 * i.e bold underline is "5".
 * - *fontfamily*, is a string defining the typeface to be used.
 * 
 * Drawing:
 * 
 * Most drawing is contained within a *path* element. Again, the graphic
 * primitives are very similar to that of HTML 5 canvas.
 * 
 * - *move* to attributes required decimals (x,y).
 * - *line* to attributes required decimals (x,y).
 * - *quad* to required decimals (x2,y2) via control point required decimals
 * (x1,y1).
 * - *curve* to required decimals (x3,y3), via control points required decimals
 * (x1,y1) and (x2,y2).
 * - *arc*, this doesn't follow the HTML Canvas signatures, instead it's a copy
 * of the SVG arc command. The SVG specification documentation gives the best
 * description of its behaviors. The attributes are named identically, they are
 * decimals and all required.
 * - *close* ends the current subpath and causes an automatic straight line to
 * be drawn from the current point to the initial point of the current subpath.
 * 
 * Complex drawing:
 * 
 * In addition to the graphics primitive operations there are non-primitive
 * operations. These provide an easy method to draw some basic shapes.
 * 
 * - *rect*, attributes "x", "y", "w", "h", all required decimals
 * - *roundrect*, attributes "x", "y", "w", "h", all required decimals. Also
 * "arcsize" an optional decimal attribute defining how large, the corner curves
 * are.
 * - *ellipse*, attributes "x", "y", "w", "h", all required decimals.
 * 
 * Note that these 3 shapes and all paths must be followed by either a fill,
 * stroke, or fillstroke.
 * 
 * Text:
 * 
 * *text* elements have the following attributes.
 * 
 * - "str", the text string to display, required.
 * - "x" and "y", the decimal location (x,y) of the text element, required.
 * - "align", the horizontal alignment of the text element, either "left",
 * "center" or "right". Optional, default is "left".
 * - "valign", the vertical alignment of the text element, either "top", "middle"
 * or "bottom". Optional, default is "top".
 * - "localized", 0 or 1, if 1 then the "str" actually contains a key to use to
 * fetch the value out of mxResources. Optional, default is
 * <mxStencil.defaultLocalized>.
 * - "vertical", 0 or 1, if 1 the label is rendered vertically (rotated by 90
 * degrees). Optional, default is 0.
 * - "rotation", angle in degrees (0 to 360). The angle to rotate the text by.
 * Optional, default is 0.
 * - "align-shape", 0 or 1, if 0 ignore the rotation of the shape when setting
 * the text rotation. Optional, default is 1.
 * 
 * If <allowEval> is true, then the text content of the this element can define
 * a function which is invoked with the shape as the only argument and returns
 * the value for the text element (ignored if the str attribute is not null).
 * 
 * Images:
 * 
 * *image* elements can either be external URLs, or data URIs, where supported
 * (not in IE 7-). Attributes are:
 * 
 * - "src", required string. Either a data URI or URL.
 * - "x", "y", required decimals. The (x,y) position of the image.
 * - "w", "h", required decimals. The width and height of the image.
 * - "flipH" and "flipV", optional 0 or 1. Whether to flip the image along the
 * horizontal/vertical axis. Default is 0 for both.
 * 
 * If <allowEval> is true, then the text content of the this element can define
 * a function which is invoked with the shape as the only argument and returns
 * the value for the image source (ignored if the src attribute is not null).
 * 
 * Sub-shapes:
 * 
 * *include-shape* allow stencils to be rendered within the current stencil by
 * referencing the sub-stencil by name. Attributes are:
 * 
 * - "name", required string. The unique shape name of the stencil.
 * - "x", "y", "w", "h", required decimals. The (x,y) position of the sub-shape
 * and its width and height.
 * 
 * Constructor: mxStencil
 * 
 * Constructs a new generic shape by setting <desc> to the given XML node and
 * invoking <parseDescription> and <parseConstraints>.
 * 
 * Parameters:
 * 
 * desc - XML node that contains the stencil description.
 */
function mxStencil(desc)
{
	this.desc = desc;
	this.parseDescription();
	this.parseConstraints();
};

/**
 * Variable: defaultLocalized
 * 
 * Static global variable that specifies the default value for the localized
 * attribute of the text element. Default is false.
 */
mxStencil.defaultLocalized = false;

/**
 * Function: allowEval
 * 
 * Static global switch that specifies if the use of eval is allowed for
 * evaluating text content and images. Default is false. Set this to true
 * if stencils can not contain user input.
 */
mxStencil.allowEval = false;

/**
 * Variable: desc
 *
 * Holds the XML node with the stencil description.
 */
mxStencil.prototype.desc = null;

/**
 * Variable: constraints
 * 
 * Holds an array of <mxConnectionConstraints> as defined in the shape.
 */
mxStencil.prototype.constraints = null;

/**
 * Variable: aspect
 *
 * Holds the aspect of the shape. Default is 'auto'.
 */
mxStencil.prototype.aspect = null;

/**
 * Variable: w0
 *
 * Holds the width of the shape. Default is 100.
 */
mxStencil.prototype.w0 = null;

/**
 * Variable: h0
 *
 * Holds the height of the shape. Default is 100.
 */
mxStencil.prototype.h0 = null;

/**
 * Variable: bgNodes
 *
 * Holds the XML node with the stencil description.
 */
mxStencil.prototype.bgNode = null;

/**
 * Variable: fgNodes
 *
 * Holds the XML node with the stencil description.
 */
mxStencil.prototype.fgNode = null;

/**
 * Variable: strokewidth
 *
 * Holds the strokewidth direction from the description.
 */
mxStencil.prototype.strokewidth = null;

/**
 * Function: parseDescription
 *
 * Reads <w0>, <h0>, <aspect>, <bgNodes> and <fgNodes> from <desc>.
 */
mxStencil.prototype.parseDescription = function()
{
	// LATER: Preprocess nodes for faster painting
	this.fgNode = this.desc.getElementsByTagName('foreground')[0];
	this.bgNode = this.desc.getElementsByTagName('background')[0];
	this.w0 = Number(this.desc.getAttribute('w') || 100);
	this.h0 = Number(this.desc.getAttribute('h') || 100);
	
	// Possible values for aspect are: variable and fixed where
	// variable means fill the available space and fixed means
	// use w0 and h0 to compute the aspect.
	var aspect = this.desc.getAttribute('aspect');
	this.aspect = (aspect != null) ? aspect : 'variable';
	
	// Possible values for strokewidth are all numbers and "inherit"
	// where the inherit means take the value from the style (ie. the
	// user-defined stroke-width). Note that the strokewidth is scaled
	// by the minimum scaling that is used to draw the shape (sx, sy).
	var sw = this.desc.getAttribute('strokewidth');
	this.strokewidth = (sw != null) ? sw : '1';
};

/**
 * Function: parseConstraints
 *
 * Reads the constraints from <desc> into <constraints> using
 * <parseConstraint>.
 */
mxStencil.prototype.parseConstraints = function()
{
	var conns = this.desc.getElementsByTagName('connections')[0];
	
	if (conns != null)
	{
		var tmp = mxUtils.getChildNodes(conns);
		
		if (tmp != null && tmp.length > 0)
		{
			this.constraints = [];
			
			for (var i = 0; i < tmp.length; i++)
			{
				this.constraints.push(this.parseConstraint(tmp[i]));
			}
		}
	}
};

/**
 * Function: parseConstraint
 *
 * Parses the given XML node and returns its <mxConnectionConstraint>.
 */
mxStencil.prototype.parseConstraint = function(node)
{
	var x = Number(node.getAttribute('x'));
	var y = Number(node.getAttribute('y'));
	var perimeter = node.getAttribute('perimeter') == '1';
	var name = node.getAttribute('name');
	
	return new mxConnectionConstraint(new mxPoint(x, y), perimeter, name);
};

/**
 * Function: evaluateTextAttribute
 * 
 * Gets the given attribute as a text. The return value from <evaluateAttribute>
 * is used as a key to <mxResources.get> if the localized attribute in the text
 * node is 1 or if <defaultLocalized> is true.
 */
mxStencil.prototype.evaluateTextAttribute = function(node, attribute, shape)
{
	var result = this.evaluateAttribute(node, attribute, shape);
	var loc = node.getAttribute('localized');
	
	if ((mxStencil.defaultLocalized && loc == null) || loc == '1')
	{
		result = mxResources.get(result);
	}

	return result;
};

/**
 * Function: evaluateAttribute
 *
 * Gets the attribute for the given name from the given node. If the attribute
 * does not exist then the text content of the node is evaluated and if it is
 * a function it is invoked with <shape> as the only argument and the return
 * value is used as the attribute value to be returned.
 */
mxStencil.prototype.evaluateAttribute = function(node, attribute, shape)
{
	var result = node.getAttribute(attribute);
	
	if (result == null)
	{
		var text = mxUtils.getTextContent(node);
		
		if (text != null && mxStencil.allowEval)
		{
			var funct = mxUtils.eval(text);
			
			if (typeof(funct) == 'function')
			{
				result = funct(shape);
			}
		}
	}
	
	return result;
};

/**
 * Function: drawShape
 *
 * Draws this stencil inside the given bounds.
 */
mxStencil.prototype.drawShape = function(canvas, shape, x, y, w, h)
{
	// TODO: Internal structure (array of special structs?), relative and absolute
	// coordinates (eg. note shape, process vs star, actor etc.), text rendering
	// and non-proportional scaling, how to implement pluggable edge shapes
	// (start, segment, end blocks), pluggable markers, how to implement
	// swimlanes (title area) with this API, add icon, horizontal/vertical
	// label, indicator for all shapes, rotation
	var direction = mxUtils.getValue(shape.style, mxConstants.STYLE_DIRECTION, null);
	var aspect = this.computeAspect(shape.style, x, y, w, h, direction);
	var minScale = Math.min(aspect.width, aspect.height);
	var sw = (this.strokewidth == 'inherit') ?
			Number(mxUtils.getNumber(shape.style, mxConstants.STYLE_STROKEWIDTH, 1)) :
			Number(this.strokewidth) * minScale;
	canvas.setStrokeWidth(sw);

	this.drawChildren(canvas, shape, x, y, w, h, this.bgNode, aspect, false);
	this.drawChildren(canvas, shape, x, y, w, h, this.fgNode, aspect, true);
};

/**
 * Function: drawChildren
 *
 * Draws this stencil inside the given bounds.
 */
mxStencil.prototype.drawChildren = function(canvas, shape, x, y, w, h, node, aspect, disableShadow)
{
	if (node != null && w > 0 && h > 0)
	{
		var tmp = node.firstChild;
		
		while (tmp != null)
		{
			if (tmp.nodeType == mxConstants.NODETYPE_ELEMENT)
			{
				this.drawNode(canvas, shape, tmp, aspect, disableShadow);
			}
			
			tmp = tmp.nextSibling;
		}
	}
};

/**
 * Function: computeAspect
 *
 * Returns a rectangle that contains the offset in x and y and the horizontal
 * and vertical scale in width and height used to draw this shape inside the
 * given <mxRectangle>.
 * 
 * Parameters:
 * 
 * shape - <mxShape> to be drawn.
 * bounds - <mxRectangle> that should contain the stencil.
 * direction - Optional direction of the shape to be darwn.
 */
mxStencil.prototype.computeAspect = function(shape, x, y, w, h, direction)
{
	var x0 = x;
	var y0 = y;
	var sx = w / this.w0;
	var sy = h / this.h0;
	
	var inverse = (direction == mxConstants.DIRECTION_NORTH || direction == mxConstants.DIRECTION_SOUTH);

	if (inverse)
	{
		sy = w / this.h0;
		sx = h / this.w0;
		
		var delta = (w - h) / 2;

		x0 += delta;
		y0 -= delta;
	}

	if (this.aspect == 'fixed')
	{
		sy = Math.min(sx, sy);
		sx = sy;
		
		// Centers the shape inside the available space
		if (inverse)
		{
			x0 += (h - this.w0 * sx) / 2;
			y0 += (w - this.h0 * sy) / 2;
		}
		else
		{
			x0 += (w - this.w0 * sx) / 2;
			y0 += (h - this.h0 * sy) / 2;
		}
	}

	return new mxRectangle(x0, y0, sx, sy);
};

/**
 * Function: drawNode
 *
 * Draws this stencil inside the given bounds.
 */
mxStencil.prototype.drawNode = function(canvas, shape, node, aspect, disableShadow)
{
	var name = node.nodeName;
	var x0 = aspect.x;
	var y0 = aspect.y;
	var sx = aspect.width;
	var sy = aspect.height;
	var minScale = Math.min(sx, sy);

	if (name == 'save')
	{
		canvas.save();
	}
	else if (name == 'restore')
	{
		canvas.restore();
	}
	else if (name == 'path')
	{
		canvas.begin();

		// Renders the elements inside the given path
		var childNode = node.firstChild;
		
		while (childNode != null)
		{
			if (childNode.nodeType == mxConstants.NODETYPE_ELEMENT)
			{
				this.drawNode(canvas, shape, childNode, aspect, disableShadow);
			}
			
			childNode = childNode.nextSibling;
		}
	}
	else if (name == 'close')
	{
		canvas.close();
	}
	else if (name == 'move')
	{
		canvas.moveTo(x0 + Number(node.getAttribute('x')) * sx, y0 + Number(node.getAttribute('y')) * sy);
	}
	else if (name == 'line')
	{
		canvas.lineTo(x0 + Number(node.getAttribute('x')) * sx, y0 + Number(node.getAttribute('y')) * sy);
	}
	else if (name == 'quad')
	{
		canvas.quadTo(x0 + Number(node.getAttribute('x1')) * sx,
				y0 + Number(node.getAttribute('y1')) * sy,
				x0 + Number(node.getAttribute('x2')) * sx,
				y0 + Number(node.getAttribute('y2')) * sy);
	}
	else if (name == 'curve')
	{
		canvas.curveTo(x0 + Number(node.getAttribute('x1')) * sx,
				y0 + Number(node.getAttribute('y1')) * sy,
				x0 + Number(node.getAttribute('x2')) * sx,
				y0 + Number(node.getAttribute('y2')) * sy,
				x0 + Number(node.getAttribute('x3')) * sx,
				y0 + Number(node.getAttribute('y3')) * sy);
	}
	else if (name == 'arc')
	{
		canvas.arcTo(Number(node.getAttribute('rx')) * sx,
				Number(node.getAttribute('ry')) * sy,
				Number(node.getAttribute('x-axis-rotation')),
				Number(node.getAttribute('large-arc-flag')),
				Number(node.getAttribute('sweep-flag')),
				x0 + Number(node.getAttribute('x')) * sx,
				y0 + Number(node.getAttribute('y')) * sy);
	}
	else if (name == 'rect')
	{
		canvas.rect(x0 + Number(node.getAttribute('x')) * sx,
				y0 + Number(node.getAttribute('y')) * sy,
				Number(node.getAttribute('w')) * sx,
				Number(node.getAttribute('h')) * sy);
	}
	else if (name == 'roundrect')
	{
		var arcsize = Number(node.getAttribute('arcsize'));

		if (arcsize == 0)
		{
			arcsize = mxConstants.RECTANGLE_ROUNDING_FACTOR * 100;
		}
		
		var w = Number(node.getAttribute('w')) * sx;
		var h = Number(node.getAttribute('h')) * sy;
		var factor = Number(arcsize) / 100;
		var r = Math.min(w * factor, h * factor);
		
		canvas.roundrect(x0 + Number(node.getAttribute('x')) * sx,
				y0 + Number(node.getAttribute('y')) * sy,
				w, h, r, r);
	}
	else if (name == 'ellipse')
	{
		canvas.ellipse(x0 + Number(node.getAttribute('x')) * sx,
			y0 + Number(node.getAttribute('y')) * sy,
			Number(node.getAttribute('w')) * sx,
			Number(node.getAttribute('h')) * sy);
	}
	else if (name == 'image')
	{
		if (!shape.outline)
		{
			var src = this.evaluateAttribute(node, 'src', shape);
			
			canvas.image(x0 + Number(node.getAttribute('x')) * sx,
				y0 + Number(node.getAttribute('y')) * sy,
				Number(node.getAttribute('w')) * sx,
				Number(node.getAttribute('h')) * sy,
				src, false, node.getAttribute('flipH') == '1',
				node.getAttribute('flipV') == '1');
		}
	}
	else if (name == 'text')
	{
		if (!shape.outline)
		{
			var str = this.evaluateTextAttribute(node, 'str', shape);
			var rotation = node.getAttribute('vertical') == '1' ? -90 : 0;
			
			if (node.getAttribute('align-shape') == '0')
			{
				var dr = shape.rotation;
	
				// Depends on flipping
				var flipH = mxUtils.getValue(shape.style, mxConstants.STYLE_FLIPH, 0) == 1;
				var flipV = mxUtils.getValue(shape.style, mxConstants.STYLE_FLIPV, 0) == 1;
				
				if (flipH && flipV)
				{
					rotation -= dr;
				}
				else if (flipH || flipV)
				{
					rotation += dr;
				}
				else
				{
					rotation -= dr;
				}
			}
	
			rotation -= node.getAttribute('rotation');
	
			canvas.text(x0 + Number(node.getAttribute('x')) * sx,
					y0 + Number(node.getAttribute('y')) * sy,
					0, 0, str, node.getAttribute('align') || 'left',
					node.getAttribute('valign') || 'top', false, '',
					null, false, rotation);
		}
	}
	else if (name == 'include-shape')
	{
		var stencil = mxStencilRegistry.getStencil(node.getAttribute('name'));
		
		if (stencil != null)
		{
			var x = x0 + Number(node.getAttribute('x')) * sx;
			var y = y0 + Number(node.getAttribute('y')) * sy;
			var w = Number(node.getAttribute('w')) * sx;
			var h = Number(node.getAttribute('h')) * sy;
			
			stencil.drawShape(canvas, shape, x, y, w, h);
		}
	}
	else if (name == 'fillstroke')
	{
		canvas.fillAndStroke();
	}
	else if (name == 'fill')
	{
		canvas.fill();
	}
	else if (name == 'stroke')
	{
		canvas.stroke();
	}
	else if (name == 'strokewidth')
	{
		var s = (node.getAttribute('fixed') == '1') ? 1 : minScale;
		canvas.setStrokeWidth(Number(node.getAttribute('width')) * s);
	}
	else if (name == 'dashed')
	{
		canvas.setDashed(node.getAttribute('dashed') == '1');
	}
	else if (name == 'dashpattern')
	{
		var value = node.getAttribute('pattern');
		
		if (value != null)
		{
			var tmp = value.split(' ');
			var pat = [];
			
			for (var i = 0; i < tmp.length; i++)
			{
				if (tmp[i].length > 0)
				{
					pat.push(Number(tmp[i]) * minScale);
				}
			}
			
			value = pat.join(' ');
			canvas.setDashPattern(value);
		}
	}
	else if (name == 'strokecolor')
	{
		canvas.setStrokeColor(node.getAttribute('color'));
	}
	else if (name == 'linecap')
	{
		canvas.setLineCap(node.getAttribute('cap'));
	}
	else if (name == 'linejoin')
	{
		canvas.setLineJoin(node.getAttribute('join'));
	}
	else if (name == 'miterlimit')
	{
		canvas.setMiterLimit(Number(node.getAttribute('limit')));
	}
	else if (name == 'fillcolor')
	{
		canvas.setFillColor(node.getAttribute('color'));
	}
	else if (name == 'alpha')
	{
		canvas.setAlpha(node.getAttribute('alpha'));
	}
	else if (name == 'fontcolor')
	{
		canvas.setFontColor(node.getAttribute('color'));
	}
	else if (name == 'fontstyle')
	{
		canvas.setFontStyle(node.getAttribute('style'));
	}
	else if (name == 'fontfamily')
	{
		canvas.setFontFamily(node.getAttribute('family'));
	}
	else if (name == 'fontsize')
	{
		canvas.setFontSize(Number(node.getAttribute('size')) * minScale);
	}
	
	if (disableShadow && (name == 'fillstroke' || name == 'fill' || name == 'stroke'))
	{
		disableShadow = false;
		canvas.setShadow(false);
	}
};
