/* 
 * Copyright (c) 2000, 2004, Oracle. All rights reserved.  
 *  All rights reserved.
 *
 *  N O T I C E
 *
 * THIS MATERIAL IS CONSIDERED A TRADE SECRET BY ILOG.
 * UNAUTHORIZED ACCESS, USE, REPRODUCTION OR DISTRIBUTION IS PROHIBITED.
 */

function SVGLayer(element, view) {

this.g = element
this.index = -1
this.view = view
this.computeVisibilityFilters()
}

SVGLayer.prototype = new Object

SVGLayer.prototype.computeVisibilityFilters = function() {
var filters = this.g.getElementsByTagNameNS(GF_NS, "visibilityFilter")
for (var i = 0; i < filters.length; i++) {
var filter = filters.item(i)
if (filter.hasAttribute("language")) {
	
	
} else {
this.addVisibilityFilter(new SVGLayerVisibilityFilter(filter.getAttribute("minZoom"),
	 				   	            filter.getAttribute("maxZoom")))
}
}
}

SVGLayer.prototype.setVisible = function(value) {
if (!value)
this.g.setAttribute("visibility", "hidden")
else {
if (this.g.getAttributeNS(GF_NS, "lod") == "true") {

getURL(this.view.getURLString()+"&layer="+this.getName(), new SVGLayerCallback(this))
this.g.removeAttributeNS(GF_NS, "lod")
}
if (this.g.hasAttribute("visibility"))
this.g.removeAttribute("visibility")
}
}

SVGLayer.prototype.isVisible = function() {
return (!(this.g.getAttribute("visibility") == "hidden") &&
	 !(this.g.hasAttributeNS(GF_NS, "lod")))
}

SVGLayer.prototype.isFiltered = function() {
return this.g.hasAttributeNS(GF_NS, "filtered")
}

SVGLayer.prototype.setName = function(name) {
this.g.setAttribute("id")
}

SVGLayer.prototype.getName = function(value) {
return this.g.getAttribute("id")
}

SVGLayer.prototype.addVisibilityFilter = function(filter) {
if (this.filters == null)
this.filters = new Array()
this.filters[this.filters.length] = filter
this.index = this.filters.length
}

SVGLayer.prototype.removeFilterIndex = function(index) {
if (index < this.filters.length && j >= 0) {
for (var i = index + 1; i < this.filters.length; i++) {
this.filters[i-1] = this.filters[i]
}
this.filters.length = this.filters.length - 1
}
}

SVGLayer.prototype.removeVisibilityFilter = function(filter) {
j = this.filters.length
for (var i = 0; i < this.filters.length; i++) {
if (filter == this.filters[i])
j = i
}
if (j != this.filters.length)
removeLayerIndex(j)
}

SVGLayer.prototype.layerVisibilityChanged = function(evt) {
if (this.filters != null) {
for (var i = 0; i < this.filters.length; i++) {
if (!this.filters[i].isVisible(this, evt.target.currentScale*this.view.zoomlevel)) {
	this.g.setAttribute("visibility", "hidden")
this.g.setAttributeNS(GF_NS, "filtered", "true")
this.fireVisibilityChangedListeners()
	return
} else {
if (this.g.getAttributeNS(GF_NS, "lod") == "true") {

getURL(this.view.getURLString()+"&layer="+this.getName(), new SVGLayerCallback(this))
this.g.removeAttributeNS(GF_NS, "lod")
}
if (this.g.hasAttribute("visibility"))
this.g.removeAttribute("visibility")
if (this.g.hasAttributeNS(GF_NS, "filtered"))
	  this.g.removeAttributeNS(GF_NS, "filtered")
this.fireVisibilityChangedListeners()
}
}
}
}

SVGLayer.prototype.fireVisibilityChangedListeners = function() {
if (this.listeners == null)
return
for (var i = 0; i < this.listeners.length; i++)
this.listeners[i].visibilityChanged(this)
}

SVGLayer.prototype.addVisibilityChangedListener = function(listener) {
if (this.listeners == null)
this.listeners = new Array()
this.listeners[this.listeners.length] = listener
}

SVGLayer.prototype.removeVisibilityChangedListener = function(listener) {
var j = this.listeners.length
for (var i = 0; i < this.listeners.length; i++) {
if (listener == this.listeners[i])
j = i
}
if (j != this.listeners.length)
removeVisibilityChangedIndex(j)
}


SVGLayer.prototype.removeVisibilityChangedIndex = function(index) {
if (index < this.listeners.length && j >= 0) {
for (var i = index + 1; i < this.listeners.length; i++) {
this.listeners[i-1] = this.listeners[i]
}
this.listeners.length = this.listeners.length - 1
}
}

function SVGLayerVisibilityFilter(min, max) {
this.min = -1
this.max = -1
if (min.length > 0)
this.min = parseFloat(min)
if (max.length > 0)
this.max = parseFloat(max)
}

SVGLayerVisibilityFilter.prototype = new Object

SVGLayerVisibilityFilter.prototype.isVisible = function(layer, scale) {
return ((this.min == -1 || scale > this.min) &&
(this.max == -1 || scale <= this.max))
}

function SVGLayerCallback(ref) {
this.layer = ref
}

SVGLayerCallback.prototype.operationComplete = function(status) {
if (status.success) {
var fragment = parseXML(status.content, document)
var g = fragment.childNodes.item(0).childNodes.item(1)

var list = g.childNodes
while (list.length != 0) {
this.layer.g.appendChild(list.item(0))
}	
}
}



function SVGAbstractView(element) {
if (!element)
return
this.svg = element.viewportElement
this.element = element
this.init()
}

SVGAbstractView.prototype = new Object

