1/**
2 * $Id: mxPidValves.js,v 1.5 2013/10/22 12:55:55 mate Exp $
3 * Copyright (c) 2006-2013, JGraph Ltd
4 */
5
6//**********************************************************************************************************************************************************
7//Valve
8//**********************************************************************************************************************************************************
9/**
10 * Extends mxShape.
11 */
12function mxShapePidValve(bounds, fill, stroke, strokewidth)
13{
14	mxShape.call(this);
15	this.bounds = bounds;
16	this.fill = fill;
17	this.stroke = stroke;
18	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
19};
20
21/**
22 * Extends mxShape.
23 */
24mxUtils.extend(mxShapePidValve, mxShape);
25
26mxShapePidValve.prototype.cst = {
27		SHAPE_VALVE : 'mxgraph.pid2valves.valve',
28		//states
29		DEFAULT_STATE : 'defState',
30		CLOSED : 'closed',
31		OPEN : 'open',
32		//actuators
33		ACTUATOR : 'actuator',
34		MANUAL : 'man',
35		DIAPHRAGM : 'diaph',
36		BALANCED_DIAPHRAGM : 'balDiaph',
37		MOTOR : 'motor',
38		NONE : 'none',
39		SPRING : 'spring',
40		PILOT : 'pilot',
41		POWERED: 'powered',
42		SOLENOID : 'solenoid',
43		SOLENOID_MANUAL_RESET : 'solenoidManRes',
44		SINGLE_ACTING : 'singActing',
45		DOUBLE_ACTING : 'dblActing',
46		PILOT_CYLINDER : 'pilotCyl',
47		DIGITAL : 'digital',
48		WEIGHT : 'weight',
49		KEY : 'key',
50		ELECTRO_HYDRAULIC : 'elHyd',
51		//types
52		VALVE_TYPE : 'valveType',
53		BUTTERFLY : 'butterfly',
54		CHECK : 'check',
55		GATE : 'gate',
56		GLOBE : 'globe',
57		NEEDLE : 'needle',
58		PLUG : 'plug',
59		SELF_DRAINING : 'selfDrain',
60		ANGLE : 'angle',
61		ANGLE_GLOBE : 'angleGlobe',
62		THREE_WAY : 'threeWay',
63		ANGLE_BLOWDOWN : 'angBlow',
64		BALL : 'ball'
65};
66
67mxShapePidValve.prototype.customProperties = [
68	{name: 'defState', dispName: 'Default State', type: 'enum', defVal:'open',
69		enumList: [
70			{val:'closed', dispName:'Closed'},
71			{val:'open', dispName:'Open'}
72	]},
73	{name: 'actuator', dispName: 'Actuator', type: 'enum', defVal:'man',
74		enumList: [
75			{val:'man', dispName:'Manual'},
76			{val:'diaph', dispName:'Diphragm'},
77			{val:'balDiaph', dispName:'Balanced Diaphragm'},
78			{val:'motor', dispName:'Motor'},
79			{val:'none', dispName:'None'},
80			{val:'spring', dispName:'Spring'},
81			{val:'pilot', dispName:'Pilot'},
82			{val:'powered', dispName:'Powered'},
83			{val:'solenoid', dispName:'Solenoid'},
84			{val:'solenoidManRes', dispName:'Solenoid w/ Manual Reset'},
85			{val:'singActing', dispName:'Single Acting'},
86			{val:'dblActing', dispName:'Double Acting'},
87			{val:'pilotCyl', dispName:'Pilot Cylinder'},
88			{val:'digital', dispName:'Digital'},
89			{val:'weight', dispName:'Weight'},
90			{val:'key', dispName:'Key'},
91			{val:'elHyd', dispName:'Electro-Hidraulic'}
92	]},
93	{name: 'valveType', dispName: 'Type', type: 'enum', defVal:'gate',
94		enumList: [
95			{val:'butterfly', dispName:'Butterfly'},
96			{val:'check', dispName:'check'},
97			{val:'gate', dispName:'Gate'},
98			{val:'globe', dispName:'Globe'},
99			{val:'needle', dispName:'Needle'},
100			{val:'plug', dispName:'Plug'},
101			{val:'selfDrain', dispName:'Self Draining'},
102			{val:'angle', dispName:'Angle'},
103			{val:'angleGlobe', dispName:'Angle Globe'},
104			{val:'threeWay', dispName:'Three Way'},
105//			{val:'angBlow', dispName:'Angle Blowdown'},
106			{val:'ball', dispName:'Ball'}
107	]},
108];
109
110/**
111 * Function: paintVertexShape
112 *
113 * Paints the vertex shape.
114 */
115mxShapePidValve.prototype.paintVertexShape = function(c, x, y, w, h)
116{
117	var valveType = mxUtils.getValue(this.style, mxShapePidValve.prototype.cst.VALVE_TYPE, 'gate');
118	var actuator = mxUtils.getValue(this.style, mxShapePidValve.prototype.cst.ACTUATOR, mxShapePidValve.prototype.cst.NONE);
119	var actH = 0;
120
121	if (actuator !== 'none')
122	{
123		if (this.isAngleVariant(valveType))
124		{
125			actH = h * 0.3333;
126		}
127		else
128		{
129			actH = h * 0.4;
130		}
131	}
132
133	c.translate(x, y);
134	c.setLineJoin('round');
135
136	this.background(c, x, y, w, h, valveType, actuator, actH);
137	c.setShadow(false);
138	this.foreground(c, x, y, w, h, valveType, actuator, actH);
139};
140
141mxShapePidValve.prototype.background = function(c, x, y, w, h, valveType, actuator, actH)
142{
143	//draw the actuator
144	if (actuator !== mxShapePidValve.prototype.cst.NONE)
145	{
146		if (this.isAngleVariant(valveType))
147		{
148			this.drawActuatorBg(c, x, y, w, h / 1.2, actuator, actH);
149		}
150		else
151		{
152			this.drawActuatorBg(c, x, y, w, h, actuator, actH);
153		}
154	}
155
156	//draw the valve body
157	if (this.isGateVariant(valveType))
158	{
159		this.drawGateVariantBg(c, 0, 0, w, h, valveType, actuator, actH);
160	}
161	else if (this.isAngleVariant(valveType))
162	{
163		this.drawAngleVariantBg(c, 0, 0, w, h, valveType, actuator, actH);
164	}
165	else if (valveType === mxShapePidValve.prototype.cst.BUTTERFLY)
166	{
167		this.drawButterflyValve(c, 0, 0, w, h, actuator, actH);
168	}
169	else if (valveType === mxShapePidValve.prototype.cst.CHECK)
170	{
171		this.drawCheckValve(c, 0, 0, w, h, actuator, actH);
172	}
173};
174
175mxShapePidValve.prototype.foreground = function(c, x, y, w, h, valveType, actuator, actH)
176{
177	var valveType = mxUtils.getValue(this.style, mxShapePidValve.prototype.cst.VALVE_TYPE, 'gate');
178
179	//draw the actuator
180	if (actuator !== mxShapePidValve.prototype.cst.NONE)
181	{
182		if (this.isAngleVariant(valveType))
183		{
184			this.drawActuatorFg(c, x, y, w, h / 1.2, actuator, actH);
185		}
186		else
187		{
188			this.drawActuatorFg(c, x, y, w, h, actuator, actH);
189		}
190	}
191
192	if (this.isGateVariant(valveType))
193	{
194		this.drawGateVariantFg(c, 0, 0, w, h, valveType, actuator, actH);
195	}
196	if (this.isAngleVariant(valveType))
197	{
198		this.drawAngleVariantFg(c, 0, 0, w, h, valveType, actuator, actH);
199	}
200};
201
202mxShapePidValve.prototype.drawActuatorBg = function(c, x, y, w, h, actuator)
203{
204	if (this.isSquareVariant(actuator))
205	{
206		c.translate(w * 0.325, 0);
207		this.drawSquareAct(c, w * 0.35, h * 0.7, actuator);
208		c.translate(- w * 0.325, 0);
209	}
210	else if (actuator === mxShapePidValve.prototype.cst.MANUAL)
211	{
212		c.translate(w * 0.25, h * 0.15);
213		this.drawManAct(c, w * 0.5, h * 0.55);
214		c.translate(- w * 0.25, - h * 0.15);
215	}
216	else if (actuator === mxShapePidValve.prototype.cst.DIAPHRAGM)
217	{
218		c.translate(w * 0.25, h * 0.1);
219		this.drawDiaphAct(c, w * 0.5, h * 0.6);
220		c.translate(- w * 0.25, - h * 0.1);
221	}
222	else if (actuator === mxShapePidValve.prototype.cst.BALANCED_DIAPHRAGM)
223	{
224		c.translate(w * 0.25, h * 0.1);
225		this.drawBalDiaphActBg(c, w * 0.5, h * 0.6);
226		c.translate(- w * 0.25, - h * 0.1);
227	}
228	else if (actuator === mxShapePidValve.prototype.cst.MOTOR || actuator === mxShapePidValve.prototype.cst.ELECTRO_HYDRAULIC)
229	{
230		c.translate(w * 0.325, 0);
231		this.drawCircleAct(c, w * 0.35, h * 0.7, actuator);
232		c.translate(- w * 0.325, 0);
233	}
234	else if (actuator === mxShapePidValve.prototype.cst.SPRING)
235	{
236		c.translate(w * 0.36, 0);
237		this.drawSpringAct(c, w * 0.28, h * 0.7);
238		c.translate(- w * 0.36, 0);
239	}
240	else if (actuator === mxShapePidValve.prototype.cst.SOLENOID_MANUAL_RESET)
241	{
242		c.translate(w * 0.325, 0);
243		this.drawSolenoidManResetAct(c, w * 0.575, h * 0.7);
244		c.translate(- w * 0.325, 0);
245	}
246	else if (actuator === mxShapePidValve.prototype.cst.SINGLE_ACTING)
247	{
248		c.translate(w * 0.35, 0);
249		this.drawSingActingActBg(c, w * 0.65, h * 0.7);
250		c.translate(- w * 0.35, 0);
251	}
252	else if (actuator === mxShapePidValve.prototype.cst.DOUBLE_ACTING)
253	{
254		c.translate(w * 0.35, 0);
255		this.drawDblActingActBg(c, w * 0.65, h * 0.7);
256		c.translate(- w * 0.35, 0);
257	}
258	else if (actuator === mxShapePidValve.prototype.cst.PILOT_CYLINDER)
259	{
260		c.translate(w * 0.35, 0);
261		this.drawPilotCylinderActBg(c, w * 0.65, h * 0.7);
262		c.translate(- w * 0.35, 0);
263	}
264	else if (actuator === mxShapePidValve.prototype.cst.ANGLE_BLOWDOWN)
265	{
266		c.translate(w * 0.5, h * 0.2);
267		this.drawAngleBlowdownAct(c, w * 0.4, h * 0.5);
268		c.translate(- w * 0.5, - h * 0.2);
269	}
270};
271
272mxShapePidValve.prototype.drawActuatorFg = function(c, x, y, w, h, actuator)
273{
274	if (actuator === mxShapePidValve.prototype.cst.BALANCED_DIAPHRAGM)
275	{
276		c.translate(w * 0.25, h * 0.1);
277		this.drawBalDiaphActFg(c, w * 0.5, h * 0.6);
278		c.translate(- w * 0.25, - h * 0.1);
279	}
280	else if (actuator === mxShapePidValve.prototype.cst.SINGLE_ACTING ||
281			actuator === mxShapePidValve.prototype.cst.DOUBLE_ACTING ||
282			actuator === mxShapePidValve.prototype.cst.PILOT_CYLINDER)
283	{
284		c.translate(w * 0.35, 0);
285		this.drawActingActFg(c, w * 0.65, h * 0.7);
286		c.translate(- w * 0.35, 0);
287	}
288};
289
290mxShapePidValve.prototype.drawManAct = function(c, w, h)
291{
292	c.begin();
293	c.moveTo(0, 0);
294	c.lineTo(w, 0);
295	c.moveTo(w * 0.5, 0);
296	c.lineTo(w * 0.5, h);
297	c.stroke();
298};
299
300mxShapePidValve.prototype.drawDiaphAct = function(c, w, h)
301{
302	c.begin();
303	c.moveTo(w * 0.5, h * 0.2);
304	c.lineTo(w * 0.5, h);
305	c.stroke();
306
307	c.begin();
308	c.moveTo(0, h * 0.2);
309	c.arcTo(w * 0.6, h * 0.4, 0, 0, 1, w, h * 0.2);
310	c.close();
311	c.fillAndStroke();
312};
313
314mxShapePidValve.prototype.drawBalDiaphActBg = function(c, w, h)
315{
316	c.ellipse(0, 0, w, h * 0.3);
317	c.fillAndStroke();
318
319	c.begin();
320	c.moveTo(w * 0.5, h * 0.3);
321	c.lineTo(w * 0.5, h);
322	c.stroke();
323};
324
325mxShapePidValve.prototype.drawBalDiaphActFg = function(c, w, h)
326{
327	c.begin();
328	c.moveTo(0, h * 0.15);
329	c.lineTo(w, h * 0.15);
330	c.stroke();
331};
332
333mxShapePidValve.prototype.drawCircleAct = function(c, w, h, actuator)
334{
335	c.ellipse(0, 0, w, h * 0.5);
336	c.fillAndStroke();
337
338	c.begin();
339	c.moveTo(w * 0.5, h * 0.5);
340	c.lineTo(w * 0.5, h);
341	c.stroke();
342
343	var m = '';
344
345	if (actuator === mxShapePidValve.prototype.cst.MOTOR)
346	{
347		m = 'M';
348	}
349	else if (actuator === mxShapePidValve.prototype.cst.ELECTRO_HYDRAULIC)
350	{
351		m = 'E/H';
352	}
353
354	c.setFontStyle(1);
355	c.setFontFamily('Helvetica');
356	c.setFontSize(Math.min(w, h) * 0.4);
357	c.text(w * 0.5, h * 0.25, 0, 0, m, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
358};
359
360mxShapePidValve.prototype.drawSpringAct = function(c, w, h)
361{
362	c.begin();
363	c.moveTo(w * 0.5, 0);
364	c.lineTo(w * 0.5, h);
365	c.moveTo(w * 0.32, h * 0.16);
366	c.lineTo(w * 0.68, h * 0.08);
367	c.moveTo(w * 0.21, h * 0.32);
368	c.lineTo(w * 0.79, h * 0.20);
369	c.moveTo(w * 0.1, h * 0.52);
370	c.lineTo(w * 0.9, h * 0.36);
371	c.moveTo(0, h * 0.72);
372	c.lineTo(w, h * 0.5);
373	c.stroke();
374};
375
376mxShapePidValve.prototype.drawSolenoidManResetAct = function(c, w, h)
377{
378	c.rect(0, 0, w * 0.61, h * 0.46);
379	c.fillAndStroke();
380
381	c.begin();
382	c.moveTo(w * 0.56, h * 0.6);
383	c.lineTo(w * 0.78, h * 0.5);
384	c.lineTo(w, h * 0.6);
385	c.lineTo(w * 0.78, h * 0.7);
386	c.close();
387	c.fillAndStroke();
388
389	c.begin();
390	c.moveTo(w * 0.305, h * 0.46);
391	c.lineTo(w * 0.305, h);
392	c.moveTo(w * 0.305, h * 0.6);
393	c.lineTo(w * 0.56, h * 0.6);
394	c.stroke();
395
396	c.setFontStyle(1);
397	c.setFontFamily('Helvetica');
398	c.setFontSize(Math.min(w, h) * 0.4);
399	c.text(w * 0.305, h * 0.23, 0, 0, 'S', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
400
401	c.setFontStyle(0);
402	c.setFontSize(Math.min(w, h) * 0.15);
403	c.text(w * 0.78, h * 0.6, 0, 0, 'R', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
404};
405
406mxShapePidValve.prototype.drawSingActingActBg = function(c, w, h)
407{
408	c.rect(0, 0, w * 0.46, h * 0.46);
409	c.fillAndStroke();
410
411	c.begin();
412	c.moveTo(w * 0.23, h * 0.46);
413	c.lineTo(w * 0.23, h);
414	c.moveTo(w * 0.46, h * 0.23);
415	c.lineTo(w, h * 0.23);
416	c.moveTo(w * 0.77, h * 0.15);
417	c.lineTo(w * 0.69, h * 0.31);
418	c.moveTo(w * 0.82, h * 0.15);
419	c.lineTo(w * 0.74, h * 0.31);
420	c.stroke();
421};
422
423mxShapePidValve.prototype.drawActingActFg = function(c, w, h)
424{
425	c.begin();
426	c.moveTo(w * 0.23, h * 0.23);
427	c.lineTo(w * 0.23, h * 0.46);
428	c.moveTo(0, h * 0.23);
429	c.lineTo(w * 0.46, h * 0.23);
430	c.stroke();
431};
432
433mxShapePidValve.prototype.drawDblActingActBg = function(c, w, h)
434{
435	c.rect(0, 0, w * 0.46, h * 0.46);
436	c.fillAndStroke();
437
438	c.begin();
439	c.moveTo(w * 0.23, h * 0.46);
440	c.lineTo(w * 0.23, h);
441	c.moveTo(w * 0.46, h * 0.115);
442	c.lineTo(w, h * 0.115);
443	c.moveTo(w * 0.77, h * 0.035);
444	c.lineTo(w * 0.69, h * 0.195);
445	c.moveTo(w * 0.82, h * 0.035);
446	c.lineTo(w * 0.74, h * 0.195);
447	c.moveTo(w * 0.46, h * 0.345);
448	c.lineTo(w, h * 0.345);
449	c.moveTo(w * 0.77, h * 0.265);
450	c.lineTo(w * 0.69, h * 0.425);
451	c.moveTo(w * 0.82, h * 0.265);
452	c.lineTo(w * 0.74, h * 0.425);
453	c.stroke();
454};
455
456mxShapePidValve.prototype.drawPilotCylinderActBg = function(c, w, h)
457{
458	c.rect(0, 0, w * 0.46, h * 0.46);
459	c.fillAndStroke();
460
461	c.begin();
462	c.moveTo(w * 0.23, h * 0.46);
463	c.lineTo(w * 0.23, h);
464	c.moveTo(w * 0.46, h * 0.23);
465	c.lineTo(w * 0.77, h * 0.23);
466	c.stroke();
467
468	c.rect(w * 0.77, h * 0.115, w * 0.23, h * 0.23);
469	c.fillAndStroke();
470
471	c.setFontStyle(0);
472	c.setFontFamily('Helvetica');
473	c.setFontSize(Math.min(w, h) * 0.15);
474	c.text(w * 0.885, h * 0.23, 0, 0, 'P', mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
475};
476
477mxShapePidValve.prototype.drawAngleBlowdownAct = function(c, w, h)
478{
479	c.begin();
480	c.moveTo(w * 0.34, 0);
481	c.lineTo(w, h * 0.405);
482	c.moveTo(0, h);
483	c.lineTo(w * 0.665, h * 0.205);
484	c.stroke();
485};
486
487mxShapePidValve.prototype.drawSquareAct = function(c, w, h, actuator)
488{
489	c.rect(0, 0, w, h * 0.5);
490	c.fillAndStroke();
491
492	c.begin();
493	c.moveTo(w * 0.5, h * 0.5);
494	c.lineTo(w * 0.5, h);
495	c.stroke();
496
497	var m = '';
498
499	if (actuator === mxShapePidValve.prototype.cst.PILOT)
500	{
501		m = 'P';
502	}
503	else if (actuator === mxShapePidValve.prototype.cst.SOLENOID)
504	{
505		m = 'S';
506	}
507	else if (actuator === mxShapePidValve.prototype.cst.DIGITAL)
508	{
509		m = 'D';
510	}
511	else if (actuator === mxShapePidValve.prototype.cst.WEIGHT)
512	{
513		m = 'W';
514	}
515	else if (actuator === mxShapePidValve.prototype.cst.KEY)
516	{
517		m = 'K';
518	}
519
520	c.setFontStyle(1);
521	c.setFontFamily('Helvetica');
522	c.setFontSize(Math.min(w, h) * 0.4);
523	c.text(w * 0.5, h * 0.25, 0, 0, m, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
524};
525
526mxShapePidValve.prototype.drawGateVariantFg = function(c, x, y, w, h, valveType, actuator, actH)
527{
528	var defState = mxUtils.getValue(this.style, mxShapePidValve.prototype.cst.DEFAULT_STATE, 'open');
529	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
530	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
531
532	if (valveType === mxShapePidValve.prototype.cst.BALL)
533	{
534		c.ellipse(x + w * 0.3, y + actH + (h - actH) * 0.18, w * 0.4, (h - actH) * 0.64);
535		c.fillAndStroke();
536	}
537	else if (valveType === mxShapePidValve.prototype.cst.GLOBE)
538	{
539		c.ellipse(x + w * 0.3, y + actH + (h - actH) * 0.18, w * 0.4, (h - actH) * 0.64);
540		c.setFillColor(strokeColor);
541		c.fillAndStroke();
542		c.setFillColor(fillColor);
543	}
544	else if (valveType === mxShapePidValve.prototype.cst.PLUG)
545	{
546		this.drawPlug(c, x + w * 0.4, y + actH + (h - actH) * 0.25, w * 0.2, (h - actH) * 0.5);
547	}
548	else if (valveType === mxShapePidValve.prototype.cst.NEEDLE)
549	{
550		this.drawNeedle(c, x + w * 0.45, y + actH + (h - actH) * 0.1, w * 0.1, (h - actH) * 0.9);
551	}
552	else if (valveType === mxShapePidValve.prototype.cst.SELF_DRAINING)
553	{
554		this.drawDrain(c, x + w * 0.48, y + actH + (h - actH) * 0.5, w * 0.04, (h - actH) * 0.49);
555	}
556};
557
558mxShapePidValve.prototype.drawAngleVariantFg = function(c, x, y, w, h, valveType, actuator, actH)
559{
560	var defState = mxUtils.getValue(this.style, mxShapePidValve.prototype.cst.DEFAULT_STATE, 'open');
561	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
562	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
563
564	if (valveType === mxShapePidValve.prototype.cst.ANGLE_GLOBE)
565	{
566		if (actuator === 'none')
567		{
568			c.ellipse(w * 0.34, h * 0.175, w * 0.32, h * 0.4);
569		}
570		else
571		{
572			c.ellipse(w * 0.34, h * 0.45, w * 0.32, h * 0.2667);
573		}
574		c.setFillColor(strokeColor);
575		c.fillAndStroke();
576		c.setFillColor(fillColor);
577	}
578};
579
580mxShapePidValve.prototype.drawGateVariantBg = function(c, x, y, w, h, valveType, actuator, actH)
581{
582	if (valveType === mxShapePidValve.prototype.cst.GATE)
583	{
584		this.drawGateValve(c, x, y + actH, w, h - actH);
585	}
586	else if (valveType === mxShapePidValve.prototype.cst.BALL || valveType === mxShapePidValve.prototype.cst.GLOBE)
587	{
588		c.ellipse(x + w * 0.3, y + actH + (h - actH) * 0.18, w * 0.4, (h - actH) * 0.64);
589		c.fillAndStroke();
590		this.drawGateValve(c, x, y + actH, w, h - actH);
591	}
592	else if (valveType === mxShapePidValve.prototype.cst.PLUG)
593	{
594		this.drawPlug(c, x + w * 0.4, y + actH + (h - actH) * 0.25, w * 0.2, (h - actH) * 0.5);
595		this.drawGateValve(c, x, y + actH, w, h - actH);
596	}
597	else if (valveType === mxShapePidValve.prototype.cst.NEEDLE)
598	{
599		this.drawNeedle(c, x + w * 0.45, y + actH + (h - actH) * 0.1, w * 0.1, (h - actH) * 0.9);
600		this.drawGateValve(c, x, y + actH, w, h - actH);
601	}
602	else if (valveType === mxShapePidValve.prototype.cst.SELF_DRAINING)
603	{
604		this.drawDrain(c, x + w * 0.48, y + actH + (h - actH) * 0.5, w * 0.04, (h - actH) * 0.49);
605		this.drawGateValve(c, x, y + actH, w, h - actH);
606	}
607};
608
609mxShapePidValve.prototype.drawAngleVariantBg = function(c, x, y, w, h, valveType, actuator, actH)
610{
611	if (valveType === mxShapePidValve.prototype.cst.ANGLE)
612	{
613		this.drawAngleValve(c, w * 0.2, y + actH, w * 0.8, h - actH);
614	}
615	else if (valveType === mxShapePidValve.prototype.cst.ANGLE_GLOBE)
616	{
617		this.drawAngleGlobeValveBg(c, w * 0.2, y + actH, w * 0.8, h - actH);
618	}
619	else if (valveType === mxShapePidValve.prototype.cst.THREE_WAY)
620	{
621		this.drawThreeWayValve(c, 0, y + actH, w, h - actH);
622	}
623	else if (valveType === mxShapePidValve.prototype.cst.ANGLE_BLOWDOWN)
624	{
625		this.drawAngleBlowdownValve(c, x, y + actH, w, h - actH);
626	}
627};
628
629mxShapePidValve.prototype.drawPlug = function(c, x, y, w, h)
630{
631	c.translate(x, y);
632	c.begin();
633	c.moveTo(0, h * 0.5);
634	c.lineTo(w * 0.5, 0);
635	c.lineTo(w, h * 0.5);
636	c.lineTo(w * 0.5, h);
637	c.close();
638	c.fillAndStroke();
639	c.translate(-x, -y);
640};
641
642mxShapePidValve.prototype.drawNeedle = function(c, x, y, w, h)
643{
644	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
645	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
646
647	c.translate(x, y);
648	c.begin();
649	c.moveTo(0, 0);
650	c.lineTo(w, 0);
651	c.lineTo(w * 0.5, h);
652	c.close();
653	c.setFillColor(strokeColor);
654	c.fillAndStroke();
655	c.setFillColor(fillColor);
656	c.translate(-x, -y);
657};
658
659mxShapePidValve.prototype.drawDrain = function(c, x, y, w, h)
660{
661	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
662	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
663
664	c.translate(x, y);
665	c.begin();
666	c.moveTo(w * 0.5, 0);
667	c.lineTo(w * 0.5, h * 0.96);
668	c.stroke();
669
670	c.begin();
671	c.moveTo(0, h * 0.9);
672	c.lineTo(w, h * 0.9);
673	c.lineTo(w * 0.5, h);
674	c.close();
675	c.setFillColor(strokeColor);
676	c.fillAndStroke();
677	c.setFillColor(fillColor);
678	c.translate(-x, -y);
679};
680
681mxShapePidValve.prototype.drawGateValve = function(c, x, y, w, h)
682{
683	var defState = mxUtils.getValue(this.style, mxShapePidValve.prototype.cst.DEFAULT_STATE, 'open');
684	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
685	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
686
687	c.translate(x, y);
688	c.begin();
689	c.moveTo(0, 0);
690	c.lineTo(w * 0.5, h * 0.5);
691	c.lineTo(0, h);
692	c.close();
693	c.moveTo(w, 0);
694	c.lineTo(w * 0.5, h * 0.5);
695	c.lineTo(w, h);
696	c.close();
697
698	if (defState === mxShapePidValve.prototype.cst.CLOSED)
699	{
700		c.setFillColor(strokeColor);
701		c.fillAndStroke();
702		c.setFillColor(fillColor);
703	}
704	else
705	{
706		c.fillAndStroke();
707	}
708
709	c.translate(-x, -y);
710};
711
712mxShapePidValve.prototype.drawAngleValve = function(c, x, y, w, h)
713{
714	c.translate(x, y);
715
716	c.begin();
717	c.moveTo(w * 0.375, h * 0.375);
718	c.lineTo(w, 0);
719	c.lineTo(w, h * 0.75);
720	c.close();
721	c.moveTo(w * 0.375, h * 0.375);
722	c.lineTo(w * 0.75, h);
723	c.lineTo(0, h);
724	c.close();
725	c.fillAndStroke();
726
727	c.translate(-x, -y);
728};
729
730mxShapePidValve.prototype.drawAngleGlobeValveBg = function(c, x, y, w, h)
731{
732	c.translate(x, y);
733
734	c.ellipse(w * 0.175, h * 0.175, w * 0.4, h * 0.4);
735	c.fillAndStroke();
736	c.begin();
737	c.moveTo(w * 0.375, h * 0.375);
738	c.lineTo(w, 0);
739	c.lineTo(w, h * 0.75);
740	c.close();
741	c.moveTo(w * 0.375, h * 0.375);
742	c.lineTo(w * 0.75, h);
743	c.lineTo(0, h);
744	c.close();
745	c.fillAndStroke();
746	c.translate(-x, -y);
747};
748
749mxShapePidValve.prototype.drawAngleGlobeValveFg = function(c, x, y, w, h)
750{
751	c.translate(x, y);
752	c.ellipse(w * 0.275, h * 0.275, w * 0.2, h * 0.2);
753	c.fillAndStroke();
754	c.translate(-x, -y);
755};
756
757mxShapePidValve.prototype.drawThreeWayValve = function(c, x, y, w, h)
758{
759	c.translate(x, y);
760
761	c.begin();
762	c.moveTo(0, 0);
763	c.lineTo(w * 0.5, h * 0.375);
764	c.lineTo(0, h * 0.75);
765	c.close();
766
767	c.moveTo(w, 0);
768	c.lineTo(w * 0.5, h * 0.375);
769	c.lineTo(w, h * 0.75);
770	c.close();
771
772	c.moveTo(w * 0.5, h * 0.375);
773	c.lineTo(w * 0.8, h);
774	c.lineTo(w * 0.2, h);
775	c.close();
776	c.fillAndStroke();
777
778	c.translate(-x, -y);
779};
780
781mxShapePidValve.prototype.drawAngleBlowdownValve = function(c, x, y, w, h)
782{
783
784};
785
786
787mxShapePidValve.prototype.drawButterflyValve = function(c, x, y, w, h, actuator, actH)
788{
789	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
790	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
791
792	var yv = y + actH;
793	var hv = h - actH;
794
795	c.translate(x, yv);
796	c.begin();
797	c.moveTo(0, 0);
798	c.lineTo(0, hv);
799	c.moveTo(w, 0);
800	c.lineTo(w, hv);
801
802	c.moveTo(w * 0.05, hv * 0.05);
803	c.lineTo(w * 0.95, hv * 0.95);
804
805	c.fillAndStroke();
806
807	c.ellipse(w * 0.4, hv * 0.33, w * 0.2, hv * 0.33);
808	c.fillAndStroke();
809
810	c.translate(-x, -y);
811};
812
813mxShapePidValve.prototype.drawCheckValve = function(c, x, y, w, h, actuator, actH)
814{
815	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
816	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
817
818	var yv = y + actH;
819	var hv = h - actH;
820
821	c.translate(x, yv);
822	c.begin();
823	c.moveTo(0, 0);
824	c.lineTo(0, hv);
825	c.moveTo(w, 0);
826	c.lineTo(w, hv);
827	c.moveTo(w * 0.05, hv * 0.05);
828	c.lineTo(w * 0.95, hv * 0.95);
829	c.fillAndStroke();
830
831	c.begin();
832	c.moveTo(w * 0.8925, hv * 0.815);
833	c.lineTo(w * 0.957, hv * 0.955);
834	c.lineTo(w * 0.85, hv * 0.928);
835	c.close();
836	c.setFillColor(strokeColor);
837	c.fillAndStroke();
838	c.setFillColor(fillColor);
839
840	c.translate(-x, -y);
841};
842
843mxShapePidValve.prototype.isGateVariant = function(valveType)
844{
845	if (valveType === mxShapePidValve.prototype.cst.GATE ||
846			valveType === mxShapePidValve.prototype.cst.BALL ||
847			valveType === mxShapePidValve.prototype.cst.PLUG ||
848			valveType === mxShapePidValve.prototype.cst.NEEDLE ||
849			valveType === mxShapePidValve.prototype.cst.SELF_DRAINING ||
850			valveType === mxShapePidValve.prototype.cst.GLOBE)
851	{
852		return true;
853	}
854	else
855	{
856		return false;
857	}
858};
859
860mxShapePidValve.prototype.isAngleVariant = function(valveType)
861{
862	if (valveType === mxShapePidValve.prototype.cst.ANGLE ||
863			valveType === mxShapePidValve.prototype.cst.ANGLE_GLOBE ||
864			valveType === mxShapePidValve.prototype.cst.THREE_WAY ||
865			valveType === mxShapePidValve.prototype.cst.ANGLE_BLOWDOWN)
866	{
867		return true;
868	}
869	else
870	{
871		return false;
872	}
873};
874
875mxShapePidValve.prototype.isSquareVariant = function(actType)
876{
877	if (actType === mxShapePidValve.prototype.cst.PILOT ||
878			actType === mxShapePidValve.prototype.cst.SOLENOID ||
879			actType === mxShapePidValve.prototype.cst.POWERED ||
880			actType === mxShapePidValve.prototype.cst.DIGITAL ||
881			actType === mxShapePidValve.prototype.cst.WEIGHT ||
882			actType === mxShapePidValve.prototype.cst.KEY)
883	{
884		return true;
885	}
886	else
887	{
888		return false;
889	}
890};
891
892mxCellRenderer.registerShape(mxShapePidValve.prototype.cst.SHAPE_VALVE, mxShapePidValve);
893
894//**********************************************************************************************************************************************************
895//Integrated Block And Bleed Valve
896//**********************************************************************************************************************************************************
897/**
898* Extends mxShape.
899*/
900function mxShapePidIntBlockBleedValve(bounds, fill, stroke, strokewidth)
901{
902	mxShape.call(this);
903	this.bounds = bounds;
904	this.fill = fill;
905	this.stroke = stroke;
906	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
907};
908
909/**
910* Extends mxShapePidValve.
911*/
912mxUtils.extend(mxShapePidIntBlockBleedValve, mxShapePidValve);
913
914/**
915* Function: paintVertexShape
916*
917* Paints the vertex shape.
918*/
919mxShapePidIntBlockBleedValve.prototype.paintVertexShape = function(c, x, y, w, h)
920{
921	var actuator = mxUtils.getValue(this.style, mxShapePidIntBlockBleedValve.prototype.cst.ACTUATOR, mxShapePidIntBlockBleedValve.prototype.cst.NONE);
922	var actH = 0;
923
924	if (actuator !== 'none')
925	{
926		actH = h * 0.2353;
927	}
928
929	c.translate(x, y);
930	c.setLineJoin('round');
931
932	this.background(c, x, y, w, h, actuator, actH);
933	c.setShadow(false);
934	this.foreground(c, x, y, w, h, actuator, actH);
935};
936
937mxShapePidIntBlockBleedValve.prototype.background = function(c, x, y, w, h, actuator, actH)
938{
939	//draw the actuator
940	if (actuator !== mxShapePidIntBlockBleedValve.prototype.cst.NONE)
941	{
942		this.drawActuatorBg(c, x, y, w, h, actuator);
943	}
944
945	//draw the valve body
946	this.drawValveBg(c, 0, actH, w, h - actH);
947};
948
949mxShapePidIntBlockBleedValve.prototype.foreground = function(c, x, y, w, h, actuator, actH)
950{
951	//draw the actuator
952	if (actuator !== mxShapePidIntBlockBleedValve.prototype.cst.NONE)
953	{
954		this.drawActuatorFg(c, x, y, w, h, actuator);
955	}
956};
957
958mxShapePidIntBlockBleedValve.prototype.drawValveBg = function(c, x, y, w, h)
959{
960	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
961	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
962
963	c.translate(x, y);
964	c.begin();
965	c.moveTo(0, 0);
966	c.lineTo(w * 0.5, h * 0.23);
967	c.lineTo(0, h * 0.46);
968	c.close();
969	c.moveTo(w * 0.5, h * 0.23);
970	c.lineTo(w, 0);
971	c.lineTo(w, h * 0.46);
972	c.close();
973	c.fillAndStroke();
974
975	c.begin();
976	c.moveTo(w * 0.5, h * 0.23);
977	c.lineTo(w * 0.5, h * 0.5);
978	c.stroke();
979
980	c.setFillColor(strokeColor);
981	c.begin();
982	c.moveTo(w * 0.3, h * 0.5);
983	c.lineTo(w * 0.7, h * 0.5);
984	c.lineTo(w * 0.5, h * 0.75);
985	c.close();
986	c.fillAndStroke();
987
988	c.begin();
989	c.moveTo(w * 0.3, h);
990	c.lineTo(w * 0.5, h * 0.75);
991	c.lineTo(w * 0.7, h);
992	c.fillAndStroke();
993	c.setFillColor(fillColor);
994
995	c.translate(-x, -y);
996};
997
998mxShapePidIntBlockBleedValve.prototype.drawActuatorBg = function(c, x, y, w, h, actuator)
999{
1000	if (this.isSquareVariant(actuator))
1001	{
1002		c.translate(w * 0.325, 0);
1003		this.drawSquareAct(c, w * 0.35, h * 0.4112, actuator);
1004		c.translate(- w * 0.325, 0);
1005	}
1006	else if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.MANUAL)
1007	{
1008		c.translate(w * 0.25, h * 0.0882);
1009		this.drawManAct(c, w * 0.5, h * 0.323);
1010		c.translate(- w * 0.25, - h * 0.0882);
1011	}
1012	else if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.DIAPHRAGM)
1013	{
1014		c.translate(w * 0.25, h * 0.0588);
1015		this.drawDiaphAct(c, w * 0.5, h * 0.3524);
1016		c.translate(- w * 0.25, - h * 0.0588);
1017	}
1018	else if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.BALANCED_DIAPHRAGM)
1019	{
1020		c.translate(w * 0.25, h * 0.0588);
1021		this.drawBalDiaphActBg(c, w * 0.5, h * 0.3524);
1022		c.translate(- w * 0.25, - h * 0.0588);
1023	}
1024	else if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.MOTOR || actuator === mxShapePidIntBlockBleedValve.prototype.cst.ELECTRO_HYDRAULIC)
1025	{
1026		c.translate(w * 0.325, 0);
1027		this.drawCircleAct(c, w * 0.35, h * 0.4112, actuator);
1028		c.translate(- w * 0.325, 0);
1029	}
1030	else if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.SPRING)
1031	{
1032		c.translate(w * 0.36, 0);
1033		this.drawSpringAct(c, w * 0.28, h * 0.4112);
1034		c.translate(- w * 0.36, 0);
1035	}
1036	else if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.SOLENOID_MANUAL_RESET)
1037	{
1038		c.translate(w * 0.325, 0);
1039		this.drawSolenoidManResetAct(c, w * 0.575, h * 0.4112);
1040		c.translate(- w * 0.325, 0);
1041	}
1042	else if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.SINGLE_ACTING)
1043	{
1044		c.translate(w * 0.35, 0);
1045		this.drawSingActingActBg(c, w * 0.65, h * 0.4112);
1046		c.translate(- w * 0.35, 0);
1047	}
1048	else if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.DOUBLE_ACTING)
1049	{
1050		c.translate(w * 0.35, 0);
1051		this.drawDblActingActBg(c, w * 0.65, h * 0.4112);
1052		c.translate(- w * 0.35, 0);
1053	}
1054	else if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.PILOT_CYLINDER)
1055	{
1056		c.translate(w * 0.35, 0);
1057		this.drawPilotCylinderActBg(c, w * 0.65, h * 0.4112);
1058		c.translate(- w * 0.35, 0);
1059	}
1060};
1061
1062mxShapePidIntBlockBleedValve.prototype.drawActuatorFg = function(c, x, y, w, h, actuator)
1063{
1064	if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.BALANCED_DIAPHRAGM)
1065	{
1066		c.translate(w * 0.25, h * 0.0588);
1067		this.drawBalDiaphActFg(c, w * 0.5, h * 0.3524);
1068		c.translate(- w * 0.25, - h * 0.0588);
1069	}
1070	else if (actuator === mxShapePidIntBlockBleedValve.prototype.cst.SINGLE_ACTING ||
1071			actuator === mxShapePidIntBlockBleedValve.prototype.cst.DOUBLE_ACTING ||
1072			actuator === mxShapePidIntBlockBleedValve.prototype.cst.PILOT_CYLINDER)
1073	{
1074		c.translate(w * 0.35, 0);
1075		this.drawActingActFg(c, w * 0.65, h * 0.4112);
1076		c.translate(- w * 0.35, 0);
1077	}
1078};
1079
1080mxCellRenderer.registerShape('mxgraph.pid2valves.blockBleedValve', mxShapePidIntBlockBleedValve);
1081
1082//**********************************************************************************************************************************************************
1083//Auto Recirculation Valve
1084//**********************************************************************************************************************************************************
1085/**
1086 * Extends mxShape.
1087 */
1088function mxShapePidAutoRecircValve(bounds, fill, stroke, strokewidth)
1089{
1090	mxShape.call(this);
1091	this.bounds = bounds;
1092	this.fill = fill;
1093	this.stroke = stroke;
1094	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1095};
1096
1097/**
1098 * Extends mxShape.
1099 */
1100mxUtils.extend(mxShapePidAutoRecircValve, mxShape);
1101
1102
1103/**
1104 * Function: paintVertexShape
1105 *
1106 * Paints the vertex shape.
1107 */
1108mxShapePidAutoRecircValve.prototype.paintVertexShape = function(c, x, y, w, h)
1109{
1110	c.setLineJoin('round');
1111	c.translate(x, y);
1112
1113	//background
1114	c.rect(0, 0, w, h);
1115	c.fillAndStroke();
1116	c.setShadow(false);
1117
1118	//foreground
1119	c.begin();
1120	c.moveTo(w * 0.08, h * 0.08);
1121	c.lineTo(w * 0.08, h * 0.92);
1122	c.moveTo(w * 0.92, h * 0.08);
1123	c.lineTo(w * 0.92, h * 0.92);
1124	c.moveTo(w * 0.12, h * 0.122);
1125	c.lineTo(w * 0.8738, h * 0.8837);
1126
1127	c.moveTo(w * 0.5, 0);
1128	c.lineTo(w * 0.55, h * 0.05);
1129	c.lineTo(w * 0.45, h * 0.15);
1130	c.lineTo(w * 0.55, h * 0.25);
1131	c.lineTo(w * 0.45, h * 0.35);
1132	c.lineTo(w * 0.55, h * 0.45);
1133	c.lineTo(w * 0.49, h * 0.5);
1134	c.stroke();
1135
1136	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
1137	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
1138
1139	c.begin();
1140	c.moveTo(w * 0.8257, h * 0.7695);
1141	c.lineTo(w * 0.8797, h * 0.888);
1142	c.lineTo(w * 0.79, h * 0.8651);
1143	c.close();
1144	c.setFillColor(strokeColor);
1145	c.fillAndStroke();
1146	c.setFillColor(fillColor);
1147};
1148
1149mxCellRenderer.registerShape('mxgraph.pid2valves.autoRecircValve', mxShapePidAutoRecircValve);
1150