SVGAbstractView.prototype.init = function() {
this.computeTransformation()
if (this.usingPercentage) {

this.svg.parentNode.addEventListener("SVGResize", new ResizeListener(this), false)
}

if (this.element.getAttribute("enableBackground") == "true") {



this.bottom = document.createElementNS(SVG_NS, "rect")
this.bottom.setAttribute("width", "100%")
this.bottom.setAttribute("height", "100%")
this.computeBottom()
this.bottom.setAttribute("class", "backgroundRect")
this.svg.appendChild(this.bottom)
}
if (this.element.getAttribute("disableZoom") == "true") {
this.disableZoom = true
this.initX = parseFloat(this.svg.getAttribute("x"))
this.initY = parseFloat(this.svg.getAttribute("y"))
this.initWidth = parseFloat(this.svg.getAttribute("width"))
this.initHeight = parseFloat(this.svg.getAttribute("height"))

this.svg.parentNode.addEventListener("SVGZoom", this, false)
this.svg.parentNode.addEventListener("SVGScroll", this, false)
}
if (this.element.getAttribute("enableDrag") == "true") {
this.enableDrag = true

this.svg.addEventListener("mousedown", this, false)
}
}

SVGAbstractView.prototype.getAbsoluteValue = function(elmt, attrname) {
var value = elmt.getAttribute(attrname)
var index = value.indexOf('%')
if (index == -1)
return parseFloat(value)
else {
this.usingPercentage = true
var tmp = parseFloat(value.substring(0, index))
switch (attrname) {







case "x":
return JViewsSVG.getInnerWidth()*tmp/100
break;
case "y":
return JViewsSVG.getInnerHeight()*tmp/100
break;
case "width":
return JViewsSVG.getInnerWidth()*tmp/100
break;
case "height":
return JViewsSVG.getInnerHeight()*tmp/100
break;
}
}
}

SVGAbstractView.prototype.computeBottom = function() {
if (this.bottom && (this.sx != 1 || this.sy != 1 ||
		      this.tx != this.svgX || this.ty != this.svgY)) {
this.bottom.setAttribute("x", (this.svgX - this.tx)/this.sx)
this.bottom.setAttribute("y", (this.svgY - this.ty)/this.sy)
}
}

SVGAbstractView.prototype.computeTransformation = function() {
this.svgX = this.getAbsoluteValue(this.svg, "x")
this.svgY = this.getAbsoluteValue(this.svg, "y")
this.svgWidth = this.getAbsoluteValue(this.svg, "width")
this.svgHeight = this.getAbsoluteValue(this.svg, "height")
this.sx = 1
this.sy = 1
this.tx = this.svgX
this.ty = this.svgY
var viewBoxStr = this.svg.getAttribute("viewBox")
if (viewBoxStr.length != 0) {
coords = viewBoxStr.split(" ")
var viewWidth = parseFloat(coords[2])
var viewHeight = parseFloat(coords[3])
var viewX = parseFloat(coords[0])
var viewY = parseFloat(coords[1])
var method = this.svg.getAttribute("preserveAspectRatio")
var methods = method.split(" ")
this.sx = this.svgWidth/viewWidth
this.sy = this.svgHeight/viewHeight
if (method.length == 0 ||
(methods[0] == "xMidYMid" && (!methods[1] || methods[1] == "meet"))) {

this.sx = this.sy = Math.min(this.sx, this.sy)
this.tx = this.tx + this.svgWidth/2 - this.sx*(viewX + viewWidth/2)
this.ty = this.ty + this.svgHeight/2 - this.sy*(viewY + viewHeight/2)
} else if (methods[0] == "none") {

this.tx = this.tx - this.sx*viewX
this.ty = this.ty - this.sy*viewY
}
}
this.computeBottom()
}

SVGAbstractView.prototype.xClientToMainCS = function(x) {
x = (x - this.svg.parentNode.currentTranslate.x)/this.svg.parentNode.currentScale
return (x - this.tx)/this.sx
}

SVGAbstractView.prototype.yClientToMainCS = function(y) {
y = (y - this.svg.parentNode.currentTranslate.y)/this.svg.parentNode.currentScale
return (y - this.ty)/this.sy
}

SVGAbstractView.prototype.handleEvent = function(evt) {
var type = evt.type
if (type == "SVGZoom" || type == "SVGScroll")
this.zoomAndPan(evt)
else {
if (this[type] != null)
this[type](evt) 	
}
}

SVGAbstractView.prototype.zoomAndPan = function(evt) {
if (!this.disableZoom)
return
this.fixBounds(evt.target)
}

SVGAbstractView.prototype.fixBounds = function(topSVG) {
var x = (this.initX - topSVG.currentTranslate.x)/topSVG.currentScale
this.svg.setAttribute("x", x)
var y = (this.initY - topSVG.currentTranslate.y)/topSVG.currentScale
this.svg.setAttribute("y", y)
var width = this.initWidth/topSVG.currentScale
this.svg.setAttribute("width", width)
var height = this.initHeight/topSVG.currentScale
this.svg.setAttribute("height", height)

this.computeTransformation()
}

SVGAbstractView.prototype.updatePositionWithDrag = function(evt) {
if (this.disableZoom) {
this.initX = evt.clientX - this.dx
this.initY = evt.clientY - this.dy
this.fixBounds(this.svg.parentNode)
} else {

this.svg.setAttribute("x", evt.clientX - this.dx)
this.svg.setAttribute("y", evt.clientY - this.dy)
}
}

SVGAbstractView.prototype.mousedown = function(evt) {
this.dragging = true
JViewsSVG.lockGlassPane().addEventListener("mousemove", this, false)
JViewsSVG.lockGlassPane().addEventListener("mouseup", this, false)
if (this.disableZoom) {
this.dx = evt.clientX - this.initX
this.dy = evt.clientY - this.initY
} else {

this.dx = evt.clientX - parseFloat(this.svg.getAttribute("x"))
this.dy = evt.clientY - parseFloat(this.svg.getAttribute("y"))
}
}

SVGAbstractView.prototype.mouseup = function(evt) {
if (this.dragging) {
JViewsSVG.releaseGlassPane().removeEventListener("mousemove", this, false)
JViewsSVG.releaseGlassPane().removeEventListener("mouseup", this, false)
this.updatePositionWithDrag(evt)

this.dragging = false
this.dx = 0
this.dy = 0
}
}

SVGAbstractView.prototype.mousemove = function(evt) {
if (this.dragging) {
this.updatePositionWithDrag(evt)
}
}

function ResizeListener(view) {
this.view = view
}

ResizeListener.prototype.handleEvent = function(evt) {
this.view.computeTransformation();
}



function SVGOverView(element, view) {
this.__superCtor__ = eval("SVGAbstractView")
this.__superCtor__(element)
this.__superCtor__ = null
this.view = view
}

SVGOverView.prototype = new SVGAbstractView

SVGOverView.prototype.toSVG = function() {


var rect = this.svg.createSVGRect()
for (var i = 0; i < this.view.getLayersCount(); i++) {
var use = document.createElementNS(SVG_NS, "use")
use.setAttributeNS(XLINK_NS, "xlink:href", "#"+this.view.getLayer(i).getName())
this.svg.appendChild(use)
this.increaseRect(rect, document.getElementById(this.view.getLayer(i).getName()).getBBox())
}

this.svg.setAttribute("viewBox", rect.x+" "+rect.y+" "+rect.width+" "+rect.height)
this.computeTransformation()
this.overRect = document.createElementNS(SVG_NS, "rect")
this.overRect.setAttribute("class", "overRect")
this.listener = new SVGOverViewListener(this)
this.overRect.addEventListener("mousedown", this.listener, false)
this.svg.addEventListener("mousedown", this.listener, false)
this.updateOverRectWithExternal()
this.svg.appendChild(this.overRect)

if (this.bottom) {
this.bottom.setAttribute("x", rect.x)
this.bottom.setAttribute("y", rect.y)
this.bottom.setAttribute("width", rect.width)
this.bottom.setAttribute("height", rect.height)

var clipPath = document.createElementNS(SVG_NS, "clipPath")
clipPath.setAttribute("id", "clip")
clipPath.appendChild(this.bottom.cloneNode(true))
this.svg.appendChild(clipPath)
this.overRect.setAttribute("clip-path", "url(#clip)")
}

return this
}

SVGAbstractView.prototype.computeBottom = function() {

}

SVGOverView.prototype.updateOverRectWithExternal = function() {
if (this.view.updateClipOff) {
this.overRect.setAttribute("x", this.view.xClientToMainCS(0))
this.overRect.setAttribute("y", this.view.yClientToMainCS(0))
this.overRect.setAttribute("width", JViewsSVG.getInnerWidth() /
this.view.svg.parentNode.currentScale / this.view.sx)
this.overRect.setAttribute("height", JViewsSVG.getInnerHeight() /
this.view.svg.parentNode.currentScale / this.view.sy)
} else {
this.overRect.setAttribute("x", this.view.xClientToMainCS(this.view.svgX))
this.overRect.setAttribute("y", this.view.yClientToMainCS(this.view.svgY))



this.overRect.setAttribute("width", this.view.svgWidth / this.view.svg.parentNode.currentScale / this.view.sx)
this.overRect.setAttribute("height", this.view.svgHeight / this.view.svg.parentNode.currentScale / this.view.sy)
}
}

SVGOverView.prototype.increaseRect = function(rect, add) {
if (add.x < rect.x)
rect.x = add.x
if (add.y < rect.y)
rect.y = add.y
if (add.x + add.width > rect.x + rect.width)
rect.width = (add.x + add.width) - rect.x
if (add.y + add.height > rect.y + rect.height)
rect.height = (add.y + add.height) - rect.y
}

SVGOverView.prototype.overDown = function(evt) {
evt.stopPropagation()
if (evt.target == this.overRect) {
JViewsSVG.lockGlassPane().addEventListener("mousemove", this.listener, false)
JViewsSVG.lockGlassPane().addEventListener("mouseup", this.listener, false)
this.overDragging = true
this.overDx = this.xClientToMainCS(evt.clientX) - parseFloat(this.overRect.getAttribute("x"))
this.overDy = this.yClientToMainCS(evt.clientY) - parseFloat(this.overRect.getAttribute("y"))
} else {

var X0 = this.xClientToMainCS(evt.clientX) -
	 this.overRect.getAttribute("width") / 2
this.overRect.setAttribute("x", X0)
var Y0 =  this.yClientToMainCS(evt.clientY) -
	 this.overRect.getAttribute("height") / 2
this.overRect.setAttribute("y", Y0)
this.view.svg.parentNode.currentTranslate.x = this.view.svgX -
			this.view.svg.parentNode.currentScale*(this.view.sx*X0 + this.view.tx)
this.view.svg.parentNode.currentTranslate.y = this.view.svgY -
this.view.svg.parentNode.currentScale*(this.view.sy*Y0 + this.view.ty)
this.updateOverRectWithExternal()
}
}

SVGOverView.prototype.overUp = function(evt) {
if (this.overDragging) {
evt.stopPropagation()
JViewsSVG.releaseGlassPane().removeEventListener("mousemove", this.listener, false)	
JViewsSVG.releaseGlassPane().removeEventListener("mouseup", this.listener, false)	
var X0 = this.xClientToMainCS(evt.clientX) - this.overDx
this.view.svg.parentNode.currentTranslate.x = this.view.svgX - this.view.svg.parentNode.currentScale*
							(this.view.sx*X0 + this.view.tx)
var Y0 = this.yClientToMainCS(evt.clientY) - this.overDy
this.view.svg.parentNode.currentTranslate.y = this.view.svgY - this.view.svg.parentNode.currentScale*
							(this.view.sy*Y0 + this.view.ty)
this.updateOverRectWithExternal()
this.overDragging = false
this.overDx = 0
this.overDy = 0
}
}

SVGOverView.prototype.overMove = function(evt) {
if (this.overDragging) {
evt.stopPropagation()
this.updateOverRectWithDrag(evt)
}
}

SVGOverView.prototype.updateOverRectWithDrag = function(evt) {
this.overRect.setAttribute("x", this.xClientToMainCS(evt.clientX) - this.overDx)
this.overRect.setAttribute("y", this.yClientToMainCS(evt.clientY) - this.overDy)
}

function SVGOverViewListener(overView) {
this.overView = overView
}

SVGOverViewListener.prototype = new Object

SVGOverViewListener.prototype.handleEvent = function(evt) {
var type = evt.type
switch (type) {
case "mousedown":
this.overView.overDown(evt)
break
case "mouseup":
this.overView.overUp(evt)
break
case "mousemove":
this.overView.overMove(evt)
break
}
}



function SVGView(element) {
this.__superCtor__ = eval("SVGAbstractView")
this.__superCtor__(element)
this.__superCtor__ = null
this.tempToLayer = null
this.lock = 0

this.lastScale = 0
this.lastTranslateX = this.svg.parentNode.currentTranslate.x
this.lastTranslateY = this.svg.parentNode.currentTranslate.y
if (element.hasAttributeNS(GF_NS, "zoomlevel")) {
this.zoomlevel = parseFloat(element.getAttributeNS(GF_NS, "zoomlevel"))
} else {
this.zoomlevel = 1
}
if (element.getAttribute("disableClip") == "true") {
this.disableClip = true
}


this.updateClipOff =
	(innerWidth == JViewsSVG.getInnerWidth() &&
	 innerHeight == JViewsSVG.getInnerHeight() &&
	 ((this.svg.getAttribute("x") == "0%" &&
this.svg.getAttribute("y") == "0%" &&
this.svg.getAttribute("width") == "100%" &&
this.svg.getAttribute("height") == "100%") ||
(this.svgX == 0 &&
this.svgY == 0 &&
this.svgWidth == JViewsSVG.getInnerWidth() &&
this.svgHeight == JViewsSVG.getInnerHeight())))
if (this.updateClipOff) {
this.svg.setAttribute("overflow", "visible")
} else {
this.svg.setAttribute("overflow", "hidden")
}
this.svg.parentNode.addEventListener("SVGZoom", this, false)
this.svg.parentNode.addEventListener("SVGScroll", this, false)
this.svg.parentNode.addEventListener("SVGResize", this, false)
if (element.getAttribute("enableTooltips") == "true")
SVGTooltipManager.registerView(this)


if (element.hasAttributeNS(XLINK_NS, "href")) {
getURL(this.getURLString(), new SVGViewCallback(this))
} else {
this.createLayers()
}
}

SVGView.prototype = new SVGAbstractView

SVGView.prototype.createLayers = function() {

for (var node = this.svg.firstChild; node != null; node = node.nextSibling) {
if (node.nodeName == "g") {
	   layer = new SVGLayer(node, this)
this.addLayer(layer)
}
}


this.updateClip()
}

SVGView.prototype.setName = function(name) {
this.svg.setAttribute("id")
}

SVGView.prototype.getName = function(value) {
return this.svg.getAttribute("id")
}

SVGView.prototype.addLayer = function(layer) {
if (this.layers == null)
this.layers = new Array()
this.layers[this.layers.length] = layer
layer.index = this.layers.length
this.newLayer(layer)
}

SVGView.prototype.insertLayer = function(layer, index) {
if (this.layers == null)
this.layers = new Array()
if (index < 0 || index > this.layers.length - 1)
index = this.layers.length - 1
for (var i = this.layers.length - 1; i >= index; i--)
this.layers[i+1] = this.layers[i]
this.layers[index] = layer
layer.index = index
this.newLayer(layer)
}

SVGView.prototype.addLayerIndex = function(index) {
g = svg.createElementNS(SVG_NS, "g")
layer = new SVGLayer(g, this)
this.insertLayer(layer, index)
}

SVGView.prototype.newLayer = function(layer) {

if (layer.g.parentNode == null) {
this.svg.insertBefore(this.layers[layer.index+1], layer)
}
}

SVGView.prototype.removeLayer = function(layer) {
var j = this.layers.length
for (var i = 0; i < this.layers.length; i++) {
if (layer == this.layers[i])
j = i
}
if (j != this.layers.length)
removeLayerIndex(j)
}

SVGView.prototype.removeLayerIndex = function(index) {
if (index < this.layers.length && j >= 0) {
for (var i = index + 1; i < this.layers.length; i++) {
this.layers[i-1] = this.layers[i]
}
this.layers.length = this.layers.length - 1
}
}

SVGView.prototype.getLayer = function(index) {
return this.layers[index]
}

SVGView.prototype.getLayersCount = function() {
if (this.layers)
return this.layers.length
else
return 0
}

SVGView.prototype.lockTempTopLayer = function() {
if (this.lock == 0) {
if (this.tempTopLayer == null) {
this.tempTopLayer = svgDocument.createElementNS(SVG_NS, "g")
this.tempTopLayer.setAttribute("id", "__SVGIlvTempTopLayer")
}
this.svg.appendChild(this.tempTopLayer)
}
this.lock++
return this.tempTopLayer
}

SVGView.prototype.releaseTempTopLayer = function() {
this.lock--
if (this.lock == 0) {
this.svg.removeChild(this.tempTopLayer)
}
}

SVGView.prototype.getGraphic = function(element) {
if (element == null || element.tagName == "svg")
return null
if (element.hasAttributeNS(GF_NS, "graphic"))
return element
else
return this.getGraphic(element.parentNode)
}

SVGView.prototype.handleEvent = function(evt) {
if (evt.type == "SVGZoom") {
this.zoomabilityChanged(evt)
this.layerVisibilityChanged(evt)
}
if (this.overView)
this.overView.updateOverRectWithExternal()
this.updateClip()
}

SVGView.prototype.zoomabilityChanged = function(evt) {
var list = evt.target.getElementsByTagNameNS(GF_NS, "zoomability")
var zoomFactor = evt.target.currentScale
var val = 1 / zoomFactor
var transform = "matrix("+val+" 0 0 "+val+" "
for (var i = 0; i < list.length; i++) {
var pos = list.item(i)
var elmt = pos.parentNode.parentNode
var cx = pos.getAttribute("x")
var cy = pos.getAttribute("y")
var x0 = (zoomFactor - 1)*cx/zoomFactor
var y0 = (zoomFactor - 1)*cy/zoomFactor
var oldt = elmt.getAttributeNS(GF_NS, "oldt")
if (oldt.length == 0) {
oldt = elmt.getAttribute("transform")
if (oldt.length == 0)
oldt = "none"
elmt.setAttributeNS(GF_NS, "ilv:oldt", oldt)
}
if (oldt == "none")
elmt.setAttribute("transform", transform+x0+" "+y0+")")
else
elmt.setAttribute("transform", oldt+" "+transform+x0+" "+y0+")")

}
}

SVGView.prototype.layerVisibilityChanged = function(evt) {
for (var i = 0; i < this.getLayersCount(); i++) {
this.getLayer(i).layerVisibilityChanged(evt)
}
}

SVGView.prototype.createOverView = function(element) {
this.overView = new SVGOverView(element, this)
if (this.layers)
this.overView.toSVG()
}

SVGView.prototype.createLayerView = function(element) {
this.layerView = new SVGLayerView(element, this).toSVG()
if (this.layers)
this.layerView.toSVG()
}

SVGView.prototype.updateClip = function(element) {


if (this.updateClipOff ||
(this.svg.parentNode.currentTranslate.x == this.lastTranslateX &&
this.svg.parentNode.currentTranslate.y == this.lastTranslateY &&
this.svg.parentNode.currentScale == this.lastScale)) {
return
}
var left = (this.svgX - this.svg.parentNode.currentTranslate.x)/
			this.svg.parentNode.currentScale - this.svgX
var top = (this.svgY - this.svg.parentNode.currentTranslate.y)/
			this.svg.parentNode.currentScale - this.svgY
var right = (-this.svgX - this.svgWidth + this.svg.parentNode.currentTranslate.x)/
			this.svg.parentNode.currentScale + this.svgX + this.svgWidth
var bottom = (-this.svgY - this.svgHeight + this.svg.parentNode.currentTranslate.y)/
			this.svg.parentNode.currentScale + this.svgY + this.svgHeight
this.lastTranslateX = this.svg.parentNode.currentTranslate.x
this.lastTranslateY = this.svg.parentNode.currentTranslate.y
this.lastScale = this.svg.parentNode.currentScale
this.svg.setAttribute("clip", "rect("+top+","+right+","+bottom+","+left+")")
}

SVGView.prototype.debugOn = function() {
var debug = document.createElementNS(SVG_NS, "svg")
debug.setAttribute("x", "0")
debug.setAttribute("y", "0")
debug.setAttribute("width", "200")
debug.setAttribute("height", "50")
var meta = document.createElementNS(SVG_NS, "metadata")
var view = document.createElementNS(JVIEWS_NS, "ilv:view")
view.setAttribute("disableZoom", "true")
meta.appendChild(view)
debug.appendChild(meta)
debug.setAttribute("viewBox", "0 0 200 50")
var text = document.createElementNS(SVG_NS, "text")
text.setAttribute("x", "10")
text.setAttribute("y", "20")
text.setAttribute("fill", "red")
this.debugTrace = document.createTextNode("debug on")
text.appendChild(this.debugTrace)
debug.appendChild(text)
this.svg.parentNode.appendChild(debug)
new SVGAbstractView(view)
}

SVGView.prototype.debugOff = function() {
}

SVGView.prototype.debugString = function(trace) {
if (this.debugTrace)
this.debugTrace.data = trace
}

SVGView.prototype.getURLString = function() {
var base = this.element.getAttributeNS(XLINK_NS, "href")
if (base.indexOf('?') == -1) {
base+="?request=image&width="+
this.getAbsoluteValue(this.svg, "width")+
"&height="+
this.getAbsoluteValue(this.svg, "height")
} else {
base+="&request=image&width="+
this.getAbsoluteValue(this.svg, "width")+
"&height="+
this.getAbsoluteValue(this.svg, "height")
}
return base
}

function SVGViewCallback(ref) {
this.view = ref
}

SVGViewCallback.prototype.operationComplete = function(status) {
if (status.success) {
this.view.svg.setAttribute("xmlns:ilvgf",
"http://xmlns.ilog.com/JViews/GraphicsFramework")
var fragment = parseXML(status.content, document);
var node = fragment.firstChild

if (node.hasAttribute("viewBox")) {
this.view.svg.setAttribute("viewBox", node.getAttribute("viewBox"))
this.view.computeTransformation()
}

if (node.hasAttributeNS(GF_NS, "zoomlevel")) {
this.view.zoomlevel = parseFloat(node.getAttributeNS(GF_NS, "zoomlevel"))
}

var list = node.childNodes
while (list.length != 0) {
this.view.svg.appendChild(list.item(0))
}	


this.view.init()
this.view.createLayers()
if (this.view.overView)
this.view.overView.toSVG()
if (this.view.layerView)
this.view.layerView.toSVG()
}
}


XLINK_NS = "http://www.w3.org/1999/xlink"
SVG_NS = "http://www.w3.org/2000/svg"
GF_NS = "http://xmlns.ilog.com/JViews/GraphicsFramework"
JVIEWS_NS = "http://xmlns.ilog.com/JViews/SVGToolkit"

function JViewsSVG() {}

JViewsSVG.Views = new Array()

JViewsSVG.Init = function(evt) {
JViewsSVG.target = evt.target
JViewsSVG.UpdateMenu()
var list = evt.target.getElementsByTagNameNS(JVIEWS_NS, "view")
var length = list.length
for (var i = 0; i < length; i++) {
var node = list.item(i)
var type = node.getAttribute("type")
switch (type) {
case "manager":
this.Views[i] = new SVGView(node)
break
case "over":
this.Views[i] =
this.GetView(evt.target.getElementById(this.GetLocalRef(node.getAttributeNS(XLINK_NS, "href")))).
				createOverView(node)
break
case "layer":
this.Views[i] =
	this.GetView(evt.target.getElementById(this.GetLocalRef(node.getAttributeNS(XLINK_NS, "href")))).
				createLayerView(node)
break
case "titled":
this.Views[i] = new SVGTitledView(node)
break
default:
this.Views[i] = new SVGAbstractView(node)
}
}
}

JViewsSVG.UpdateMenu = function() {
if (contextMenu) {
items = contextMenu.getElementsByTagName("item")
for (i = 0; i < items.length; i++) {
val = items.item(i).getAttribute("action")
if (val == "CopySVG" ||
val == "ViewSVG" ||
val == "ViewSource" ||
val == "SaveAs") {
items.item(i).parentNode.removeChild(items.item(i))
i--
}
}
}
}

JViewsSVG.GetView = function(svgElement) {
for (var i = 0; i < this.Views.length; i++)
if (this.Views[i].svg == svgElement)
return this.Views[i]
}

JViewsSVG.GetParentView = function(element) {
return JViewsSVG.GetView(element.viewportElement)
}

JViewsSVG.GetLocalRef = function(xlinkhref) {
return xlinkhref.slice(1, xlinkhref.length)
}

JViewsSVG.getInnerWidth = function() {
var value = JViewsSVG.target.getAttribute("width")
var index = value.indexOf('%')
if (index == -1) {
return parseFloat(value)
} else {
value  = parseFloat(value.substring(0, index))
return innerWidth*value/100
}
}

JViewsSVG.getInnerHeight = function() {
var value = JViewsSVG.target.getAttribute("height")
var index = value.indexOf('%')
if (index == -1) {
return parseFloat(value)
} else {
value  = parseFloat(value.substring(0, index))
return innerHeight*value/100
}
}

JViewsSVG.lockPane = 0

JViewsSVG.lockGlassPane = function() {
if (!JViewsSVG.glassPane) {
JViewsSVG.glassPane = JViewsSVG.target.ownerDocument.createElementNS(SVG_NS, "rect")
}
if (JViewsSVG.lockPane == 0) {
JViewsSVG.target.appendChild(JViewsSVG.glassPane)
JViewsSVG.updateGlassPane()
JViewsSVG.glassPane.setAttribute("style", "visibility:hidden;pointer-events:all")
JViewsSVG.target.addEventListener("SVGScroll", JViewsSVG.updateGlassPane, false)
}
JViewsSVG.lockPane = JViewsSVG.lockPane+1
return JViewsSVG.glassPane
}

JViewsSVG.updateGlassPane = function() {
JViewsSVG.glassPane.setAttribute("x",
-JViewsSVG.target.currentTranslate.x/JViewsSVG.target.currentScale)
JViewsSVG.glassPane.setAttribute("y",
-JViewsSVG.target.currentTranslate.y/JViewsSVG.target.currentScale)
JViewsSVG.glassPane.setAttribute("width",
	getInnerWidth()
	/JViewsSVG.target.currentScale)
JViewsSVG.glassPane.setAttribute("height",
	getInnerHeight()
	/JViewsSVG.target.currentScale)
}

JViewsSVG.releaseGlassPane = function() {
JViewsSVG.lockPane = JViewsSVG.lockPane - 1
if (JViewsSVG.lockPane == 0) {
JViewsSVG.target.removeEventListener("SVGScroll", JViewsSVG.updateGlassPane, false)
JViewsSVG.target.removeChild(JViewsSVG.glassPane)
}
return JViewsSVG.glassPane
}

function SVGTooltipManager() {
}

SVGTooltipManager.registerView = function(view) {

view.svg.addEventListener("mouseover", SVGTooltipManager.handleEvent , false)
view.svg.addEventListener("mouseout", SVGTooltipManager.handleEvent , false)
}

SVGTooltipManager.unregisterView = function(view) {
view.svg.removeEventListener("mouseover", SVGTooltipManager , false)
view.svg.removeEventListener("mousout", SVGTooltipManager , false)
}

SVGTooltipManager.handleEvent = function(evt) {
var type = evt.type;
if ( SVGTooltipManager[type] != null ) SVGTooltipManager[type](evt);
}

SVGTooltipManager.mouseover = function(evt) {
if (SVGTooltipManager.lastTarget == null) {
var tmp = JViewsSVG.GetView(evt.currentTarget).getGraphic(evt.target)
if (tmp != null && tmp.getElementsByTagNameNS(SVG_NS, "title").length != 0) {
SVGTooltipManager.launchTooltip(tmp)


__SVGTooltipManagerX = evt.clientX
__SVGTooltipManagerY = evt.clientY
}
} else {
var tmp = JViewsSVG.GetView(evt.currentTarget).getGraphic(evt.target)
if (tmp == SVGTooltipManager.lastTarget) {
SVGTooltipManager.releaseTooltip()	
SVGTooltipManager.launchTooltip(tmp)


__SVGTooltipManagerX = evt.clientX
__SVGTooltipManagerY = evt.clientY
}
}
}

SVGTooltipManager.mouseout = function(evt) {
if (SVGTooltipManager.lastTarget != null) {
var tmp = JViewsSVG.GetView(evt.currentTarget).getGraphic(evt.relatedTarget)
if (tmp == null || tmp != SVGTooltipManager.lastTarget)
SVGTooltipManager.releaseTooltip()
}
}

SVGTooltipManager.releaseTooltip = function() {
if (SVGTooltipManager.timeOut != null) {
clearTimeout(SVGTooltipManager.timeOut)
SVGTooltipManager.timeOut = null
} else {
SVGTooltipManager.hideTooltip()
}
SVGTooltipManager.lastTarget = null
}

SVGTooltipManager.launchTooltip = function(target) {
SVGTooltipManager.lastTarget = target
SVGTooltipManager.timeOut =
setTimeout("showTooltip()",
SVGTooltipManager.delay)
}

function showTooltip() {
var tooltipinfo = SVGTooltipManager.lastTarget.getElementsByTagNameNS(SVG_NS, "title").item(0)
var svgDoc = SVGTooltipManager.lastTarget.ownerDocument
var mgrView = JViewsSVG.GetParentView(SVGTooltipManager.lastTarget)
var x = mgrView.xClientToMainCS(__SVGTooltipManagerX)
var y = mgrView.yClientToMainCS(__SVGTooltipManagerY)
SVGTooltipManager.tooltip = svgDoc.createElement("g")
var zoomFactor = mgrView.svg.parentNode.currentScale
var zx = zoomFactor*mgrView.sx
var zy = zoomFactor*mgrView.sy
var x11b = 1/zx
var x22b = 1/zy
var x0 = (zx - 1)*x/zx
var y0 = (zy - 1)*y/zy
SVGTooltipManager.tooltip.setAttribute("transform", "matrix("+x11b+" 0 0 "+x22b+
" "+x0+" "+y0+")")
SVGTooltipManager.tooltip.setAttribute("style", "pointer-events:none")
var rect = svgDoc.createElementNS(SVG_NS, "rect")
rect.setAttribute("x", x)
rect.setAttribute("y", y)
rect.setAttribute("rx", 4)
rect.setAttribute("ry", 4)
rect.setAttribute("class", "tooltip")
SVGTooltipManager.tooltip.appendChild(rect)
var width = 4
var height = 16

var text = svgDoc.createElementNS(SVG_NS, "text")
text.setAttribute("x", x)
text.setAttribute("y", y)
text.setAttribute("style", "text-rendering:optimizeSpeed")
text.setAttribute("class", "tooltipText")

var contents = tooltipinfo.getElementsByTagNameNS(GF_NS, "line")
if (contents.length == 0) {
text.setAttribute("x", 4+x)
text.setAttribute("y", 16+y)
var cdata = svgDoc.createTextNode(tooltipinfo.firstChild.data)
text.appendChild(cdata)
width = text.getComputedTextLength()+8
height+=6
} else {
for (var i = 0; i < contents.length; i++) {
var tspan = svgDoc.createElementNS(SVG_NS, "tspan")
tspan.setAttribute("x", x)
tspan.setAttribute("dx", "4")
if (i == 0)
tspan.setAttribute("dy", "16")
else
tspan.setAttribute("dy", "18")
var cdata = svgDoc.createTextNode(contents.item(i).firstChild.data)
tspan.appendChild(cdata)
text.appendChild(tspan)
width = Math.max(width, tspan.getComputedTextLength()+8)
height+=12
}
}

rect.setAttribute("height", height)
rect.setAttribute("width", width)

var max =  mgrView.xClientToMainCS(mgrView.svgX + mgrView.svgWidth)
var dx = (max - (x11b*width + x))/x11b
max =  mgrView.yClientToMainCS(mgrView.svgY + mgrView.svgHeight)
var dy = (max - (x22b*height + y))/x22b
if (dx < 0 || dy < 0) {
var tstr = " translate("
if (dx < 0)
tstr = tstr+dx+" "
else
tstr = tstr+"0 "
if (dy < 0)
tstr = tstr+dy+")"
else
tstr = tstr+"0)"
SVGTooltipManager.tooltip.setAttribute("transform",
SVGTooltipManager.tooltip.getAttribute("transform")+tstr)
}

SVGTooltipManager.tooltip.appendChild(text)
JViewsSVG.GetParentView(SVGTooltipManager.lastTarget).
lockTempTopLayer().appendChild(SVGTooltipManager.tooltip)
SVGTooltipManager.timeOut = null
}

SVGTooltipManager.hideTooltip = function() {
if (SVGTooltipManager.tooltip != null) {
SVGTooltipManager.tooltip.setAttribute("visibility", "hidden")
SVGTooltipManager.tooltip.parentNode.
removeChild(SVGTooltipManager.tooltip)
SVGTooltipManager.tooltip = null
JViewsSVG.GetParentView(SVGTooltipManager.lastTarget).releaseTempTopLayer()
}
}

SVGTooltipManager.delay = 1400


function SVGCheckBox(parent, text) {
this.parent = parent
this.text = text
}

SVGCheckBox.prototype = new Object

SVGCheckBox.prototype.toSVG = function() {
this.layerItem = document.createElementNS(SVG_NS, "g")
var checkbox = document.createElementNS(SVG_NS, "g")
checkbox.setAttribute("style", "fill:none;stroke-linecap:square")
var bottom = document.createElementNS(SVG_NS, "rect")
bottom.setAttribute("x", "0")
bottom.setAttribute("y", "0")
bottom.setAttribute("width", "10")
bottom.setAttribute("height", "10")
bottom.setAttribute("style", "visibility:hidden;pointer-events:all")
var line1 = document.createElementNS(SVG_NS, "polyline")
line1.setAttribute("points", "10 0 10 10 0 10")




line1.setAttribute("stroke", "lightGray")
var line2 = document.createElementNS(SVG_NS, "polyline")
line2.setAttribute("points", "0 10 0 0 10 0")

line2.setAttribute("stroke", "gray")
this.check = document.createElementNS(SVG_NS, "polyline")
this.check.setAttribute("points", "2.5 5 5 7.5 7.5 2.5")
this.check.setAttribute("style", "stroke-width:2;fill:none")
this.check.setAttribute("visibility", "hidden")
checkbox.appendChild(bottom)
checkbox.appendChild(line1)
checkbox.appendChild(line2)
checkbox.appendChild(this.check)	

this.layerItem.appendChild(checkbox)

this.layerTitle = document.createElementNS(SVG_NS, "text")
this.layerTitle.setAttribute("style", "stroke:none")
this.layerTitle.setAttribute("x", "20")
this.layerTitle.setAttribute("y", "10")
this.layerTitle.appendChild(document.createTextNode(this.text))

this.layerItem.appendChild(this.layerTitle)

this.parent.appendChild(this.layerItem)

return this.layerItem
}

SVGCheckBox.prototype.handleEvent = function(evt) {
this.setChecked(!this.isChecked())
}

SVGCheckBox.prototype.isChecked = function() {
return this.check.getAttribute("visibility").length == 0
}

SVGCheckBox.prototype.setChecked = function(value) {
if (value && !this.isChecked()) {
this.check.removeAttribute("visibility")
this.fireStateChangedListeners()
} else
if (!value && this.isChecked()) {
this.check.setAttribute("visibility", "hidden")
this.fireStateChangedListeners()
}
}

SVGCheckBox.prototype.fireStateChangedListeners = function() {
if (this.listeners == null)
return
for (var i = 0; i < this.listeners.length; i++)
this.listeners[i].stateChanged(this)
}

SVGCheckBox.prototype.addStateChangedListener = function(listener) {
if (this.listeners == null)
this.listeners = new Array()
this.listeners[this.listeners.length] = listener
}

SVGCheckBox.prototype.removeStateChangedListener = function(listener) {
var j = this.listeners.length
for (var i = 0; i < this.listeners.length; i++) {
if (listener == this.listeners[i])
j = i
}
if (j != this.listeners.length)
removeStateChangedIndex(j)
}

SVGCheckBox.prototype.removeStateChangedIndex = function(index) {
if (index < this.listeners.length && j >= 0) {
for (var i = index + 1; i < this.listeners.length; i++) {
this.listeners[i-1] = this.listeners[i]
}
this.listeners.length = this.listeners.length - 1
}
}

SVGCheckBox.prototype.setEnabled = function(value) {
if (value) {
this.layerItem.addEventListener("click", this, false)
this.check.setAttribute("class", "enabledCheckBox")
this.layerTitle.setAttribute("class", "enabledCheckBox")
} else {
this.layerItem.removeEventListener("click", this, false)
this.check.setAttribute("class", "disabledCheckBox")
this.layerTitle.setAttribute("class", "disabledCheckBox")
}
}


function SVGTitledView(element) {
this.__superCtor__ = eval("SVGAbstractView")
this.__superCtor__(element)
this.__superCtor__ = null
if (!element)
return
if (element.getAttribute("showTitle") == "true") {
var list = this.svg.getElementsByTagName("title")
var titleStr = list.item(0).firstChild.data
var titleText = document.createElementNS(SVG_NS, "text")
titleText.setAttribute("class", "titleText")
titleText.setAttribute("x", "50%")
titleText.setAttribute("text-anchor", "middle")
titleText.appendChild(document.createTextNode(titleStr))
var bbox = titleText.getBBox()
titleText.setAttribute("y", bbox.height+5)

var title = document.createElementNS(SVG_NS, "rect")
title.setAttribute("x", "0%")
title.setAttribute("y", "0%")
title.setAttribute("width", "100%")
title.setAttribute("height", bbox.height + 12)
title.setAttribute("class", "title")
this.svg.appendChild(title)
this.svg.appendChild(titleText)
this.titleHeight = bbox.height + 12
}
}

SVGTitledView.prototype = new SVGAbstractView

SVGAbstractView.prototype.getTitleHeight = function() {
if (this.titleHeight)
return this.titleHeight
else
return 0
}


function SVGLayerView(element, view) {
this.__superCtor__ = eval("SVGTitledView")
this.__superCtor__(element)
this.__superCtor__ = null
this.view = view
}

SVGLayerView.prototype = new SVGTitledView

SVGLayerView.prototype.toSVG = function() {
var value = this.getTitleHeight()
for (var i = 0; i < this.view.getLayersCount(); i++) {
var layer = this.view.getLayer(i)
checkbox = new SVGCheckBox(this.svg, layer.getName())
var layerItem = checkbox.toSVG()
checkbox.setChecked(layer.isVisible())
checkbox.setEnabled(!layer.isFiltered())
checkbox.userObj = layer
checkbox.addStateChangedListener(this)
checkbox.visibilityChanged = function(layer) {
this.setChecked(layer.isVisible())
this.setEnabled(!layer.isFiltered())
}
layer.addVisibilityChangedListener(checkbox)
value = value + 20
layerItem.setAttribute("transform", "translate(15, "+value+")")
}

return this
}

SVGLayerView.prototype.stateChanged = function(checkbox) {
checkbox.userObj.setVisible(checkbox.isChecked())
}