
/* global coord */

var dashedValue = [];
var dashed = [];

dashed[0] = 'line1';
dashedValue[0] = [];
dashedValue[0][0] = 5;dashedValue[0][1] = 5;


function IsNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

function IsInt(n) {
    return !isNaN(parseInt(n));
}

var getTextHeight = function(font) {

  var text = $('<span>Hg</span>').css({ fontFamily: font });
  var block = $('<div style="display: inline-block; width: 1px; height: 0px;"></div>');

  var div = $('<div></div>');
  div.append(text, block);

  var body = $('body');
  body.append(div);

  try {

    var result = {};

    block.css({ verticalAlign: 'baseline' });
    result.ascent = block.offset().top - text.offset().top;

    block.css({ verticalAlign: 'bottom' });
    result.height = block.offset().top - text.offset().top;

    result.descent = result.height - result.ascent;

  } finally {
    div.remove();
  }

  return result;
};

function String2XMLString(text)
{
    if (typeof text !== 'undefined' && text !== null)
    {
        var XMLtext = '',i;
        for(i = 0;i < text.length;i++)
        {
            if (text[i] === '"')
            {
                XMLtext = XMLtext + '&quot;';
                continue;
            }
            if (text[i] === '<')
            {
                XMLtext = XMLtext + '&lt;';
                continue;
            }
            if (text[i] === '>')
            {
                XMLtext = XMLtext + '&gt;';
                continue;
            }
            if (text[i] === '&')
            {
                XMLtext = XMLtext + '&amp;';
                continue;
            }
            XMLtext = XMLtext + text[i];
        }
        return XMLtext;
    }
    return null;
}

function XMLString2String(text)
{
    return text;
}


function GETproperty(classOrId,property){ 
    var FirstChar = classOrId.charAt(0);  var Remaining= classOrId.substring(1);
    var elem = (FirstChar ==='#') ?  document.getElementById(Remaining) : document.getElementsByClassName(Remaining)[0];
    if (elem === null)
        return null;
    return window.getComputedStyle(elem,null).getPropertyValue(property);
}

var XMLnoSpace = 1; 
var _TObjectIdentifier = 0;

function TObject(){
    //Constructor


    TObject.prototype.InitConstructor = function(){
        
        this.type = 'TObject';
        this.objectManager = null;
        this.identifier = _TObjectIdentifier++;
        this.XMLNodeEnter = true;
    };
    this.InitConstructor();

    
    TObject.prototype.InitConstructor2 = function(){
    };
    
    /**
    * @param _object {[object Object]} 
    * @return {null}
    */
    TObject.prototype.Init = function(_object){
        //TODO: Implement Me 
        this.SetType(_object.GetType());
        if (typeof _object !== 'undefined' && _object !== null)
        {
            if (typeof _object.objectManager !== 'undefined' && _object.objectManager !== null && _object.objectManager.IsType('TObjectManager'))
                this.objectManager = _object.objectManager;
            if (typeof _object.XMLNodeEnter !== 'undefined' && _object.XMLNodeEnter !== null)
                this.XMLNodeEnter = _object.XMLNodeEnter;            
        }
    };


    /**
    * @param _type {[object Object]} 
    * @return {null}
    */
    TObject.prototype.SetType = function(_type){
        //TODO: Implement Me 
        if (typeof _type === 'undefined' && _type !== null)
            return;
        this.type = new String(_type).toString();
    };


    TObject.prototype.GetType = function(){
        //TODO: Implement Me 
        if (typeof this.type !== 'undefined' && this.type !== null)
            return new String(this.type).toString();
        else
            return null;
//        return new String(this.type);
    };


    TObject.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === 'TObject')
                return true;
            else
                return false;
        }else
            return false;
//        return new String(this.type);
    };


    TObject.prototype.GetIdentifier = function(){
        //TODO: Implement Me 
       if (typeof this.identifier !== 'undefined' && this.identifier !== null)
            return this.identifier;
        else
            return -1;
    };

    TObject.prototype.SetObjectManager = function(objManager){
        //TODO: Implement Me 
       if (typeof objManager !== 'undefined')
            this.objectManager = objManager;
        else
            this.objectManager =  null;
    };

    TObject.prototype.GetObjectManager = function(){
        //TODO: Implement Me 
       if (typeof this.objectManager !== 'undefined')
            return this.objectManager;
        else
            return null;
    };

    TObject.prototype.XMLSpace = function(noSpace){
        //TODO: Implement Me 
        if (typeof noSpace !== 'undefined' && noSpace !== null && IsInt(noSpace))
        {
            var i,text = '';
            for (i = 0;i < noSpace;i++)
                text = text + ' ';
            return text;
        }
        return '';
    };

    TObject.prototype.SaveXMLHeader = function(){        
        return '';
    };
    
    TObject.prototype.SaveXMLBody = function(noSpace){        
        return '';
    };
    
    TObject.prototype.SaveXML = function(noSpace){
        if (typeof noSpace === 'undefined' || noSpace === null || !IsInt(noSpace))
            noSpace = XMLnoSpace;
        var text = this.XMLSpace(noSpace) + '<' + this.GetType() + this.SaveXMLHeader() +'>';
        if (this.XMLNodeEnter) text = text + '\n';
        text = text + this.SaveXMLBody(noSpace + XMLnoSpace);
        if (this.XMLNodeEnter) text = text + this.XMLSpace(noSpace);
        text = text + '</' + this.GetType() +'>\n';
        
        return text;
    };
    
    TObject.prototype.XMLFindTag = function(tags)
    {
        if (tags !== null)
        {
            var i;
            for (i = 0;i < tags.length;i++)
            {
                if (tags[i] !== null);
                    return tags[i];
            }
        }
        return null;
    };
    
    TObject.prototype.ReadXML = function(tag){
    };
    
    TObject.prototype.LoadXML = function(tag){
        if (typeof tag !== 'undefined' && tag !== null && tag.nodeName === this.GetType())
        {
//            var tag = this.XMLFindTag(tags.getElementsByTagName(this.GetType()));
            if (tag !== null)
            {
                this.ReadXML(tag);
            }
        };
    };
    
    TObject.prototype.SetXMLNodeEnter = function(nodeEnter){        
        if (typeof nodeEnter !== 'undefined' && nodeEnter !== null)
            this.XMLNodeEnter = nodeEnter;
    };

    TObject.prototype.GetXMLNodeEnter = function(){        
        return this.XMLNodeEnter;
    };
}


function TListElement(){
    var type = 'TListElement';
    TListElement.prototype.InitConstructor = function(){
        TObject.prototype.InitConstructor.call(this);
        
        this.object = null;
        this.nextElement = null;
        this.prevElement = null;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TListElement.prototype.Init = function(_object){
        //TODO: Implement Me 
        TObject.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TListElement') && objM !== null)
        {
            this.object = objM.copy(_object.object);
            this.nextElement = null;
            this.prevElement = null;
        }
    };


    TListElement.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TObject.prototype.IsType.call(this,_type);
    };

    TListElement.prototype.AddObject = function(ob){
        //TODO: Implement Me 
        if (typeof ob !== 'undefined')
        {
            if (ob === null)
                this.object = null;
            else
            {
                if (ob.IsType('TObject'))
                    this.object = ob;
            }
        }
    };

    TListElement.prototype.GetObject = function(){
        return this.object;
    };

}

TListElement.prototype = new TObject();


function TList(){
    var type = 'TList';
    TList.prototype.InitConstructor = function(){
        TObject.prototype.InitConstructor.call(this);
        
        this.lastElement = null;
        this.firstElement = null;
        this.currentElement = null;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TList.prototype.Init = function(_object){
        //TODO: Implement Me 
        TObject.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TList'))
        {
            this.lastElement = null;
            this.firstElement = null;
            this.currentElement = null;
        }
    };

    TList.prototype.Add = function(ob){
        var objM = this.GetObjectManager();
        if (typeof objM !== 'undefined' && objM !== null)
        {
            var element = objM.newObject('TListElement');
            if (element !== null)
            {
                element.AddObject(ob);
                if (this.firstElement === null)
                {
                    this.firstElement = element;
                    this.lastElement = element;
                }else
                {
                    if (this.currentElement === null)
                        this.currentElement = this.firstElement;
                    
                    element.prevElement = this.currentElement;
                    if (this.currentElement.nextElement === null)
                    {
                        this.lastElement = element;
                    }else
                    {
                        element.nextElement = this.currentElement.nextElement;
                        if (this.currentElement.nextElement !== null)
                            this.currentElement.nextElement.prevElement = element;
                    }
                    this.currentElement.nextElement = element;
                }
                this.currentElement = element;
            }
        }
    };

    TList.prototype.GetData = function(){
        if (this.currentElement !== null)
        {
            return this.currentElement.GetObject();
        }
        return null;
    };

    TList.prototype.First = function(){
        this.currentElement = this.firstElement;
        return this.currentElement;
    };

    TList.prototype.Last = function(){
        this.currentElement = this.lastElement;
        return this.currentElement;
    };

    TList.prototype.Next = function(){
        if (this.currentElement !== null)
            this.currentElement = this.currentElement.nextElement;
        return this.currentElement;
    };

    TList.prototype.Previous = function(){
        if (this.currentElement !== null)
            this.currentElement = this.currentElement.prevElement;
        return this.currentElement;
    };
}

TList.prototype = new TObject();

function TVector(){
    var type = 'TVector';
    TVector.prototype.InitConstructor = function(){
        TObject.prototype.InitConstructor.call(this);
        
        this.coordinates = [];
        this.SetType(type);
            
    };
    this.InitConstructor();

    TVector.prototype.Init = function(_object){
        //TODO: Implement Me 
        TObject.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TVector') && objM !== null)
        {
            if (typeof _object.coordinates !== 'undefined' && _object.coordinates !== null && _object.coordinates.length > 0)
            var i,n = _object.coordinates.length;
            for(i = 0;i < n;i++)
                this.coordinates[i] = _object.coordinates[i];
        }
    };


    TVector.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TObject.prototype.IsType.call(this,_type);
    };

    TVector.prototype.GetN = function(){
        return this.coordinates.length;
    };

    TVector.prototype.GetData = function(x){
        if (typeof x !== 'undefined' && x !== null && IsInt(x))
        {
            if (x >= 0 && x < this.coordinates.length)
            {
                return this.coordinates[x];
            }
        }
        return null;
    };


    TVector.prototype.SetCoordinate = function(position, coord){
        //TODO: Implement Me 
        if (typeof position !== 'undefined' && position !== null && IsInt(position) && typeof coord !== 'undefined' && coord !== null && IsNumeric(coord) )
        {
            if (position >= 0)
                this.coordinates[position] = coord;
        }
    };

    TVector.prototype.GetCoordinate = function(position){
        //TODO: Implement Me 
        if (typeof position !== 'undefined' && position !== null && IsInt(position))
        {
            if (position >= 0 && position < this.coordinates.length)
                return this.coordinates[position];
        }
        return null;

    };
    TVector.prototype.SetZeros = function(n){
        if ((typeof n === 'undefined' || n === null) && (typeof this.coordinates !== 'undefined' && this.coordinates !== null && this.coordinates.length >= 0))
            n = this.coordinates.length;
        if (typeof n !== 'undefined' && n !== null && IsInt(n))
        {
            var i;
            this.coordinates = [];
            for (i = 0;i < n;i++)
            {
                this.coordinates[i] = 0;
            }            
        }
    };

    TVector.prototype.Subtraction = function(subtrahend){
        if (typeof subtrahend !== 'undefined' && subtrahend !== null && subtrahend.IsType('TVector'))
        {
            var n_ = subtrahend.GetN();
            var n__ = this.GetN();
            if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_))
            {
                if (n_ === n__)
                {
                    var i;
                    for(i = 0;i < n_;i++)
                        this.coordinates[i] = this.coordinates[i] - subtrahend.GetCoordinate(i);
                }                
            }
        }
    };

    TVector.prototype.Addition = function(addend){
        if (typeof addend !== 'undefined' && addend !== null && addend.IsType('TVector'))
        {
            var n_ = addend.GetN();
            var n__ = this.GetN();
            if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_))
            {
                if (n_ === n__)
                {
                    var i;
                    for(i = 0;i < n_;i++)
                        this.coordinates[i] = this.coordinates[i] + addend.GetCoordinate(i);
                }                
            }
        }
    };
    
    TVector.prototype.GetTypeSpace = function(){
        //TODO: Implement Me 
        return null;
    };

    TVector.prototype.Norm = function(){
        var n = this.GetN();
        if (typeof n !== 'undefined' && n !== null && IsInt(n))
        {
            var i,result = 0;
            for(i = 0;i < n;i++)
            {
                result = result + this.coordinates[i]*this.coordinates[i];
            }
            return Math.sqrt(result);
        }
        return null;
    };
    
    TVector.prototype.Distance = function(vector){
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            var tmp = objM.copy(this);
            if (tmp !== null)
            {
                tmp.Subtraction(vector);
                return tmp.Norm();
            }
        }
        return null;
    };
    
    TVector.prototype.MultiplicationScalar = function(scalar){
        if (typeof scalar !== 'undefined' && scalar !== null && IsNumeric(scalar))
        {
            var n = this.GetN();
            if (typeof n !== 'undefined' && n !== null && IsInt(n))
            {
                if (n > 0)
                {
                    var i;
                    for(i = 0;i < n;i++)
                        this.coordinates[i] = this.coordinates[i]*scalar;
                }                
            }
        }
    };

    TVector.prototype.ScalarProduct = function(vector){
        if (typeof vector !== 'undefined' && vector !== null && vector.IsType('TVector'))
        {
            var n_ = vector.GetN();
            var n__ = this.GetN();
            if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_))
            {
                if (n_ === n__)
                {
                    var i,s = 0;
                    for(i = 0;i < n_;i++)
                        s = s + this.coordinates[i]*vector.GetCoordinate(i);
                    return s;
                }                
            }
        }
        return null;
    };

    TVector.prototype.VectorComponent = function(vector){
        if (typeof vector !== 'undefined' && vector !== null && vector.IsType('TVector'))
        {
            var tmp1 = this.ScalarProduct(vector);
            var tmp2 = this.ScalarProduct(this);
            if (tmp1 !== null && tmp2 !== null)
                return tmp1/tmp2;
        }
        return null;
    };

}

TVector.prototype = new TObject();

function TVector2DT(){
    var type = 'TVector2DT';
    TVector2DT.prototype.InitConstructor = function(){
        TVector.prototype.InitConstructor.call(this);
        
        this.SetType(type);
        this.SetZeros(3);
        this.SetCoordinate(2,1);
    };
    this.InitConstructor();

    TVector2DT.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVector.prototype.Init.call(this,_object);
//        TObject.Init(_object);
/*        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TVector') && objM !== null)
        {
            if (typeof _object.coordinates !== 'undefined' && _object.coordinates !== null && _object.coordinates.length > 0)
            var i,n = _object.coordinates.length;
            for(i = 0;i < n;i++)
                this.coordinates[i] = _object.coordinates[i];
        }*/
    };


    TVector2DT.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVector.prototype.IsType.call(this,_type);
    };

    TVector2DT.prototype.GetX = function(){
        return this.GetCoordinate(0);
    };

    TVector2DT.prototype.GetY = function(){
        return this.GetCoordinate(1);
    };

    TVector2DT.prototype.SetX = function(data){
        this.SetCoordinate(0,data);
    };

    TVector2DT.prototype.SetY = function(data){
        this.SetCoordinate(1,data);
    };

    TVector2DT.prototype.SetCoordinates = function(x,y){
        this.SetX(x);
        this.SetY(y);
    };

    TVector2DT.prototype.SetZeros = function(n){
        TVector.prototype.SetZeros.call(this,n);
        this.SetCoordinate(n - 1,1);
    };

    TVector2DT.prototype.GetTypeSpace = function(){
        //TODO: Implement Me 
        return '2D';
    };

    TVector2DT.prototype.Subtraction = function(subtrahend){
        TVector.prototype.Subtraction.call(this,subtrahend);
        this.SetCoordinate(2,1);
    };

    TVector2DT.prototype.Addition = function(addend){
        TVector.prototype.Addition.call(this,addend);
        this.SetCoordinate(2,1);    
    };
    
    TVector2DT.prototype.Norm = function(){
        var n = this.GetN();
        if (typeof n !== 'undefined' && n !== null && IsInt(n))
        {
            var i,result = 0;
            for(i = 0;i < n-1;i++)
            {
                result = result + this.coordinates[i]*this.coordinates[i];
            }
            return Math.sqrt(result);
        }
        return null;
    };
    
    TVector2DT.prototype.MultiplicationScalar = function(scalar){
        TVector.prototype.MultiplicationScalar.call(this,scalar);
        this.SetCoordinate(2,1);    
    };    

    TVector2DT.prototype.ScalarProduct = function(vector){
        if (typeof vector !== 'undefined' && vector !== null && vector.IsType('TVector'))
        {
            var n_ = vector.GetN();
            var n__ = this.GetN();
            if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_))
            {
                if (n_ === n__)
                {
                    var i,s = 0;
                    for(i = 0;i < n_-1;i++)
                        s = s + this.coordinates[i]*vector.GetCoordinate(i);
                    return s;
                }                
            }
        }
        return null;
    };

}

TVector2DT.prototype = new TVector();

function TVector3DT(){
    var type = 'TVector3DT';
    TVector3DT.prototype.InitConstructor = function(){
        TVector.prototype.InitConstructor.call(this);
        
        this.SetType(type);
        this.SetZeros(4);
        this.SetCoordinate(3,1);
    };
    this.InitConstructor();

    TVector3DT.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVector.prototype.Init.call(this,_object);
//        TObject.Init(_object);
/*        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TVector') && objM !== null)
        {
            if (typeof _object.coordinates !== 'undefined' && _object.coordinates !== null && _object.coordinates.length > 0)
            var i,n = _object.coordinates.length;
            for(i = 0;i < n;i++)
                this.coordinates[i] = _object.coordinates[i];
        }*/
    };


    TVector3DT.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVector.prototype.IsType.call(this,_type);
    };

    TVector3DT.prototype.GetX = function(){
        return this.GetCoordinate(0);
    };

    TVector3DT.prototype.GetY = function(){
        return this.GetCoordinate(1);
    };

    TVector3DT.prototype.GetZ = function(){
        return this.GetCoordinate(2);
    };

    TVector3DT.prototype.SetX = function(data){
        this.SetCoordinate(0,data);
    };

    TVector3DT.prototype.SetY = function(data){
        this.SetCoordinate(1,data);
    };

    TVector3DT.prototype.SetZ = function(data){
        this.SetCoordinate(2,data);
    };

    TVector3DT.prototype.SetCoordinates = function(x,y,z){
        this.SetX(x);
        this.SetY(y);
        this.SetZ(z);
    };

    TVector3DT.prototype.SetZeros = function(n){
        TVector.prototype.SetZeros.call(this,n);
        this.SetCoordinate(n - 1,1);
    };

    TVector3DT.prototype.GetTypeSpace = function(){
        //TODO: Implement Me 
        return '3D';
    };

    TVector3DT.prototype.Subtraction = function(subtrahend){
        TVector.prototype.Subtraction.call(this,subtrahend);
        this.SetCoordinate(3,1);
    };

    TVector3DT.prototype.Addition = function(addend){
        TVector.prototype.Addition.call(this,addend);
        this.SetCoordinate(3,1);    
    };
    
    TVector3DT.prototype.Norm = function(){
        var n = this.GetN();
        if (typeof n !== 'undefined' && n !== null && IsInt(n))
        {
            var i,result = 0;
            for(i = 0;i < n-1;i++)
            {
                result = result + this.coordinates[i]*this.coordinates[i];
            }
            return Math.sqrt(result);
        }
        return null;
    };
    
    TVector3DT.prototype.MultiplicationScalar = function(scalar){
        TVector.prototype.MultiplicationScalar.call(this,scalar);
        this.SetCoordinate(3,1);    
    };    

    TVector3DT.prototype.ScalarProduct = function(vector){
        if (typeof vector !== 'undefined' && vector !== null && vector.IsType('TVector'))
        {
            var n_ = vector.GetN();
            var n__ = this.GetN();
            if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_))
            {
                if (n_ === n__)
                {
                    var i,s = 0;
                    for(i = 0;i < n_-1;i++)
                        s = s + this.coordinates[i]*vector.GetCoordinate(i);
                    return s;
                }                
            }
        }
        return null;
    };

}

TVector3DT.prototype = new TVector();

function TDrawContext(){
    var type = 'TDrawContext';
    TDrawContext.prototype.InitConstructor = function(){
        TObject.prototype.InitConstructor.call(this);
        
        this.matrixes = [];
        this.transformation = null;
        this.SetType(type);
        this.defaultColour = null;
        this.defaultBackgroundColour = null;
        this.defaultTextColour = null;
        this.defaultFont = 'Arial';
        this.defaultFontSize = 12;
        this.topStack = -1;
        this.scale = 1;
        this.textScaleYN = true;
        this.normalFontSize = 10;
        this.fontRelativeSize = 'normalsize';
        this.fontStyle = [];
        this.parameters = [];
        this.correctScale = 1;
        this.dashedType = null;
    };
    this.InitConstructor();

    TDrawContext.prototype.Init = function(_object){
        TObject.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TDrawContext') && objM !== null)
        {
            var i;
            if (typeof _object.transformation !== 'undefined' && _object.transformation !== null)
                this.transformation = objM.copy(_object.transformation);
            if (typeof _object.defaultColour !== 'undefined' && _object.defaultColour !== null && defaultColour.IsType('TColour'))
                this.defaultColour = objM.copy(_object.defaultColour);
            if (typeof _object.defaultBackgroundColour !== 'undefined' && _object.defaultBackgroundColour !== null && defaultBackgroundColour.IsType('TColour'))
                this.defaultBackgroundColour = objM.copy(_object.defaultBackgroundColour);
            if (typeof _object.defaultTextColour !== 'undefined' && _object.defaultTextColour !== null && defaultTextColour.IsType('TColour'))
                this.defaultTextColour = objM.copy(_object.defaultTextColour);
            if (typeof _object.defaultFont !== 'undefined' && _object.defaultFont !== null)
            {
                this.defaultFont = new String(_object.defaultFont);
                if (this.defaultFont !== null)
                    this.defaultFont = this.defaultFont.toString();
            }
            if (typeof _object.defaultFontSize !== 'undefined' && _object.defaultFontSize !== null && IsNumeric(_object.defaultFontSize))
                this.defaultFontSize = _object.defaultFontSize;
            if (typeof _object.topStack !== 'undefined' && _object.topStack !== null && IsInt(_object.topStack))
                this.topStack = _object.topStack;
            if (typeof _object.scale !== 'undefined' && _object.scale !== null && IsNumeric(_object.scale))
                this.scale = _object.scale;
            if (typeof _object.transformation !== 'undefined' && _object.transformation !== null)
                this.transformation = objM.copy(_object.transformation);
            if (typeof _object.matrixes !== 'matrixes' && _object.matrixes !== null && _object.matrixes.length > 0)
            {
                var n = _object.matrixes.length;
                for(i = 0;i < n;i++)
                    this.matrixes[i] = objM.copy(_object.matrixes[i]);
            }
            if (typeof _object.textScaleYN !== 'undefined' && _object.textScaleYN !== null)
                this.textScaleYN = _object.textScaleYN;
            if (typeof _object.normalFontSize !== 'undefined' && _object.normalFontSize !== null && IsNumeric(_object.normalFontSize))
                this.normalFontSize = _object.normalFontSize;
            if (typeof _object.fontRelativeSize !== 'undefined' && _object.fontRelativeSize !== null)
            {
                this.fontRelativeSize = new String(_object.fontRelativeSize);
                if (this.fontRelativeSize !== null)
                    this.fontRelativeSize = this.fontRelativeSize.toString();
            }
            if (typeof _object.fontStyle !== 'undefined' && _object.fontStyle !== null)
            {
                for (i = 0;i < _object.fontStyle.length;i++)
                {
                    if (typeof _object.fontStyle[i] !== 'undefined' && _object.fontStyle[i] !== null)
                    {
                        this.fontStyle[i] = new String(_object.fontStyle[i]);
                        if (this.fontStyle[i] !== null)
                            this.fontStyle[i] = this.fontStyle[i].toString();
                    }
                }
            }
            if (typeof _object.parameters !== 'undefined' && _object.parameters !== null)
            {
                for (i = 0;i < _object.parameters.length;i++)
                {
                    if (typeof _object.parameters[i] !== 'undefined' && _object.parameters[i] !== null && IsNumeric(_object.parameters[i]))
                    {
                        this.parameters[i] = _object.parameters[i];
                    }
                }
            }
            if (typeof _object.correctScale !== 'undefined' && _object.correctScale !== null && IsNumeric(_object.correctScale))
                this.correctScale = _object.correctScale;
            if (typeof _object.dashedType !== 'undefined' && _object.dashedType !== null)
            {
                this.dashedType = new String(_object.dashedType);
                if (this.dashedType !== null)
                    this.dashedType = this.dashedType.toString();
            }
        }
    };


    TDrawContext.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TObject.prototype.IsType.call(this,_type);
    };

    TDrawContext.prototype.SetTransformation = function(matrix){
        var objM = this.GetObjectManager();
        if (typeof matrix !== 'undefined' && matrix !== null && matrix.IsType('TMatrixTransformation') && objM !== null)
            this.transformation = objM.copy(matrix);
    };

    TDrawContext.prototype.GetTransformation = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
            return  objM.copy(this.transformation);
        return null;
    };

    TDrawContext.prototype.PushMatrix = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            this.topStack = this.topStack + 1;
            var matrix = objM.copy(this.transformation);
            this.matrixes[this.topStack] = matrix;
        }
    };

    TDrawContext.prototype.PopMatrix = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            this.transformation = objM.copy(this.matrixes[this.topStack]);
//            this.matrixes.slice(this.matrixes.length - 1,1);
            this.matrixes[this.topStack] = null;
            this.topStack = this.topStack - 1;
        }
    };
    
    TDrawContext.prototype.MultiplicationMatrix = function(matrix){
        var objM = this.GetObjectManager();
        if (typeof matrix !== 'undefined' && matrix !== null && matrix.IsType('TMatrixTransformation') && objM !== null)
        {
            if (this.transformation === null)
                this.transformation = objM.copy(matrix);
            else
                this.transformation.MatrixMultiplication(matrix);
        }
    };

    TDrawContext.prototype.Begin = function(type){
    };

    TDrawContext.prototype.End = function(){
    };
    
    TDrawContext.prototype.Vertex2D = function(x,y){
    };

    TDrawContext.prototype.Vertex3D = function(x,y,z){
    };

    TDrawContext.prototype.SetColour = function(colour){
    };

    TDrawContext.prototype.Text2D = function(x,y,text_,colour_,maxWidth){
    };

    TDrawContext.prototype.Text = function(coordinates,text_,colour_,maxWidth){
    };

    TDrawContext.prototype.SetFont = function(font_){
    };
    
    TDrawContext.prototype.SetFontSize = function(fontSize_){
    };

    TDrawContext.prototype.GetTextWidth = function(text,font,size,style){
    };

    TDrawContext.prototype.GetTextHeight = function(text,font,size){
    };

    TDrawContext.prototype.SetTextBaseLine = function(parameter){        
    };

    TDrawContext.prototype.SetDefaultColour = function(colour_){
        var objM = this.GetObjectManager();
        if (typeof colour_ !== 'undefined' && colour_ !== null && colour_.IsType('TColour') && objM !== null)
            this.defaultColour = objM.copy(colour_);
    };

    TDrawContext.prototype.SetDefaultBackgroundColour = function(colour_){
        var objM = this.GetObjectManager();
        if (typeof colour_ !== 'undefined' && colour_ !== null && colour_.IsType('TColour') && objM !== null)
            this.defaultBackgroundColour = objM.copy(colour_);
    };

    TDrawContext.prototype.SetDefaultTextColour = function(colour_){
        var objM = this.GetObjectManager();
        if (typeof colour_ !== 'undefined' && colour_ !== null && colour_.IsType('TColour') && objM !== null)
            this.defaultTextColour = objM.copy(colour_);
    };

    TDrawContext.prototype.SetDefaultFont = function(font_){
        if (typeof font_ !== 'undefined' && font_ !== null)
        {
            this.defaultFont = new String(font_);
            if (this.defaultFont !== null)
                this.defaultFont = this.defaultFont.toString();
        }
    };

    TDrawContext.prototype.SetDefaultFontSize = function(fontSize_){
        if (typeof fontSize_ !== 'undefined' && fontSize_ !== null && IsNumeric(fontSize_))
            this.defaultFontSize = fontSize_;
    };

    TDrawContext.prototype.GetDefaultColour = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
            return objM.copy(this.defaultColour);
        else
            return null;
    };

    TDrawContext.prototype.GetDefaultBackgroundColour = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
            return objM.copy(this.defaultBackgroundColour);
        else
            return null;
    };

    TDrawContext.prototype.GetDefaultTextColour = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
            return objM.copy(this.defaultTextColour);
        else
            return null;
    };

    TDrawContext.prototype.GetDefaultFont = function(){
        var tmp = new String(this.defaultFont);
        if (tmp !== null)
            return tmp.toString();
        else
            return null;
        
    };

    TDrawContext.prototype.GetDefaultFontSize = function(){
        return this.defaultFontSize;        
    };

    TDrawContext.prototype.SetScale = function(scale_){
        if (typeof scale_ !== null && scale_ !== null && IsNumeric(scale_))
            this.scale = scale_;
    };

    TDrawContext.prototype.GetScale = function(){
        return this.scale;
    };

    TDrawContext.prototype.SetScaleTextYN = function(YN){
        if (typeof YN !== null && YN !== null)
            this.textScaleYN = YN;
    };

    TDrawContext.prototype.GetScaleTextYN = function(){
        return this.textScaleYN;
    };

    TDrawContext.prototype.DrawImage = function(fileName,coordinates,wh,scale,alignX,alignY,img){
    };

    TDrawContext.prototype.DrawTableImage = function(coordinates,img){
    };


    TDrawContext.prototype.SetNormalFontSize = function(size){
        var tmp = size.substr(0, size.length-2);
        if (typeof tmp !== null && tmp !== null && IsNumeric(tmp))
            this.normalFontSize = tmp;
    };

    TDrawContext.prototype.GetNormalFontSize = function(){
        return this.normalFontSize;
    };

    TDrawContext.prototype.SetFontRelativeSize = function(size){
        if (typeof size !== 'undefined' && size !== null)
        {
            this.fontRelativeSize = new String(size);
            if (this.fontRelativeSize !== null)
                this.fontRelativeSize = this.fontRelativeSize.toString();
        }
        if (size === null)
            this.fontRelativeSize = null;
    };

    TDrawContext.prototype.GetFontRelativeSize = function(){
        if (typeof this.fontRelativeSize !== 'undefined' && this.fontRelativeSize !== null)
        {
            var tmp = new String(this.fontRelativeSize);
            if (tmp !== null)
                tmp = tmp.toString();
            return tmp;
        }
        return null;
    };
    
    TDrawContext.prototype.GetNumericFontRelativeSize = function(){
        if (typeof this.fontRelativeSize !== 'undefined' && this.fontRelativeSize !== null)
        {
            switch (this.fontRelativeSize)
            {
                case 'tiny':
                    return 0.547945205*this.normalFontSize;
                case 'scriptsize':
                    return 0.730593607*this.normalFontSize;
                case 'footnotesize':
                    return 0.821917808*this.normalFontSize;
                case 'small':
                    return 0.913242009*this.normalFontSize;
                case 'normalsize':
                    return this.normalFontSize;
                case 'large':
                    return 1.095890411*this.normalFontSize;
                case 'Large':
                    return 1.315068493*this.normalFontSize;
                case 'LARGE':
                    return 1.578082192*this.normalFontSize;
                case 'huge':
                    return 1.894063927*this.normalFontSize;
                case 'Huge':
                    return 2.272146119*this.normalFontSize;
            }
        }
        return this.normalFontSize;
    };

    TDrawContext.prototype.SetFontStyle = function(style){
        if (typeof style !== 'undefined' && style !== null)
        {
            var i;
            this.fontStyle = [];
            for (i = 0;i < style.length;i++)
            {
                if (typeof style[i] !== 'undefined' && style[i] !== null)
                {
                    this.fontStyle[i] = new String(style[i]);
                    if (this.fontStyle[i] !== null)
                        this.fontStyle[i] = this.fontStyle[i].toString();
                }
            }
        }
    };    

    TDrawContext.prototype.GetFontStyle = function(){
        return this.fontStyle;
    };

    TDrawContext.prototype.SetParameter = function(value,number){
        if (typeof number === 'undefined' || number === null || !IsNumeric(number) || number < 0)
            number = 0;
        if (typeof value !== 'undefined' && value !== null)
        {
            this.parameters[number] = value;
        }
    };

    TDrawContext.prototype.GetParameter = function(number){
        if (typeof number === 'undefined' || number === null || !IsNumeric(number) || number < 0)
            number = 0;
        if (this.parameters.length > number && typeof this.parameters[number] !== 'undefined' && this.parameters[number] !== null)
        {
            return this.parameters[number];
        }
        return 0;
    };

    TDrawContext.prototype.GetNParameters = function(){
        return this.parameters.length;
    };

    TDrawContext.prototype.ForeignObject = function(coordinates,wh,object,alignX,alignY){
    };

    TDrawContext.prototype.SetCorrectScale = function(correct){
        if (typeof correct !== 'undefined' && correct !== null && IsNumeric(correct))
        {
            this.correctScale = correct;
        }
    };

    TDrawContext.prototype.GetCorrectScale = function(){
        return this.correctScale;
    };

    TDrawContext.prototype.SetDashedType = function(type){
        if (typeof type !== 'undefined' && type !== null)
        {
            this.dashedType = new String(type);
            if (this.dashedType !== null)
                this.dashedType = this.dashedType.toString();
        }
        if (type === null)
            this.dashedType = null;
    };

    TDrawContext.prototype.GetDashedType = function(){
        if (this.dashedType !== null)
        {
            var tmp = new String(this.dashedType);
            if (tmp !== null)
                return tmp.toString();
        }
        return null;
    };

    TDrawContext.prototype.FindDashed = function(){
        if (typeof this.dashedType !== 'undefined' && this.dashedType !== null)
        {
            var i,n = dashed.length;
            for (i = 0;i < n;i++)
            {
                if (this.dashedType === dashed[i])
                    return i;
            }
        }
        return -1;
    };

    TDrawContext.prototype.SetLineWidth = function(width_){
    };


}

TDrawContext.prototype = new TObject();

function TDrawCanvasContext(){
    var type = 'TDrawCanvasContext';
    TDrawCanvasContext.prototype.InitConstructor = function(){
        TDrawContext.prototype.InitConstructor.call(this);
        
        this.ctx = null;
        this.type_ = '';
        this.startPath = false;
        this.colourPath = null;
        this.lineWidth = 1;
        this.font = null;
        this.fontSize = null;
        this.alignmentX = null;
        this.alignmentY = null;
        this.SetType(type);
    };
    this.InitConstructor();

    TDrawCanvasContext.prototype.InitConstructor2 = function(){
        TDrawContext.prototype.InitConstructor2.call(this);
        
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            if (this.defaultColour === null)
            {
                this.defaultColour = objM.newObject('TColourRGBA');
                this.defaultColour.SetColourRGBA(0,0,0,1);                
            }
            if (this.defaultBackgroundColour === null)
            {
                this.defaultBackgroundColour = objM.newObject('TColourRGBA');
                this.defaultBackgroundColour.SetColourRGBA(1,1,1,1);                
            }               
            if (this.defaultTextColour === null)
            {
                this.defaultTextColour = objM.newObject('TColourRGBA');
                this.defaultTextColour.SetColourRGBA(0,0,0,1);                
            }
        }
    };
    
    TDrawCanvasContext.prototype.Init = function(_object){
        TDrawContext.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            if (typeof _object.ctx !== 'undefined' && _object.ctx !== null)
                this.ctx = _object.ctx;
            if (typeof _object.lineWidth !== 'undefined' && _object.lineWidth !== null)
                this.lineWidth = _object.lineWidth;
            if (typeof _object.startPath !== 'undefined' && _object.startPath !== null)
                this.startPath = _object.startPath;
            if (typeof _object.colourPath !== 'undefined' && _object.colourPath !== null && colourPath.IsType('TColour'))
                this.colourPath = objM.copy(_object.colourPath);
            if (typeof _object.type_ !== 'undefined' && _object.type_ !== null)
            {
                this.type_ = new String(_object.type_);
                if (this.type_ !== null)
                    this.type_ = this.type_.toString();
            }
            if (typeof _object.font !== 'undefined' && _object.font !== null)
            {
                this.font = new String(_object.font);
                if (this.font !== null)
                    this.font = this.font.toString();
            }else
                this.font = null;
            if (typeof _object.fontSize !== 'undefined' && _object.fontSize !== null)
                this.fontSize = _object.fontSize;
            if (typeof _object.alignmentY !== 'undefined' && _object.alignmentY !== null)
            {
                this.alignmentY = new String(_object.alignmentY);
                if (this.alignmentY !== null)
                    this.alignmentY = this.alignmentY.toString();
            }else
                this.alignmentY = null;
            if (typeof _object.alignmentX !== 'undefined' && _object.alignmentX !== null)
            {
                this.alignmentX = new String(_object.alignmentX);
                if (this.alignmentX !== null)
                    this.alignmentX = this.alignmentX.toString();
            }else
                this.alignmentX = null;
        }
    };

    TDrawCanvasContext.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TDrawContext.prototype.IsType.call(this,_type);
    };

    TDrawCanvasContext.prototype.GetContext = function(){
        return this.ctx;
    };
        
    TDrawCanvasContext.prototype.SetContext = function(ctx_){
        if (typeof ctx_ !== 'undefined' && ctx_ !== null)
            this.ctx = ctx_;
    };

    TDrawCanvasContext.prototype.Begin = function(type_){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null)
        {
            this.type_ = new String(type_);
            if (this.type_ !== null)
                this.type_ = this.type_.toString();
            switch(type_)
            {
                case 'rectangle':
                    this.ctx.beginPath();
                    this.startPath = true;
                    this.colourPath = null;
                    break;
                case 'line':
                case 'lineClosed':
                    if (this.GetDashedType() !== null)
                    {
                        var number = this.FindDashed();
                        if (number >= 0)
                        {
                            this.ctx.setLineDash(dashedValue[number]);
                        }else
                            this.ctx.setLineDash([]);                  
                    }else
                        this.ctx.setLineDash([]);                  
                    this.ctx.beginPath();
                    this.startPath = true;
                    this.colourPath = null;
                    this.lineWidth = 1;
                    break;
                case 'circle':
                    this.lineWidth = 1;
//                    this.txt = this.txt + '<circle ';
                    break;
                case 'ellipse':
                    this.lineWidth = 1;
                    break;
            }
        }
    };

    TDrawCanvasContext.prototype.End = function(){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null)
        {
            var tmp;
            switch(this.type_)
            {
                case 'rectangle':
                    this.ctx.closePath();
                    if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
                    {
                        var r = Math.round(this.colourPath.GetColour(0)*255);
                        var g = Math.round(this.colourPath.GetColour(1)*255);
                        var b = Math.round(this.colourPath.GetColour(2)*255);
                        var a = this.colourPath.GetColour(3);
                        this.ctx.fillStyle = "rgba(" + r +  "," + g + ","  + b + "," + a + ")";
                    }else
                    {
                        tmp = this.GetDefaultBackgroundColour();
                        if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                        {
                            var r = Math.round(tmp.GetColour(0)*255);
                            var g = Math.round(tmp.GetColour(1)*255);
                            var b = Math.round(tmp.GetColour(2)*255);
                            var a = tmp.GetColour(3);
                            this.ctx.fillStyle = "rgba(" + r +  "," + g + ","  + b + "," + a + ")";
                        }
                    }
                    this.ctx.fill();
                    break;
                case 'lineClosed':
                    this.ctx.closePath();
                case 'line':
                    if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
                    {
                        var r = Math.round(this.colourPath.GetColour(0)*255);
                        var g = Math.round(this.colourPath.GetColour(1)*255);
                        var b = Math.round(this.colourPath.GetColour(2)*255);
                        var a = this.colourPath.GetColour(3);
                        this.ctx.strokeStyle = "rgba(" + r +  "," + g + ","  + b + "," + a + ")";
                        this.ctx.lineWidth = Math.round(this.lineWidth);
                    }else
                    {
                        tmp = this.GetDefaultColour();
                        if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                        {
                            var r = Math.round(tmp.GetColour(0)*255);
                            var g = Math.round(tmp.GetColour(1)*255);
                            var b = Math.round(tmp.GetColour(2)*255);
                            var a = tmp.GetColour(3);
                            this.ctx.fillStyle = "rgba(" + r +  "," + g + ","  + b + "," + a + ")";
                            if (typeof this.lineWidth !== 'undefined' && this.lineWidth !== null)
                                this.ctx.lineWidth = Math.round(this.lineWidth);
                        }
                    }
                    this.ctx.stroke();
                    break;
                case 'circle':
                    var coord1 = this.transformation.CreateVector();
                    var coord2 = this.transformation.CreateVector();
                    coord2.SetCoordinate(0,this.GetParameter());
                    var result1 = this.transformation.MatrixVectorMultiplication(coord1);
                    var result2 = this.transformation.MatrixVectorMultiplication(coord2);
                    result2.Subtraction(result1);
                    this.ctx.beginPath();
                    this.ctx.arc(this.GetParameter(1),this.GetParameter(2),result2.Norm(),0,2*Math.PI);
                    tmp = this.GetDefaultBackgroundColour();
                    if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                    {
                        var r = Math.round(tmp.GetColour(0)*255);
                        var g = Math.round(tmp.GetColour(1)*255);
                        var b = Math.round(tmp.GetColour(2)*255);
                        var a = tmp.GetColour(3);
                        this.ctx.fillStyle = "rgba(" + r +  "," + g + ","  + b + "," + a + ")";
                        this.ctx.fill();
                    }
                    if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
                    {
                        var r = Math.round(this.colourPath.GetColour(0)*255);
                        var g = Math.round(this.colourPath.GetColour(1)*255);
                        var b = Math.round(this.colourPath.GetColour(2)*255);
                        var a = this.colourPath.GetColour(3);
                        this.ctx.strokeStyle = "rgba(" + r +  "," + g + ","  + b + "," + a + ")";
                        this.ctx.lineWidth = Math.round(this.lineWidth);
                    }else
                    this.ctx.closePath();
                    this.ctx.stroke();
                    break;
                case 'ellipse':
                    var coord1 = this.transformation.CreateVector();
                    var coord2 = this.transformation.CreateVector();
                    coord2.SetCoordinate(0,this.GetParameter(0));
                    var result1 = this.transformation.MatrixVectorMultiplication(coord1);
                    var result2 = this.transformation.MatrixVectorMultiplication(coord2);
                    result2.Subtraction(result1);
                    coord1 = this.transformation.CreateVector();
                    coord2 = this.transformation.CreateVector();
                    coord2.SetCoordinate(1,this.GetParameter(1));
                    result1 = this.transformation.MatrixVectorMultiplication(coord1);
                    var result2_ = this.transformation.MatrixVectorMultiplication(coord2);
                    result2_.Subtraction(result1);
                    this.ctx.beginPath();
                    this.ctx.ellipse(this.GetParameter(2),this.GetParameter(3),result2.Norm(),result2_.Norm(),0,0,2*Math.PI);
                    tmp = this.GetDefaultBackgroundColour();
                    if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                    {
                        var r = Math.round(tmp.GetColour(0)*255);
                        var g = Math.round(tmp.GetColour(1)*255);
                        var b = Math.round(tmp.GetColour(2)*255);
                        var a = tmp.GetColour(3);
                        this.ctx.fillStyle = "rgba(" + r +  "," + g + ","  + b + "," + a + ")";
                        this.ctx.fill();
                    }
                    if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
                    {
                        var r = Math.round(this.colourPath.GetColour(0)*255);
                        var g = Math.round(this.colourPath.GetColour(1)*255);
                        var b = Math.round(this.colourPath.GetColour(2)*255);
                        var a = this.colourPath.GetColour(3);
                        this.ctx.strokeStyle = "rgba(" + r +  "," + g + ","  + b + "," + a + ")";
                        this.ctx.lineWidth = Math.round(this.lineWidth);
                    }else
                    this.ctx.closePath();
                    this.ctx.stroke();
                    break;
            }
            this.startPath = true;
            this.colourPath = null;
            this.lineWidth = 1;
        }
    };
    
    TDrawCanvasContext.prototype.Vertex2D = function(x,y){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector2DT');
                vec.SetCoordinates(x,y);
                this.Vertex(vec);
            }
        }
    };

    TDrawCanvasContext.prototype.Vertex3D = function(x,y,z){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector3DT');
                vec.SetCoordinates(x,y,z);
                this.Vertex(vec);
            }
        }
    };

    TDrawCanvasContext.prototype.Vertex = function(coordinates){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null && typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
        {
            if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
            {
                var n,result = this.transformation.MatrixVectorMultiplication(coordinates);
                if (result !== null)
                {
                    switch(this.type_)
                    {
                        case 'rectangle':
                        case 'line':
                        case 'lineClosed':
                            if (this.startPath)
                            {
                                this.startPath = false;
                                this.ctx.moveTo(result.GetCoordinate(0),result.GetCoordinate(1));
                            }else
                                this.ctx.lineTo(result.GetCoordinate(0),result.GetCoordinate(1));
                            break;
                        case 'circle':
                            this.SetParameter(result.GetCoordinate(0),1);
                            this.SetParameter(result.GetCoordinate(1),2);
                            break;
                        case 'ellipse':
//                            n = this.GetNParameters();
                            this.SetParameter(result.GetCoordinate(0),2);
                            this.SetParameter(result.GetCoordinate(1),3);
                            break;
                    }
                }
            }
        }
    };

    TDrawCanvasContext.prototype.SetColour = function(colour){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null)
        {
            var objM = this.GetObjectManager();
            if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour') && objM !== null)
            {
                this.colourPath = objM.copy(colour);
            }
        }
    };

    TDrawCanvasContext.prototype.SetLineWidth = function(width){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null)
        {
            var objM = this.GetObjectManager();
            if (typeof width !== 'undefined' && width !== null && IsNumeric(width) && objM !== null)
            {
                this.lineWidth = width;
            }
        }
    };

    TDrawCanvasContext.prototype.Text2D = function(x,y,text_,colour_,maxWidth){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector2DT');
                vec.SetCoordinates(x,y);
                this.Text(vec,text_,colour_,maxWidth);
            }
        }
    };

    TDrawCanvasContext.prototype.Text = function(coordinates,text_,colour_,maxWidth){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null && typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
        {
            if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
            {
                var i,tmpFontStyle,fontStyle_,result = this.transformation.MatrixVectorMultiplication(coordinates);
                if (result !== null)
                {
                    if (typeof colour_ !== 'undefined' && colour_ !== null && colour_.IsType('TColour'))
                    {
                        var r = Math.round(colour_.GetColour(0)*255);
                        var g = Math.round(colour_.GetColour(1)*255);
                        var b = Math.round(colour_.GetColour(2)*255);
                        var a = colour_.GetColour(3);
                        this.ctx.fillStyle = "rgba(" + r +  "," + g + ","  + b + "," + a + ")";
                    }else
                    {
                        var tmp = this.GetDefaultTextColour();
                        if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                        {
                            var r = Math.round(tmp.GetColour(0)*255);
                            var g = Math.round(tmp.GetColour(1)*255);
                            var b = Math.round(tmp.GetColour(2)*255);
                            var a = tmp.GetColour(3);
                            this.ctx.fillStyle = "rgba(" + r +  "," + g + ","  + b + "," + a + ")";
                        }                        
                    }
                    
                    var txt1 = null,txt2 = null;
                    if (typeof this.font !== 'undefined' && this.font !== null)
                        txt1 = this.font;
                    if (txt1 === null)
                        txt1 = this.GetDefaultFont();
                    if (typeof this.fontSize !== 'undefined' && this.fontSize !== null && IsNumeric(this.fontSize))
                        txt2 = this.fontSize;
                    if (txt2 === null)
                        txt2 = this.GetDefaultFontSize();
                    
                    tmpFontStyle = '';
                    fontStyle_ = this.GetFontStyle();
                    if (fontStyle_ !== null)
                        for (i = 0;i < fontStyle_.length;i++)
                            tmpFontStyle = tmpFontStyle + ' ' + fontStyle_[i];

                    if (txt1 !== null && txt2 !== null)
                    {
                        var objM = this.GetObjectManager();
                        if (objM !== null && this.transformation !== null)
                        {
                            if (this.GetScaleTextYN())
                            {
                                var coord = null,coord2 = null;
                                switch(this.transformation.GetTypeSpace())
                                {
                                    case '2D':
                                        coord = objM.newObject('TVector2DT');
                                        coord2 = objM.newObject('TVector2DT');
                                        break;
                                    case '3D':
                                        coord = objM.newObject('TVector3DT');
                                        coord2 = objM.newObject('TVector3DT');
                                        break;
                                }
                                if (coord !== null && coord2 !== null)
                                {
    //                                coord.SetZeros(3);
                                    coord.SetCoordinate(0,txt2);
                                    coord = this.transformation.MatrixVectorMultiplication(coord);
                                    coord2 = this.transformation.MatrixVectorMultiplication(coord2);
                                    coord.Subtraction(coord2);
                                    txt2 = coord.Norm();
                                }
                            }
                        }
                        this.ctx.font = tmpFontStyle + ' ' + txt2 + 'px '  + txt1;
                    }

                    switch(this.alignmentX)
                    {
                        case 'left':
                            this.ctx.textAlign='left';
                            break;
                        case 'right':
                            this.ctx.textAlign='right';
                            break;
                        default:
                            this.ctx.textAlign='center';
                    }   
                    
                    switch(this.alignmentY)
                    {
                        case 'top':
                            this.ctx.textBaseline='top';
                            break;
                        case 'bottom':
                            this.ctx.textBaseline='bottom';
                            break;
                        case 'center':
                            this.ctx.textBaseline='middle';
                            break;
                        case 'hanging':
                            this.ctx.textBaseline='hanging';
                            break;
                        case 'alphabetic':
                            this.ctx.textBaseline='alphabetic';
                            break;
                        default:
                            this.ctx.textBaseline='middle';
                    }   

                    if (!this.GetScaleTextYN())
                        this.ctx.font = tmpFontStyle + ' ' + this.GetNumericFontRelativeSize() + "px " + txt1;
                    
                    if (typeof maxWidth !== 'undefined' && maxWidth !== null && IsNumeric(maxWidth))
                    {
                        var objM = this.GetObjectManager();
                        if (objM !== null && this.transformation !== null)
                        {
                            if (this.GetScaleTextYN())
                            {
                                var coord = null,coord2 = null;
                                switch(this.transformation.GetTypeSpace())
                                {
                                    case '2D':
                                        coord = objM.newObject('TVector2DT');
                                        coord2 = objM.newObject('TVector2DT');
                                        break;
                                    case '3D':
                                        coord = objM.newObject('TVector3DT');
                                        coord2 = objM.newObject('TVector3DT');
                                        break;
                                }
                                if (coord !== null && coord2 !== null)
                                {
    //                                coord.SetZeros(3);
                                    coord.SetCoordinate(0,maxWidth);
                                    coord = this.transformation.MatrixVectorMultiplication(coord);
                                    coord2 = this.transformation.MatrixVectorMultiplication(coord2);
                                    coord.Subtraction(coord2);
                                    maxWidth = coord.Norm();
                                }
                            }
                        }
//                        this.ctx.font = 'italic bold 20px Arial';
                        this.ctx.fillText(text_,result.GetCoordinate(0),result.GetCoordinate(1),maxWidth);
                    }else
                        this.ctx.fillText(text_,result.GetCoordinate(0),result.GetCoordinate(1));
                }
            }
        }
    };

    TDrawCanvasContext.prototype.SetFont = function(font_){
        if (typeof font_ !== 'undefined' && font_ !== null)
        {
            this.font = new String(font_);
            if (this.font !== null)
                this.font = this.font.toString();
        }
    };
    
    TDrawCanvasContext.prototype.SetFontSize = function(fontSize_){
        if (typeof fontSize_ !== 'undefined' && fontSize_ !== null && IsNumeric(fontSize_))
            this.fontSize = fontSize_;
    };

    TDrawCanvasContext.prototype.GetTextWidth = function(text,font,size,style){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null && typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
        {
            if (typeof text !== 'undefined' && text !== null)
            {
                var tmp1,tmp2,tmp_style,i;
                if (typeof style === 'undefined' || style === null || style.length === 0)
                    tmp_style = '';
                else
                {
                    tmp_style = '';
                    for (i = 0;i < style.length;i++)
                    {
                        tmp_style = tmp_style + ' ' + style[i];
                    }
                }
                if (typeof font !== 'undefined' && font !== null)
                    tmp1 = font;
                else
                    tmp1 = this.GetDefaultFont();
                if (typeof size !== 'undefined' && size !== null && IsNumeric(size))
                    tmp2 = size;
                else
                    tmp2 = this.GetDefaultFontSize();
                if (tmp1 !== null && tmp2 !== null)
                    this.ctx.font = tmp_style + " " + tmp2 + "px "  + tmp1;                
                var tmp = this.ctx.measureText(text);
                if (typeof tmp !== 'undefined' && tmp !== null)
                    return tmp.width;
            }
        }
        return null;
    };

    TDrawCanvasContext.prototype.GetTextHeight = function(text,font,size){
        var tmp1,tmp2;
        if (typeof font !== 'undefined' && font !== null)
            tmp1 = font;
        else
            tmp1 = this.GetDefaultFont();
        if (typeof size !== 'undefined' && size !== null && IsNumeric(size))
            tmp2 = size;
        else
            tmp2 = this.GetDefaultFontSize();
        if (tmp1 !== null && tmp2 !== null)
        {
            var txt = tmp2 + "px " + tmp1;
            return size;
//            return getTextHeight(txt);
        }
        return null;        
    };

    TDrawCanvasContext.prototype.SetTextBaseLine = function(parameter){
        if (typeof parameter !== 'undefined' && parameter !== null)
        {
            if (typeof this.ctx !== 'undefined' && this.ctx !== null)
            {
                this.alignmentY = new String(parameter);
                if (this.alignmentY !== null)
                    this.alignmentY = this.alignmentY.toString();
            }
            
        }
    };

    TDrawCanvasContext.prototype.SetAlignmentX = function(parameter){
        if (typeof parameter !== 'undefined' && parameter !== null)
        {
            if (typeof this.ctx !== 'undefined' && this.ctx !== null)
            {
                this.alignmentX = new String(parameter);
                if (this.alignmentX !== null)
                    this.alignmentX = this.alignmentX.toString();
            }
            
        }
    };

    TDrawCanvasContext.prototype.DrawImage = function(fileName,coordinates,wh,scale,alignX,alignY,img){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof fileName !== 'undefined' && fileName !== null && typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (typeof wh !== 'undefined' && wh !== null && wh.IsType('TVector'))// && wh.GetCoordinate(0) > 0 && wh.GetCoordinate(1) > 0)
            {
                if (typeof this.ctx !== 'undefined' && this.ctx !== null)
                {
                    if (typeof img === 'undefined' || img === null)
                        return;

                    var result = this.transformation.MatrixVectorMultiplication(coordinates);
                    var result2 = this.transformation.MatrixVectorMultiplication(wh);
                    if (result !== null && result2 !== null)
                    {
                        var x = result.GetCoordinate(0),y = result.GetCoordinate(1);
                        var w = Math.abs(result2.GetCoordinate(0)-x);
                        var h = Math.abs(result2.GetCoordinate(1)-y);
                    
/*                    var result = this.transformation.MatrixVectorMultiplication(coordinates);
                    var result2 = this.transformation.MatrixVectorMultiplication(wh);

                    var w = Math.abs(scale*result2.GetCoordinate(0));
                    var h = Math.abs(scale*result2.GetCoordinate(1));
                    var x = result.GetCoordinate(0),y = result.GetCoordinate(1);*/
                        if (typeof alignX !== 'undefined' && alignX !== null)
                        {
                            if (alignX === 'right')
                                x = x - w;
                            if (alignX === 'center')
                                x = x - w/2;
                        }
                        if (typeof alignY !== 'undefined' && alignY !== null)
                        {
                            if (alignY === 'bottom')
                                y = y - h;
                            if (alignY === 'center')
                                y = y - h/2;
                        }
                        this.ctx.drawImage(img,x ,y , w,h);
                    }
//                    this.ctx.drawImage(img,0 ,0 , 50,50);
                        
//                    var p = GETproperty('#slidecanvasFigure1','font-size')
                }
            }
        }               
    };

}

TDrawCanvasContext.prototype = new TDrawContext();


function TDrawSvgContext(){
    var type = 'TDrawSvgContext';
    TDrawSvgContext.prototype.InitConstructor = function(){
        TDrawContext.prototype.InitConstructor.call(this);
        
        this.txt = '';
        this.type_ = '';
        this.startPath = false;
        this.colourPath = null;
/*        this.lineWidth = 1;
        this.font = null;
        this.fontSize = null;
        this.alignmentX = null;
        this.alignmentY = null;*/
        this.SetType(type);
    };
    this.InitConstructor();

    TDrawSvgContext.prototype.InitConstructor2 = function(){
        TDrawContext.prototype.InitConstructor2.call(this);
        
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            if (this.defaultColour === null)
            {
                this.defaultColour = objM.newObject('TColourRGBA');
                this.defaultColour.SetColourRGBA(0,0,0,1);                
            }
            if (this.defaultBackgroundColour === null)
            {
                this.defaultBackgroundColour = objM.newObject('TColourRGBA');
                this.defaultBackgroundColour.SetColourRGBA(1,1,1,1);                
            }               
            if (this.defaultTextColour === null)
            {
                this.defaultTextColour = objM.newObject('TColourRGBA');
                this.defaultTextColour.SetColourRGBA(0,0,0,1);                
            }
        }
    };
    
    TDrawSvgContext.prototype.Init = function(_object){
        TDrawContext.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            if (typeof _object.txt !== 'undefined' && _object.txt !== null)
                this.txt = _object.txt;
            if (typeof _object.type_ !== 'undefined' && _object.type_ !== null)
            {
                this.type_ = new String(_object.type_);
                if (this.type_ !== null)
                    this.type_ = this.type_.toString();
            }
            if (typeof _object.startPath !== 'undefined' && _object.startPath !== null)
                this.startPath = _object.startPath;
            if (typeof _object.colourPath !== 'undefined' && _object.colourPath !== null && colourPath.IsType('TColour'))
                this.colourPath = objM.copy(_object.colourPath);
/*          if (typeof _object.lineWidth !== 'undefined' && _object.lineWidth !== null)
                this.lineWidth = _object.lineWidth;
            if (typeof _object.font !== 'undefined' && _object.font !== null)
            {
                this.font = new String(_object.font);
                if (this.font !== null)
                    this.font = this.font.toString();
            }else
                this.font = null;
            if (typeof _object.fontSize !== 'undefined' && _object.fontSize !== null)
                this.fontSize = _object.fontSize;
            if (typeof _object.alignmentY !== 'undefined' && _object.alignmentY !== null)
            {
                this.alignmentY = new String(_object.alignmentY);
                if (this.alignmentY !== null)
                    this.alignmentY = this.alignmentY.toString();
            }else
                this.alignmentY = null;
            if (typeof _object.alignmentX !== 'undefined' && _object.alignmentX !== null)
            {
                this.alignmentX = new String(_object.alignmentX);
                if (this.alignmentX !== null)
                    this.alignmentX = this.alignmentX.toString();
            }else
                this.alignmentX = null;*/
        }
    };

    TDrawSvgContext.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TDrawContext.prototype.IsType.call(this,_type);
    };

    TDrawSvgContext.prototype.GetContext = function(){
        return this.txt;
    };
        
    TDrawSvgContext.prototype.SetContext = function(txt_){
        if (typeof txt_ !== 'undefined' && txt_ !== null)
            this.txt = txt_;
    };

    TDrawSvgContext.prototype.Begin = function(type_){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            this.type_ = new String(type_);
            if (this.type_ !== null)
                this.type_ = this.type_.toString();
            switch(type_)
            {
                case 'rectangle':
                    this.txt = this.txt + '<path stroke-linejoin="bevel" d="';
                    this.startPath = true;
                    this.colourPath = null;
                    break;
                case 'line':
                case 'lineClosed':
                case 'polygon':
                    this.txt = this.txt + '<path ';
                    if (this.GetDashedType() !== null)
                    {
                        var number = this.FindDashed();
                        if (number >= 0)
                        {
                            var i,n=dashedValue[number].length;
                            if (n > 0)
                            {
                                this.txt = this.txt + 'stroke-dasharray="';
                                for (i = 0;i < n;i++)
                                {
                                    this.txt = this.txt + dashedValue[number][i] + ' ';
                                }
                                this.txt = this.txt + '" ';
                            }
                        }
                    }
                    this.txt = this.txt + 'stroke-linejoin="bevel" d="';
                    this.startPath = true;
                    this.colourPath = null;
                    this.lineWidth = 1;
                    break;
                case 'circle':
                    this.txt = this.txt + '<circle ';
                    break;
                case 'ellipse':
                    this.txt = this.txt + '<ellipse ';
                    break;
            }
        }
    };

    TDrawSvgContext.prototype.End = function(){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var tmp,colourFill,opacityFill,opacityStroke,colour,_lineWidth;
            colourFill = '#000000';
            opacityFill = '0';
	    opacityStroke = '1';
            switch(this.type_)
            {
                case 'rectangle':
                    if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
                    {
                        var r = Math.round(this.colourPath.GetColour(0)*255);
                        var g = Math.round(this.colourPath.GetColour(1)*255);
                        var b = Math.round(this.colourPath.GetColour(2)*255);
                        var a = this.colourPath.GetColour(3);
                        colourFill = "rgb(" + r +  "," + g + ","  + b + ")";
                        opacityFill = a;
                    }else
                    {
                        tmp = this.GetDefaultBackgroundColour();
                        if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                        {
                            var r = Math.round(tmp.GetColour(0)*255);
                            var g = Math.round(tmp.GetColour(1)*255);
                            var b = Math.round(tmp.GetColour(2)*255);
                            var a = tmp.GetColour(3);
                            colourFill = "rgb(" + r +  "," + g + ","  + b + ")";
                            opacityFill = a;
                        }
                    }
                    break;
                case 'circle':
                case 'ellipse':
                case 'polygon':
                   tmp = this.GetDefaultBackgroundColour();
                    if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                    {
                        var r = Math.round(tmp.GetColour(0)*255);
                        var g = Math.round(tmp.GetColour(1)*255);
                        var b = Math.round(tmp.GetColour(2)*255);
                        var a = tmp.GetColour(3);
                        if (a > 0)
                        {
                            colourFill = "rgb(" + r +  "," + g + ","  + b + ")";
                            opacityFill = a;
                        }else
                            colourFill = null;
                    }
                     if (this.type_ === 'polygon')
                        this.txt = this.txt + 'Z';
                   break;
                case 'lineClosed':
                    if (this.type_ === 'lineClosed')
                        opacityFill = 1;
                    this.txt = this.txt + 'Z';
            }
            switch(this.type_)
            {
                case 'rectangle':
                case 'line':
                case 'polygon':
                case 'lineClosed':
                case 'circle':
                case 'ellipse':
                    if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
                    {
                        var r = Math.round(this.colourPath.GetColour(0)*255);
                        var g = Math.round(this.colourPath.GetColour(1)*255);
                        var b = Math.round(this.colourPath.GetColour(2)*255);
                        var a = this.colourPath.GetColour(3);
                        colour = "rgb(" + r +  "," + g + ","  + b + ")";
			opacityStroke = a;
                        _lineWidth = Math.round(this.lineWidth);
                    }else
                    {
                        tmp = this.GetDefaultColour();
                        if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                        {
                            var r = Math.round(tmp.GetColour(0)*255);
                            var g = Math.round(tmp.GetColour(1)*255);
                            var b = Math.round(tmp.GetColour(2)*255);
                            var a = tmp.GetColour(3);
			    opacityStroke = a;
                            colour = "rgba(" + r +  "," + g + ","  + b +  ")";
                            if (typeof this.lineWidth !== 'undefined' && this.lineWidth !== null)
                                _lineWidth = Math.round(this.lineWidth);
                            else 
                                _lineWidth = 1;
                        }
                    }
                    break;
            }
            switch(this.type_)
            {
                case 'rectangle':
                case 'lineClosed':
                    
/*                    if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
                    {
                        var r = Math.round(this.colourPath.GetColour(0)*255);
                        var g = Math.round(this.colourPath.GetColour(1)*255);
                        var b = Math.round(this.colourPath.GetColour(2)*255);
                        var a = this.colourPath.GetColour(3);
                        colourFill = "rgb(" + r +  "," + g + ","  + b + ")";
                        opacityFill = a;
                    }else
                    {
                        tmp = this.GetDefaultBackgroundColour();
                        if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                        {
                            var r = Math.round(tmp.GetColour(0)*255);
                            var g = Math.round(tmp.GetColour(1)*255);
                            var b = Math.round(tmp.GetColour(2)*255);
                            var a = tmp.GetColour(3);
                            colourFill = "rgb(" + r +  "," + g + ","  + b + ")";
                            opacityFill = a;
                        }
                    }*/
                case 'line':
                    this.txt = this.txt + '" fill="'+ colourFill + '" style="stroke:' + colour + ';stroke-width:' + _lineWidth + ';fill-opacity:'+ opacityFill +'"/>\n';
                    break;
                case 'polygon':
                     this.txt = this.txt + '" fill="'+ colourFill + '" style="stroke:' + colour + ';stroke-width:' + _lineWidth + ';stroke-opacity:' + opacityStroke + ';fill-opacity:'+ opacityFill +'"/>\n';
                    break;
                case 'circle':
                    var coord1 = this.transformation.CreateVector();
                    var coord2 = this.transformation.CreateVector();
                    coord2.SetCoordinate(0,this.GetParameter());
                    var result1 = this.transformation.MatrixVectorMultiplication(coord1);
                    var result2 = this.transformation.MatrixVectorMultiplication(coord2);
                    result2.Subtraction(result1);
                    this.txt = this.txt + ' r="' + result2.Norm() + '" stroke="' + colour + '" stroke-width="' + _lineWidth + '" fill="' + colourFill + '"/>\n';
                    break;
                case 'ellipse':
                    var coord1 = this.transformation.CreateVector();
                    var coord2 = this.transformation.CreateVector();
                    coord2.SetCoordinate(0,this.GetParameter(0));
                    var result1 = this.transformation.MatrixVectorMultiplication(coord1);
                    var result2 = this.transformation.MatrixVectorMultiplication(coord2);
                    result2.Subtraction(result1);
                    coord1 = this.transformation.CreateVector();
                    coord2 = this.transformation.CreateVector();
                    coord2.SetCoordinate(1,this.GetParameter(1));
                    result1 = this.transformation.MatrixVectorMultiplication(coord1);
                    var result2_ = this.transformation.MatrixVectorMultiplication(coord2);
                    result2_.Subtraction(result1);
                    this.txt = this.txt + ' rx="' + result2.Norm() + '" ry="' + result2_.Norm() + '" stroke="' + colour + '" stroke-width="' + _lineWidth + '"';
                    if (colourFill !== null)
                        this.txt = this.txt + ' fill="' + colourFill + '"';
                    else
                        this.txt = this.txt + ' fill="none"';
                    this.txt = this.txt + '/>\n';
                    break;
            }
            this.startPath = true;
            this.colourPath = null;
            this.lineWidth = 1;
        }
    };
    
    TDrawSvgContext.prototype.Vertex2D = function(x,y){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector2DT');
                vec.SetCoordinates(x,y);
                this.Vertex(vec);
            }
        }
    };

    TDrawSvgContext.prototype.Vertex3D = function(x,y,z){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector3DT');
                vec.SetCoordinates(x,y,z);
                this.Vertex(vec);
            }
        }
    };


    TDrawSvgContext.prototype.Vertex = function(coordinates){
        if (typeof this.txt !== 'undefined' && this.txt !== null && typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
        {
            if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
            {
                var result = this.transformation.MatrixVectorMultiplication(coordinates);
                if (result !== null)
                {
                    switch(this.type_)
                    {
                        case 'rectangle':
                        case 'line':
                        case 'polygon':
                        case 'lineClosed':
                            if (this.startPath)
                            {
                                this.startPath = false;
                                this.txt = this.txt + ' M';
                            }else
                                this.txt = this.txt + ' L';
                            this.txt = this.txt + result.GetCoordinate(0) + ',' + result.GetCoordinate(1);
                            break;
                        case 'circle':
                        case 'ellipse':
                            this.txt = this.txt + 'cx="' + result.GetCoordinate(0) + '" cy="' + result.GetCoordinate(1) + '"';
                            break;
                    }
                }
            }
        }
    };

    TDrawSvgContext.prototype.SetColour = function(colour){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var objM = this.GetObjectManager();
            if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour') && objM !== null)
            {
                this.colourPath = objM.copy(colour);
            }
        }
    };

    TDrawSvgContext.prototype.SetLineWidth = function(width){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var objM = this.GetObjectManager();
            if (typeof width !== 'undefined' && width !== null && IsNumeric(width) && objM !== null)
            {
                this.lineWidth = width;
            }
        }
    };

    TDrawSvgContext.prototype.Text2D = function(x,y,text_,colour_,maxWidth){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector2DT');
                vec.SetCoordinates(x,y);
                this.Text(vec,text_,colour_,maxWidth);
            }
        }
    };

    TDrawSvgContext.prototype.Text = function(coordinates,text_,colour_,maxWidth){
        if (typeof this.txt !== 'undefined' && this.txt !== null && typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
        {
            if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
            {
                var tmp,result = this.transformation.MatrixVectorMultiplication(coordinates);
                if (result !== null)
                {
                    var colourFill,opacityFill,_textAlignX,_textAlignY;
                    colourFill = '#000000';
                    opacityFill = '0';
                    _textAlignX='middle';
                    _textAlignY='middle';
                    if (typeof colour_ !== 'undefined' && colour_ !== null && colour_.IsType('TColour'))
                    {
                        var r = Math.round(colour_.GetColour(0)*255);
                        var g = Math.round(colour_.GetColour(1)*255);
                        var b = Math.round(colour_.GetColour(2)*255);
                        var a = colour_.GetColour(3);
                        colourFill = "rgb(" + r +  "," + g + ","  + b + ")";
                        opacityFill = a;
                    }else
                    {
                        var tmp = this.GetDefaultTextColour();
                        if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                        {
                            var r = Math.round(tmp.GetColour(0)*255);
                            var g = Math.round(tmp.GetColour(1)*255);
                            var b = Math.round(tmp.GetColour(2)*255);
                            var a = tmp.GetColour(3);
                            colourFill = "rgb(" + r +  "," + g + ","  + b + ")";
                            opacityFill = a;
                        }                        
                    }
                    
                    var txt1 = null,txt2 = null;
                    if (typeof this.font !== 'undefined' && this.font !== null)
                        txt1 = this.font;
                    if (txt1 === null)
                        txt1 = this.GetDefaultFont();
                    if (typeof this.fontSize !== 'undefined' && this.fontSize !== null && IsNumeric(this.fontSize))
                        txt2 = this.fontSize;
                    if (txt2 === null)
                        txt2 = this.GetDefaultFontSize();
                    
                    if (txt1 !== null && txt2 !== null)
                    {
                        var objM = this.GetObjectManager();
                        if (objM !== null && this.transformation !== null)
                        {
                            if (this.GetScaleTextYN())
                            {
                                var coord = null,coord2 = null;
                                switch(this.transformation.GetTypeSpace())
                                {
                                    case '2D':
                                        coord = objM.newObject('TVector2DT');
                                        coord2 = objM.newObject('TVector2DT');
                                        break;
                                    case '3D':
                                        coord = objM.newObject('TVector3DT');
                                        coord2 = objM.newObject('TVector3DT');
                                        break;
                                }
                                if (coord !== null && coord2 !== null)
                                {
    //                                coord.SetZeros(3);
                                    coord.SetCoordinate(0,txt2);
                                    coord = this.transformation.MatrixVectorMultiplication(coord);
                                    coord2 = this.transformation.MatrixVectorMultiplication(coord2);
                                    coord.Subtraction(coord2);
                                    txt2 = coord.Norm();
                                }
                            }
                        }
//                        this.ctx.font = txt2 + "px " + txt1;
                    }

                    switch(this.alignmentX)
                    {
                        case 'left':
                            _textAlignX='start';
                            break;
                        case 'right':
                            _textAlignX='end';
                            break;
                        default:
                            _textAlignX='middle';
                    }   
                    
                    switch(this.alignmentY)
                    {
                        case 'top':
                            _textAlignY='text-before-edge';
                            break;
                        case 'bottom':
                            _textAlignY='text-after-edge';
                            break;
                        case 'center':
                            _textAlignY='middle';
                            break;
                        case 'hanging':
                            _textAlignY='hanging';
                            break;
                        case 'alphabetic':
                            _textAlignY='alphabetic';
                            break;
                        default:
                            _textAlignY='middle';
                    }   

                    if (_textAlignY==='middle')
                        tmp = result.GetCoordinate(1)+0.25*txt2;
                    else
                        tmp = result.GetCoordinate(1);
                    this.txt = this.txt + '<text x="' + result.GetCoordinate(0) + '" y="' + tmp + '"';
                    this.txt = this.txt + ' style="text-anchor: '+ _textAlignX + ';';
                    if (_textAlignY!=='middle')
                        this.txt = this.txt + 'dominant-baseline:' + _textAlignY + ';';
                    this.txt = this.txt + ' fill:' + colourFill + '; fill-opacity:' + opacityFill;
                    var fontStyle_ = this.GetFontStyle();
                    if (fontStyle_ !== null)
                    {
                        var i;
                        for (i = 0;i < fontStyle_.length;i++)
                        {
                            if (fontStyle_[i] === 'bold')
                                this.txt = this.txt + ';font-weight: bold';
                            if (fontStyle_[i] === 'italic')
                                this.txt = this.txt + ';font-style: italic';
                        }
                    }
                    this.txt = this.txt + '"';
                    
                    if (typeof maxWidth !== 'undefined' && maxWidth !== null && IsNumeric(maxWidth))
                    {
                        var objM = this.GetObjectManager();
                        if (objM !== null && this.transformation !== null)
                        {
                            if (this.GetScaleTextYN())
                            {
                                var coord = null,coord2 = null;
                                switch(this.transformation.GetTypeSpace())
                                {
                                    case '2D':
                                        coord = objM.newObject('TVector2DT');
                                        coord2 = objM.newObject('TVector2DT');
                                        break;
                                    case '3D':
                                        coord = objM.newObject('TVector3DT');
                                        coord2 = objM.newObject('TVector3DT');
                                        break;
                                }
                                if (coord !== null && coord2 !== null)
                                {
                                    coord.SetCoordinate(0,maxWidth);
                                    coord = this.transformation.MatrixVectorMultiplication(coord);
                                    coord2 = this.transformation.MatrixVectorMultiplication(coord2);
                                    coord.Subtraction(coord2);
                                    maxWidth = coord.Norm();
                                }
                            }
                        }
//                        this.txt = this.txt + ' textLength="' + maxWidth +'"';
                    }
                    this.txt = this.txt + ' font-family="' + txt1 + '"';
                    if (this.GetScaleTextYN())
                        this.txt = this.txt + ' font-size="' + txt2 + '">';
                    else
                        this.txt = this.txt + ' font-size="' + this.GetNumericFontRelativeSize() + '">';
                        
                    this.txt = this.txt + text_ + '</text>\n';
                }
            }
        }
    };

    TDrawSvgContext.prototype.SetFont = function(font_){
        if (typeof font_ !== 'undefined' && font_ !== null)
        {
            this.font = new String(font_);
            if (this.font !== null)
                this.font = this.font.toString();
        }
    };
    
    TDrawSvgContext.prototype.SetFontSize = function(fontSize_){
        if (typeof fontSize_ !== 'undefined' && fontSize_ !== null && IsNumeric(fontSize_))
            this.fontSize = fontSize_;
    };

/*    TDrawCanvasContext.prototype.GetTextWidth = function(text,font,size){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null && typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
        {
            if (typeof text !== 'undefined' && text !== null)
            {
                var tmp1,tmp2;
                if (typeof font !== 'undefined' && font !== null)
                    tmp1 = font;
                else
                    tmp1 = this.GetDefaultFont();
                if (typeof size !== 'undefined' && size !== null && IsNumeric(size))
                    tmp2 = size;
                else
                    tmp2 = this.GetDefaultFontSize();
                if (tmp1 !== null && tmp2 !== null)
                    this.ctx.font = tmp2 + "px " + tmp1;                
                var tmp = this.ctx.measureText(text);
                if (typeof tmp !== 'undefined' && tmp !== null)
                    return tmp.width;
            }
        }
        return null;
    };

    TDrawCanvasContext.prototype.GetTextHeight = function(text,font,size){
        var tmp1,tmp2;
        if (typeof font !== 'undefined' && font !== null)
            tmp1 = font;
        else
            tmp1 = this.GetDefaultFont();
        if (typeof size !== 'undefined' && size !== null && IsNumeric(size))
            tmp2 = size;
        else
            tmp2 = this.GetDefaultFontSize();
        if (tmp1 !== null && tmp2 !== null)
        {
            var txt = tmp2 + "px " + tmp1;
            return size;
//            return getTextHeight(txt);
        }
        return null;        
    };*/

    TDrawSvgContext.prototype.SetTextBaseLine = function(parameter){
        if (typeof parameter !== 'undefined' && parameter !== null)
        {
            if (typeof this.txt !== 'undefined' && this.txt !== null)
            {
                this.alignmentY = new String(parameter);
                if (this.alignmentY !== null)
                    this.alignmentY = this.alignmentY.toString();
            }
            
        }
    };

    TDrawSvgContext.prototype.SetAlignmentX = function(parameter){
        if (typeof parameter !== 'undefined' && parameter !== null)
        {
            if (typeof this.txt !== 'undefined' && this.txt !== null)
            {
                this.alignmentX = new String(parameter);
                if (this.alignmentX !== null)
                    this.alignmentX = this.alignmentX.toString();
            }
            
        }
    };


    TDrawSvgContext.prototype.DrawImage = function(fileName,coordinates,wh,scale,alignX,alignY,img){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof fileName !== 'undefined' && fileName !== null && typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (typeof wh !== 'undefined' && wh !== null && wh.IsType('TVector'))// && wh.GetCoordinate(0) > 0 && wh.GetCoordinate(1) > 0)
            {
                if (typeof this.txt !== 'undefined' && this.txt !== null)
                {
                    var result = this.transformation.MatrixVectorMultiplication(coordinates);
                    var result2 = this.transformation.MatrixVectorMultiplication(wh);
                    if (result !== null && result2 !== null)
                    {
                        var x = result.GetCoordinate(0),y = result.GetCoordinate(1);
                        var tmp1 = Math.abs(result2.GetCoordinate(0)-x);
                        var tmp2 = Math.abs(result2.GetCoordinate(1)-y);

                    
/*                    if (typeof scale === 'undefined' || scale === null || !IsNumeric(scale))
                        scale = 1;
                    var result = this.transformation.MatrixVectorMultiplication(coordinates);
                    var result2 = this.transformation.MatrixVectorMultiplication(wh);
                    if (result !== null && result2 !== null)
                    {

                        
                        
                        var tmp1 = Math.abs(scale*result2.GetCoordinate(0));
                        var tmp2 = Math.abs(scale*result2.GetCoordinate(1));
                        var x = result.GetCoordinate(0),y = result.GetCoordinate(1);*/
                        if (typeof alignX !== 'undefined' && alignX !== null)
                        {
                            if (alignX === 'right')
                                x = x - tmp1;
                            if (alignX === 'center')
                                x = x - tmp1/2;
                        }
                        if (typeof alignY !== 'undefined' && alignY !== null)
                        {
                            if (alignY === 'bottom')
                                y = y - tmp2;
                            if (alignY === 'center')
                                y = y - tmp2/2;
                        }
                        this.txt = this.txt + '<foreignObject width="' + tmp1  +'" height="' + tmp2 +'" x="' + x +'" y="' + y + '">';
                        this.txt = this.txt + '<img src="' + fileName + '"  width="' + tmp1  +'" height="' + tmp2 +'">';
                        this.txt = this.txt + '</foreignObject>';
                        
                       
//                        this.txt = this.txt + '<image xlink:href="' + fileName + '" x="' + result.GetCoordinate(0) + '" y="' + result.GetCoordinate(1) +'" ';
//                        this.txt = this.txt + 'height="' + tmp1 + '" width="' + tmp2 + '" />';
                   }
                }
            }
        }               
    };

    TDrawSvgContext.prototype.ForeignObject = function(coordinates,wh,object,alignX,alignY){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (typeof wh !== 'undefined' && wh !== null && wh.IsType('TVector'))
            {
                if (typeof object !== 'undefined' && object !== null)
                {
                    if (typeof this.txt !== 'undefined' && this.txt !== null)
                    {
                        var result = this.transformation.MatrixVectorMultiplication(coordinates);
//                        var result2 = this.transformation.MatrixVectorMultiplication(wh);
                        var result2 = wh;
                        if (result !== null && result2 !== null)
                        {
                            var x = result.GetCoordinate(0),y = result.GetCoordinate(1);
//                            var tmp1 = Math.abs(result2.GetCoordinate(0)-x);
//                            var tmp2 = Math.abs(result2.GetCoordinate(1)-y);
                            var tmp1 = Math.abs(result2.GetCoordinate(0));
                            var tmp2 = Math.abs(result2.GetCoordinate(1));
                            if (typeof alignX !== 'undefined' && alignX !== null)
                            {
                                if (alignX === 'right')
                                    x = x - tmp1;
                                if (alignX === 'center')
                                    x = x - tmp1/2;
                            }
                            if (typeof alignY !== 'undefined' && alignY !== null)
                            {
                                if (alignY === 'bottom')
                                    y = y - tmp2;
                                if (alignY === 'center')
                                    y = y - tmp2/2;
                            }
                            this.txt = this.txt + '<foreignObject width="' + tmp1  +'" height="' + tmp2 +'" x="' + x +'" y="' + y + '">';
                            this.txt = this.txt + object;
                            this.txt = this.txt + '</foreignObject>';


                        }
                    }

                }
            }
        }
    };

}

TDrawSvgContext.prototype = new TDrawContext();

function TThreeScene(){
    var type = 'TThreeScene';
    TThreeScene.prototype.InitConstructor = function(){
        TDrawContext.prototype.InitConstructor.call(this);
        this.type_ = '';
        this.scene = null;
//        this.sceneCSS = null;
        this.geometryObject = null;
        this.imageCatalog = null;
        this.synchronization = null;
        
        this.SetType(type);
    };
    this.InitConstructor();

    TThreeScene.prototype.InitConstructor2 = function(){
        TDrawContext.prototype.InitConstructor2.call(this);
        
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
//            this.imageCatalog = RandomString(15);
        }
    };
    
    TThreeScene.prototype.Init = function(_object){
        TDrawContext.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            if (typeof _object.type_ !== 'undefined' && _object.type_ !== null)
            {
                this.type_ = new String(_object.type_);
                if (this.type_ !== null)
                    this.type_ = this.type_.toString();
            }
            if (typeof _object.scene !== 'undefined' && _object.scene !== null)
                this.scene = _object.scene;
//            if (typeof _object.sceneCSS !== 'undefined' && _object.sceneCSS !== null)
 //               this.sceneCSS = _object.sceneCSS;
            if (typeof _object.geometryObject !== 'undefined' && _object.geometryObject !== null)
                this.geometryObject = _object.geometryObject;
            if (typeof _object.imageCatalog !== 'undefined' && _object.imageCatalog !== null)
            {
                this.imageCatalog = new String(_object.imageCatalog);
                if (this.imageCatalog !== null)
                    this.imageCatalog = this.imageCatalog.toString();
            }
        }
    };

    TThreeScene.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TDrawContext.prototype.IsType.call(this,_type);
    };

    TThreeScene.prototype.Begin = function(type_){
        if (typeof type_ !== 'undefined' && type_ !== null)
        {
            this.type_ = new String(type_);
            if (this.type_ !== null)
                this.type_ = this.type_.toString();
            this.geometryObject = new THREE.Geometry(); 
        }
    };

    TThreeScene.prototype.End = function(){
        if (typeof this.scene !== 'undefined' && this.scene !== null && typeof this.geometryObject !== 'undefined' && this.geometryObject !== null)
        {
            switch(this.type_)
            {
                case 'triangle':
                    this.geometryObject.faces.push(new THREE.Face3(0, 1, 2)); 
//                    this.scene.add(this.geometryObject); 

                 var triangleMaterial = new THREE.MeshBasicMaterial({ 
                     color:0xFFFFFF, 
                     side:THREE.DoubleSide 
                 });                                         

                                        
                 var triangleMesh = new THREE.Mesh(this.geometryObject, triangleMaterial); 
                 triangleMesh.position.set(0,0, 0); 
                 this.scene.add(triangleMesh);         
                    
                    
                    break;
            }
        }
    };
    
    TThreeScene.prototype.Vertex2D = function(x,y){
        if (typeof this.scene !== 'undefined' && this.scene !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector2DT');
                vec.SetCoordinates(x,y);
                this.Vertex(vec);
            }
        }
    };

    TThreeScene.prototype.Vertex3D = function(x,y,z){
        if (typeof this.scene !== 'undefined' && this.scene !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector3DT');
                vec.SetCoordinates(x,y,z);
                this.Vertex(vec);
            }
        }
    };


    TThreeScene.prototype.Vertex = function(coordinates){
        if (typeof this.scene !== 'undefined' && this.scene !== null && typeof this.geometryObject !== 'undefined' && this.geometryObject !== null && typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
        {
            if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
            {
                var result = this.transformation.MatrixVectorMultiplication(coordinates);
                if (result !== null)
                {
                    this.geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 
                }
            }
        }
    };

    TThreeScene.prototype.SetScene = function(scene_){
        if (typeof scene_ !== 'undefined' && scene_ !== null)
        {
            this.scene = scene_;
        }
        if (scene_ === null)
            this.scene = null;
    };

    TThreeScene.prototype.GetScene = function(){
        return this.scene;
    };

    TThreeScene.prototype.GetImageCatalog = function(){
        var tmp = new String(this.imageCatalog);
        if (tmp !== null)
            return tmp.toString();
        return null;
    };

    TThreeScene.prototype.SetImageCatalog = function(catalog){
        if (typeof catalog !== 'undefined' && catalog !== null)
        {
            this.imageCatalog = new String(catalog);
            if (this.imageCatalog !== null)
                this.imageCatalog = this.imageCatalog.toString();
        }
    };
    
    TThreeScene.prototype.ResetSynchronization = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
            this.synchronization = objM.newObject('TSynchronization');
    };
    
    TThreeScene.prototype.IncSynchronization = function(){
        if (typeof this.synchronization !== 'undefined' && this.synchronization !== null && this.synchronization.IsType('TSynchronization'))
            this.synchronization.IncCounter();
    };
    
    TThreeScene.prototype.DecSynchronization = function(){
        if (typeof this.synchronization !== 'undefined' && this.synchronization !== null && this.synchronization.IsType('TSynchronization'))
            return this.synchronization.DecCounter();
        return false;
    };

    TThreeScene.prototype.SetSynchronizationFunction = function(fun){
        if (typeof this.synchronization !== 'undefined' && this.synchronization !== null && this.synchronization.IsType('TSynchronization'))
            this.synchronization.SetFun(fun);
    };

    TThreeScene.prototype.SetSynchronization = function(synchro){
        if (typeof synchro !== 'undefined' && synchro !== null && synchro.IsType('TSynchronization'))
            this.synchronization = synchro;
        if (synchro === null)
            this.synchronization = null;
    };

    TThreeScene.prototype.GetSynchronization = function(){
        return this.synchronization;
    };

/*    TThreeScene.prototype.SetSceneCSS = function(scene_){
        if (typeof scene_ !== 'undefined' && scene_ !== null)
        {
            this.sceneCSS = scene_;
        }
        if (scene_ === null)
            this.sceneCSS = null;
    };*/

/*    TThreeScene.prototype.GetSceneCSS = function(){
        return this.sceneCSS;
    };*/


}

TThreeScene.prototype = new TDrawContext();


function TDrawTikZContext(){
    var type = 'TDrawTikZContext';
    TDrawTikZContext.prototype.InitConstructor = function(){
        TDrawContext.prototype.InitConstructor.call(this);
        
        this.txt = '';
        this.type = '';
        this.startPath = false;
        this.colourPath = null;
        this.txtTmp = '';
        this.txtTmpFirst = '';
/*        this.lineWidth = 1;
        this.font = null;
        this.fontSize = null;
        this.alignmentX = null;
        this.alignmentY = null;*/
        this.SetType(type);
    };
    this.InitConstructor();

    TDrawTikZContext.prototype.InitConstructor2 = function(){
        TDrawContext.prototype.InitConstructor2.call(this);
        
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            if (this.defaultColour === null)
            {
                this.defaultColour = objM.newObject('TColourRGBA');
                this.defaultColour.SetColourRGBA(0,0,0,1);                
            }
            if (this.defaultBackgroundColour === null)
            {
                this.defaultBackgroundColour = objM.newObject('TColourRGBA');
                this.defaultBackgroundColour.SetColourRGBA(1,1,1,1);                
            }               
            if (this.defaultTextColour === null)
            {
                this.defaultTextColour = objM.newObject('TColourRGBA');
                this.defaultTextColour.SetColourRGBA(0,0,0,1);                
            }
        }
    };
    
    TDrawTikZContext.prototype.Init = function(_object){
        TDrawContext.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            if (typeof _object.txt !== 'undefined' && _object.txt !== null)
                this.txt = _object.txt;
            if (typeof _object.txtTmp !== 'undefined' && _object.txtTmp !== null)
                this.txtTmp = _object.txtTmp;
            if (typeof _object.txtTmpFirst !== 'undefined' && _object.txtTmpFirst !== null)
                this.txtTmpFirst = _object.txtTmpFirst;
            if (typeof _object.type_ !== 'undefined' && _object.type_ !== null)
            {
                this.type_ = new String(_object.type_);
                if (this.type_ !== null)
                    this.type_ = this.type_.toString();
            }
            if (typeof _object.startPath !== 'undefined' && _object.startPath !== null)
                this.startPath = _object.startPath;
            if (typeof _object.colourPath !== 'undefined' && _object.colourPath !== null && colourPath.IsType('TColour'))
                this.colourPath = objM.copy(_object.colourPath);
/*          if (typeof _object.lineWidth !== 'undefined' && _object.lineWidth !== null)
                this.lineWidth = _object.lineWidth;
            if (typeof _object.font !== 'undefined' && _object.font !== null)
            {
                this.font = new String(_object.font);
                if (this.font !== null)
                    this.font = this.font.toString();
            }else
                this.font = null;
            if (typeof _object.fontSize !== 'undefined' && _object.fontSize !== null)
                this.fontSize = _object.fontSize;
            if (typeof _object.alignmentY !== 'undefined' && _object.alignmentY !== null)
            {
                this.alignmentY = new String(_object.alignmentY);
                if (this.alignmentY !== null)
                    this.alignmentY = this.alignmentY.toString();
            }else
                this.alignmentY = null;
            if (typeof _object.alignmentX !== 'undefined' && _object.alignmentX !== null)
            {
                this.alignmentX = new String(_object.alignmentX);
                if (this.alignmentX !== null)
                    this.alignmentX = this.alignmentX.toString();
            }else
                this.alignmentX = null;*/
        }
    };

    TDrawTikZContext.prototype.IsType = function(_type){
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TDrawContext.prototype.IsType.call(this,_type);
    };

    TDrawTikZContext.prototype.GetContext = function(){
        return this.txt;
    };
        
    TDrawTikZContext.prototype.SetContext = function(txt_){
        if (typeof txt_ !== 'undefined' && txt_ !== null)
            this.txt = txt_;
    };

    TDrawTikZContext.prototype.Begin = function(type_){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            this.txtTmp = '';
            this.txtTmpFirst = '';
            this.startPath = true;
            this.type_ = new String(type_);
            if (this.type_ !== null)
                this.type_ = this.type_.toString();
            switch(type_)
            {
                case 'rectangle':
/*                    this.txt = this.txt + '\\draw ';
                    this.startPath = true;
                    this.colourPath = null;*/
                    break;
                case 'line':
                case 'lineClosed':

/*                    this.txt = this.txt + '\\draw ';
                    this.startPath = true;
                    this.colourPath = null;
                    this.lineWidth = 1;*/
                    break;
                case 'circle':
//                    this.txt = this.txt + '<circle ';
                    break;
            }
        }
    };

    TDrawTikZContext.prototype.End = function(){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var _lineWidth,colour,tmp;
            
            if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
            {
                var r = this.colourPath.GetColour(0);
                var g = this.colourPath.GetColour(1);
                var b = this.colourPath.GetColour(2);
                var a = this.colourPath.GetColour(3);
                this.txt = this.txt + '\\definecolor{currentcolor}{rgb}{' + r + ',' + g +',' + b + '}\n';
            }else
            {
                tmp = this.GetDefaultColour();
                if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                {
                    var r = tmp.GetColour(0);
                    var g = tmp.GetColour(1);
                    var b = tmp.GetColour(2);
                    var a = tmp.GetColour(3);
                    this.txt = this.txt + '\\definecolor{currentcolor}{rgb}{' + r + ',' + g +',' + b + '}\n';
                }
            }
            
            if (this.type_ === 'rectangle' || this.type_ === 'lineClosed')
            {

                if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
                {
                    var r = this.colourPath.GetColour(0);
                    var g = this.colourPath.GetColour(1);
                    var b = this.colourPath.GetColour(2);
                    var a = this.colourPath.GetColour(3);
                    this.txt = this.txt + '\\definecolor{currentcolorb}{rgb}{' + r + ',' + g +',' + b + '}\n';
                }else
                {
                    tmp = this.GetDefaultBackgroundColour();
                    if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                    {
                        var r = tmp.GetColour(0);
                        var g = tmp.GetColour(1);
                        var b = tmp.GetColour(2);
                        var a = tmp.GetColour(3);
                        this.txt = this.txt + '\\definecolor{currentcolorb}{rgb}{' + r + ',' + g +',' + b + '}\n';
                    }
                }
            }            
           
            if (this.type_ === 'circle' || this.type_ === 'ellipse')
            {

                tmp = this.GetDefaultBackgroundColour();
                if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                {
                    var r = tmp.GetColour(0);
                    var g = tmp.GetColour(1);
                    var b = tmp.GetColour(2);
                    var a = tmp.GetColour(3);
                    this.txt = this.txt + '\\definecolor{currentcolorb}{rgb}{' + r + ',' + g +',' + b + '}\n';
                }
            }            
           
            if (this.type_ === 'rectangle' || this.type_ === 'lineClosed' || this.type_ === 'line')
            {
                this.txt = this.txt + '\\path [draw=currentcolor, ';// ={rgb:red,1;green,2;blue,10}, ';
                if (this.GetDashedType() !== null)
                {
                    var number = this.FindDashed();
                    if (number >= 0)
                    {
                        var i,n=dashedValue[number].length;
                        if (n > 0)
                        {
                            this.txt = this.txt + 'dash pattern=';
                            for (i = 0;i < n;i++)
                            {
                                if (i%2 === 0)
                                    this.txt = this.txt + 'on ';
                                else
                                    this.txt = this.txt + 'off ';
                                this.txt = this.txt + dashedValue[number][i] + 'pt ';
                            }
                            this.txt = this.txt + ', ';
                        }
                    }
                }

                if (this.type_ === 'rectangle' || this.type_ === 'lineClosed')
                    this.txt = this.txt + 'fill=currentcolorb, ';


                if (typeof this.lineWidth !== 'undefined' && this.lineWidth !== null)
                    _lineWidth = Math.round(this.lineWidth);
                else 
                    _lineWidth = 1;

                this.txt = this.txt + 'line width=' + _lineWidth/2 + 'pt ';

                this.txt = this.txt + '] ';
                this.txt = this.txt + this.txtTmpFirst + this.txtTmp;
                switch(this.type_)
                {
                    case 'rectangle':
                        this.txt = this.txt + '--cycle';
                        break;
                    case 'lineClosed':
                        this.txt = this.txt + '--cycle';
                        break;
                    case 'line':
                        break;
                }
                this.txt = this.txt + ';\n';
            }
            if (this.type_ === 'circle')
            {
                var coord1 = this.transformation.CreateVector();
                var coord2 = this.transformation.CreateVector();
                coord2.SetCoordinate(0,this.GetParameter());
                var result1 = this.transformation.MatrixVectorMultiplication(coord1);
                var result2 = this.transformation.MatrixVectorMultiplication(coord2);
                result2.Subtraction(result1);
                this.txt = this.txt + '\\draw [draw=currentcolor, ';
                this.txt = this.txt + 'fill=currentcolorb, ';
                if (typeof this.lineWidth !== 'undefined' && this.lineWidth !== null)
                    _lineWidth = Math.round(this.lineWidth);
                else 
                    _lineWidth = 1;
                this.txt = this.txt + 'line width=' + _lineWidth/2 + 'pt ';
                this.txt = this.txt + '] ';
                this.txt = this.txt + this.txtTmpFirst + ' circle (' + result2.Norm() + 'pt);\n';
                
            }

            if (this.type_ === 'ellipse')
            {
                var coord1 = this.transformation.CreateVector();
                var coord2 = this.transformation.CreateVector();
                coord2.SetCoordinate(0,this.GetParameter(0));
                var result1 = this.transformation.MatrixVectorMultiplication(coord1);
                var result2 = this.transformation.MatrixVectorMultiplication(coord2);
                result2.Subtraction(result1);
                coord1 = this.transformation.CreateVector();
                coord2 = this.transformation.CreateVector();
                coord2.SetCoordinate(1,this.GetParameter(1));
                result1 = this.transformation.MatrixVectorMultiplication(coord1);
                var result2_ = this.transformation.MatrixVectorMultiplication(coord2);
                result2_.Subtraction(result1);
                this.txt = this.txt + '\\draw [draw=currentcolor, ';
                this.txt = this.txt + 'fill=currentcolorb, ';
                if (typeof this.lineWidth !== 'undefined' && this.lineWidth !== null)
                    _lineWidth = Math.round(this.lineWidth);
                else 
                    _lineWidth = 1;
                this.txt = this.txt + 'line width=' + _lineWidth/2 + 'pt ';
                this.txt = this.txt + '] ';
                this.txt = this.txt + this.txtTmpFirst + ' ellipse (' + result2.Norm() + 'pt and ' + result2_.Norm() + 'pt);\n';
                
            }
            
            
/*            var tmp,colourFill,opacityFill,colour,_lineWidth;
            colourFill = '#000000';
            opacityFill = '0';
            switch(this.type_)
            {
                case 'rectangle':
                    
                    if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
                    {
                        var r = Math.round(this.colourPath.GetColour(0)*255);
                        var g = Math.round(this.colourPath.GetColour(1)*255);
                        var b = Math.round(this.colourPath.GetColour(2)*255);
                        var a = this.colourPath.GetColour(3);
                        colourFill = "rgb(" + r +  "," + g + ","  + b + ")";
                        opacityFill = a;
                    }else
                    {
                        tmp = this.GetDefaultBackgroundColour();
                        if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                        {
                            var r = Math.round(tmp.GetColour(0)*255);
                            var g = Math.round(tmp.GetColour(1)*255);
                            var b = Math.round(tmp.GetColour(2)*255);
                            var a = tmp.GetColour(3);
                            colourFill = "rgb(" + r +  "," + g + ","  + b + ")";
                            opacityFill = a;
                        }
                    }
                case 'lineClosed':
                    if (this.type_ === 'lineClosed')
                        opacityFill = 1;
                    this.txt = this.txt + 'Z';
                case 'line':
                    if(typeof this.colourPath !== 'undefined' && this.colourPath !== null && this.colourPath.IsType('TColour'))
                    {
                        var r = Math.round(this.colourPath.GetColour(0)*255);
                        var g = Math.round(this.colourPath.GetColour(1)*255);
                        var b = Math.round(this.colourPath.GetColour(2)*255);
                        var a = this.colourPath.GetColour(3);
                        colour = "rgb(" + r +  "," + g + ","  + b + ")";
                        _lineWidth = Math.round(this.lineWidth);
                    }else
                    {
                        tmp = this.GetDefaultColour();
                        if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                        {
                            var r = Math.round(tmp.GetColour(0)*255);
                            var g = Math.round(tmp.GetColour(1)*255);
                            var b = Math.round(tmp.GetColour(2)*255);
                            var a = tmp.GetColour(3);
                            colour = "rgba(" + r +  "," + g + ","  + b +  ")";
                            if (typeof this.lineWidth !== 'undefined' && this.lineWidth !== null)
                                _lineWidth = Math.round(this.lineWidth);
                            else 
                                _lineWidth = 1;
                        }
                    }
                    this.txt = this.txt + '" fill="'+ colourFill + '" style="stroke:' + colour + ';stroke-width:' + _lineWidth + ';fill-opacity:'+ opacityFill +'"/>\n';
                    break;
            }
            this.startPath = true;
            this.colourPath = null;
            this.lineWidth = 1;*/
        }
    };
    
    TDrawTikZContext.prototype.Vertex2D = function(x,y){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector2DT');
                vec.SetCoordinates(x,y);
                this.Vertex(vec);
            }
        }
    };

    TDrawTikZContext.prototype.Vertex3D = function(x,y,z){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector3DT');
                vec.SetCoordinates(x,y,z);
                this.Vertex(vec);
            }
        }
    };
    
    TDrawTikZContext.prototype.Vertex = function(coordinates){
        if (typeof this.txt !== 'undefined' && this.txt !== null && typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
        {
            if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
            {
                var result = this.transformation.MatrixVectorMultiplication(coordinates);
                if (result !== null)
                {
                    switch(this.type_)
                    {
                        case 'rectangle':
                        case 'line':
                        case 'lineClosed':
                            if (this.startPath)
                            {
                                this.startPath = false;
                                this.txtTmpFirst = '(' + result.GetCoordinate(0) + 'pt,' + result.GetCoordinate(1) +'pt)';
                            }else
                            {
                                this.txtTmp = this.txtTmp + ' -- ';
                                this.txtTmp = this.txtTmp + '(' + result.GetCoordinate(0) + 'pt,' + result.GetCoordinate(1) +'pt)';
                            }
                            break;
                        case 'circle':
                        case 'ellipse':
                            if (this.startPath)
                            {
                                this.startPath = false;
                                this.txtTmpFirst = '(' + result.GetCoordinate(0) + 'pt,' + result.GetCoordinate(1) +'pt)';
                            }
                            break;
                    }
                }
            }
        }
    };

    TDrawTikZContext.prototype.SetColour = function(colour){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var objM = this.GetObjectManager();
            if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour') && objM !== null)
            {
                this.colourPath = objM.copy(colour);
            }
        }
    };

    TDrawTikZContext.prototype.SetLineWidth = function(width){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var objM = this.GetObjectManager();
            if (typeof width !== 'undefined' && width !== null && IsNumeric(width) && objM !== null)
            {
                this.lineWidth = width;
            }
        }
    };

    TDrawTikZContext.prototype.Text2D = function(x,y,text_,colour_,maxWidth){
        if (typeof this.txt !== 'undefined' && this.txt !== null)
        {
            var objM = this.GetObjectManager();
            if ( objM !== null)
            {
                var vec = objM.newObject('TVector2DT');
                vec.SetCoordinates(x,y);
                this.Text(vec,text_,colour_,maxWidth);
            }
        }
    };

    TDrawTikZContext.prototype.Text = function(coordinates,text_,colour_,maxWidth){
        if (typeof this.txt !== 'undefined' && this.txt !== null && typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
        {
            if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
            {
                var tmp,result = this.transformation.MatrixVectorMultiplication(coordinates);
                if (result !== null)
                {
                    
/*                    var colourFill,opacityFill,_textAlignX,_textAlignY;
                    colourFill = '#000000';
                    opacityFill = '0';
                    _textAlignX='middle';
                    _textAlignY='middle';*/
                    if (typeof colour_ !== 'undefined' && colour_ !== null && colour_.IsType('TColour'))
                    {
                        var r = Math.round(colour_.GetColour(0)*255);
                        var g = Math.round(colour_.GetColour(1)*255);
                        var b = Math.round(colour_.GetColour(2)*255);
                        var a = colour_.GetColour(3);
                        this.txt = this.txt + '\\definecolor{currentcolorb}{rgb}{' + r + ',' + g +',' + b + '}\n';
                    }else
                    {
                        var tmp = this.GetDefaultTextColour();
                        if(typeof tmp !== 'undefined' && tmp !== null && tmp.IsType('TColour'))
                        {
                            var r = Math.round(tmp.GetColour(0)*255);
                            var g = Math.round(tmp.GetColour(1)*255);
                            var b = Math.round(tmp.GetColour(2)*255);
                            var a = tmp.GetColour(3);
                            this.txt = this.txt + '\\definecolor{currentcolorb}{rgb}{' + r + ',' + g +',' + b + '}\n';
                        }                        
                    }

                    
                    var sizeFont = '\\' + this.GetFontRelativeSize();
                    
                    
/*                    var txt1 = null,txt2 = null;
                    if (typeof this.font !== 'undefined' && this.font !== null)
                        txt1 = this.font;
                    if (txt1 === null)
                        txt1 = this.GetDefaultFont();
                    if (typeof this.fontSize !== 'undefined' && this.fontSize !== null && IsNumeric(this.fontSize))
                        txt2 = this.fontSize;
                    if (txt2 === null)
                        txt2 = this.GetDefaultFontSize();*/
                    
/*                    if (txt1 !== null && txt2 !== null)
                    {
                        var objM = this.GetObjectManager();
                        if (objM !== null && this.transformation !== null)
                        {
                            var coord = null,coord2 = null;
                            switch(this.transformation.GetTypeSpace())
                            {
                                case '2D':
                                    coord = objM.newObject('TVector2DT');
                                    coord2 = objM.newObject('TVector2DT');
                                    break;
                            }
                            if (coord !== null && coord2 !== null)
                            {
//                                coord.SetZeros(3);
                                coord.SetCoordinate(0,txt2);
                                coord = this.transformation.MatrixVectorMultiplication(coord);
                                coord2 = this.transformation.MatrixVectorMultiplication(coord2);
                                coord.Subtraction(coord2);
                                txt2 = coord.Norm();
                            }
                        }
//                        this.ctx.font = txt2 + "px " + txt1;
                    }*/

                    var anchor1,anchor2;
                    switch(this.alignmentX)
                    {
                        case 'left':
                            anchor1='west';
                            break;
                        case 'right':
                            anchor1='east';
                            break;
                        default:
                            anchor1='';
                    }   
                    
                    switch(this.alignmentY)
                    {
                        case 'top':
                            anchor2='north';
                            break;
                        case 'bottom':
                            anchor2='south';
                            break;
                        case 'center':
                            anchor2='';
                            break;
                        case 'hanging':
                            anchor2='';
                            break;
                        case 'alphabetic':
                            anchor2='';
                            break;
                        default:
                            anchor2='';
                    }
                    
                    if (anchor1 === '' && anchor2 === '')
                        anchor1 = 'base';

/*                    if (_textAlignY==='middle')
                        tmp = result.GetCoordinate(1)+0.25*txt2;
                    else
                        tmp = result.GetCoordinate(1);*/
                    var tmp = result.GetCoordinate(1);
                    if (this.alignmentY === 'center')
                        tmp = tmp - this.GetNumericFontRelativeSize()/3;
                    this.txt = this.txt + '\\node [text=currentcolorb,anchor=' + anchor1 + ' ' + anchor2;
                    this.txt = this.txt + '] at (' + result.GetCoordinate(0) + 'pt,' + tmp + 'pt) {';
                    this.txt = this.txt + sizeFont + ' ';
                    var fontStyle_ = this.GetFontStyle();
                    if (fontStyle_ !== null)
                    {
                        var i;
                        for (i = 0;i < fontStyle_.length;i++)
                        {
                            if (fontStyle_[i] === 'bold')
                                this.txt = this.txt + '\\textbf{';
                            if (fontStyle_[i] === 'italic')
                                this.txt = this.txt + '\\textit{';
                        }
                    }

                    this.txt = this.txt + text_;

                    if (fontStyle_ !== null)
                    {
                        var i;
                        for (i = 0;i < fontStyle_.length;i++)
                        {
                            if (fontStyle_[i] === 'bold')
                                this.txt = this.txt + '}';
                            if (fontStyle_[i] === 'italic')
                                this.txt = this.txt + '}';
                        }
                    }
                    this.txt = this.txt + '};\n';
                    
                    
/*                    this.txt = this.txt + '<text x="' + result.GetCoordinate(0) + '" y="' + tmp + '"';
                    this.txt = this.txt + ' style="text-anchor: '+ _textAlignX + ';';
                    if (_textAlignY!=='middle')
                        this.txt = this.txt + 'dominant-baseline:' + _textAlignY + ';';
                    this.txt = this.txt + ' fill:' + colourFill + '; fill-opacity:' + opacityFill + '"';
                    
                    if (typeof maxWidth !== 'undefined' && maxWidth !== null && IsNumeric(maxWidth))
                    {
                        var objM = this.GetObjectManager();
                        if (objM !== null && this.transformation !== null)
                        {
                            var coord = null,coord2 = null;
                            switch(this.transformation.GetTypeSpace())
                            {
                                case '2D':
                                    coord = objM.newObject('TVector2DT');
                                    coord2 = objM.newObject('TVector2DT');
                                    break;
                            }
                            if (coord !== null && coord2 !== null)
                            {
                                coord.SetCoordinate(0,maxWidth);
                                coord = this.transformation.MatrixVectorMultiplication(coord);
                                coord2 = this.transformation.MatrixVectorMultiplication(coord2);
                                coord.Subtraction(coord2);
                                maxWidth = coord.Norm();
                            }
                        }
//                        this.txt = this.txt + ' textLength="' + maxWidth +'"';
                    }
                    this.txt = this.txt + ' font-family="' + txt1 + '"';
                    this.txt = this.txt + ' font-size="' + txt2 + '">';
                    this.txt = this.txt + text_ + '</text>\n';*/
                }
            }
        }
    };

    TDrawTikZContext.prototype.SetFont = function(font_){
        if (typeof font_ !== 'undefined' && font_ !== null)
        {
            this.font = new String(font_);
            if (this.font !== null)
                this.font = this.font.toString();
        }
    };
    
    TDrawTikZContext.prototype.SetFontSize = function(fontSize_){
        if (typeof fontSize_ !== 'undefined' && fontSize_ !== null && IsNumeric(fontSize_))
            this.fontSize = fontSize_;
    };

/*    TDrawCanvasContext.prototype.GetTextWidth = function(text,font,size){
        if (typeof this.ctx !== 'undefined' && this.ctx !== null && typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
        {
            if (typeof text !== 'undefined' && text !== null)
            {
                var tmp1,tmp2;
                if (typeof font !== 'undefined' && font !== null)
                    tmp1 = font;
                else
                    tmp1 = this.GetDefaultFont();
                if (typeof size !== 'undefined' && size !== null && IsNumeric(size))
                    tmp2 = size;
                else
                    tmp2 = this.GetDefaultFontSize();
                if (tmp1 !== null && tmp2 !== null)
                    this.ctx.font = tmp2 + "px " + tmp1;                
                var tmp = this.ctx.measureText(text);
                if (typeof tmp !== 'undefined' && tmp !== null)
                    return tmp.width;
            }
        }
        return null;
    };

    TDrawCanvasContext.prototype.GetTextHeight = function(text,font,size){
        var tmp1,tmp2;
        if (typeof font !== 'undefined' && font !== null)
            tmp1 = font;
        else
            tmp1 = this.GetDefaultFont();
        if (typeof size !== 'undefined' && size !== null && IsNumeric(size))
            tmp2 = size;
        else
            tmp2 = this.GetDefaultFontSize();
        if (tmp1 !== null && tmp2 !== null)
        {
            var txt = tmp2 + "px " + tmp1;
            return size;
//            return getTextHeight(txt);
        }
        return null;        
    };*/

    TDrawTikZContext.prototype.SetTextBaseLine = function(parameter){
        if (typeof parameter !== 'undefined' && parameter !== null)
        {
            if (typeof this.txt !== 'undefined' && this.txt !== null)
            {
                this.alignmentY = new String(parameter);
                if (this.alignmentY !== null)
                    this.alignmentY = this.alignmentY.toString();
            }
            
        }
    };

    TDrawTikZContext.prototype.SetAlignmentX = function(parameter){
        if (typeof parameter !== 'undefined' && parameter !== null)
        {
            if (typeof this.txt !== 'undefined' && this.txt !== null)
            {
                this.alignmentX = new String(parameter);
                if (this.alignmentX !== null)
                    this.alignmentX = this.alignmentX.toString();
            }
            
        }
    };

    TDrawTikZContext.prototype.DrawImage = function(fileName,coordinates,wh,scale,alignX,alignY,img){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof fileName !== 'undefined' && fileName !== null && typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (typeof wh !== 'undefined' && wh !== null && wh.IsType('TVector'))// && wh.GetCoordinate(0) > 0 && wh.GetCoordinate(1) > 0)
            {
                if (typeof this.txt !== 'undefined' && this.txt !== null)
                {
                    
                    var result = this.transformation.MatrixVectorMultiplication(coordinates);
                    var result2 = this.transformation.MatrixVectorMultiplication(wh);
                    if (result !== null && result2 !== null)
                    {
                        var x = result.GetCoordinate(0),y = result.GetCoordinate(1);
                        var tmp1 = Math.abs(result2.GetCoordinate(0)-x);
                        var tmp2 = Math.abs(result2.GetCoordinate(1)-y);
//                        var x = result.GetCoordinate(0);
//                        var y = result.GetCoordinate(1);
                        if (typeof alignX !== 'undefined' && alignX !== null)
                        {
                            if (alignX === 'right')
                                x = x - tmp1;
                            if (alignX === 'center')
                                x = x - tmp1/2;
                        }
                        if (typeof alignY !== 'undefined' && alignY !== null)
                        {
                            if (alignY === 'bottom')
                                y = y + tmp2;
                            if (alignY === 'center')
                                y = y + tmp2/2;
                        }
//                        tmp1 = tmp1/100;
                        if (typeof scale !== 'undefined' && scale !== null && IsNumeric(scale))
                            tmp1 = tmp1*scale;
                        this.txt = this.txt + '\\node [inner sep=0pt,anchor= north west] at(' + x + 'pt,' + y + 'pt)';
//                        this.txt = this.txt + '{\\includegraphics[width='+ tmp1 + '\\linewidth pt]{' + fileName + '}};\n';
                        this.txt = this.txt + '{\\includegraphics[width=' + tmp1 + 'pt]{' + fileName + '}};\n';
//                        this.txt = this.txt + '\\node [inner sep=0pt,anchor= north west] at(' + result2.GetCoordinate(0) + 'pt,' + result2.GetCoordinate(1) + 'pt)';
//                        this.txt = this.txt + '{\\includegraphics[width=' + tmp2+ 'pt]{' + fileName + '}};\n';
                        
                       
//                        this.txt = this.txt + '<image xlink:href="' + fileName + '" x="' + result.GetCoordinate(0) + '" y="' + result.GetCoordinate(1) +'" ';
//                        this.txt = this.txt + 'height="' + tmp1 + '" width="' + tmp2 + '" />';
                   }
                }
            }
        }               
    };

    TDrawTikZContext.prototype.ForeignObject = function(coordinates,wh,object,alignX,alignY){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (typeof wh !== 'undefined' && wh !== null && wh.IsType('TVector'))
            {
                if (typeof object !== 'undefined' && object !== null)
                {
                    if (typeof this.txt !== 'undefined' && this.txt !== null)
                    {
                        var result = this.transformation.MatrixVectorMultiplication(coordinates);
//                        var result2 = this.transformation.MatrixVectorMultiplication(wh);
                        var result2 = wh;
                        if (result !== null && result2 !== null)
                        {
                            var x = result.GetCoordinate(0),y = result.GetCoordinate(1);
//                            var tmp1 = Math.abs(result2.GetCoordinate(0)-x);
//                            var tmp2 = Math.abs(result2.GetCoordinate(1)-y);
                            var tmp1 = Math.abs(result2.GetCoordinate(0));
                            var tmp2 = Math.abs(result2.GetCoordinate(1));
                            if (typeof alignX !== 'undefined' && alignX !== null)
                            {
                                if (alignX === 'right')
                                    x = x - tmp1;
                                if (alignX === 'center')
                                    x = x - tmp1/2;
                            }
                            if (typeof alignY !== 'undefined' && alignY !== null)
                            {
                                if (alignY === 'bottom')
                                    y = y + tmp2;
                                if (alignY === 'center')
                                    y = y + tmp2/2;
                            }
//                            if (typeof scale !== 'undefined' && scale !== null && IsNumeric(scale))
//                                tmp1 = tmp1*scale;
                            this.txt = this.txt + '\\node [below right] at (' + x  +'pt,' + y +'pt) {';
                            this.txt = this.txt + object;
                            this.txt = this.txt + '};\n';


                        }
                    }

                }
            }
        }
    };

}

TDrawTikZContext.prototype = new TDrawContext();


function TColour(){
    var type = 'TColour';
    TColour.prototype.InitConstructor = function(){
        TVector.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TColour.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVector.prototype.Init.call(this,_object);
//        TObject.Init(_object);
/*        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TVector') && objM !== null)
        {
            if (typeof _object.coordinates !== 'undefined' && _object.coordinates !== null && _object.coordinates.length > 0)
            var i,n = _object.coordinates.length;
            for(i = 0;i < n;i++)
                this.coordinates[i] = _object.coordinates[i];
        }*/
    };


    TColour.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVector.prototype.IsType.call(this,_type);
    };

    TColour.prototype.GetColour = function(position){
        return this.GetCoordinate(position);
    };


    TColour.prototype.SetColour = function(position,coord){
        this.SetCoordinate(position,coord);
    };

    TColour.prototype.MeanColour = function(weight,colour){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof weight !== 'undefined' && weight !== null && typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour'))
        {
            var tmp = objM.copy(this);
            var n = this.GetN();
            if (tmp !== null && n !== null && n > 0)
            {
                var i;
                for (i = 0;i < n;i++)
                {
                    
                    tmp.SetColour(i,weight*this.GetColour(i) + (1-weight)*colour.GetColour(i));
                }
                return tmp;
            }
        }
        return null;
    };

}

TColour.prototype = new TVector();

function TColourRGBA(){
    var type = 'TColourRGBA';
    TColourRGBA.prototype.InitConstructor = function(){
        TColour.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TColourRGBA.prototype.Init = function(_object){
        //TODO: Implement Me 
        TColour.prototype.Init.call(this,_object);
//        TObject.Init(_object);
/*        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TVector') && objM !== null)
        {
            if (typeof _object.coordinates !== 'undefined' && _object.coordinates !== null && _object.coordinates.length > 0)
            var i,n = _object.coordinates.length;
            for(i = 0;i < n;i++)
                this.coordinates[i] = _object.coordinates[i];
        }*/
    };


    TColourRGBA.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TColour.prototype.IsType.call(this,_type);
    };

    TColourRGBA.prototype.GetColourR = function(){
        return this.GetCoordinate(0);
    };

    TColourRGBA.prototype.GetColourG = function(){
        return this.GetCoordinate(1);
    };

    TColourRGBA.prototype.GetColourB = function(){
        return this.GetCoordinate(2);
    };

    TColourRGBA.prototype.GetColourA = function(){
        return this.GetCoordinate(3);
    };

    TColourRGBA.prototype.SetColourR = function(coord){
        this.SetCoordinate(0,coord);
    };

    TColourRGBA.prototype.SetColourG = function(coord){
        this.SetCoordinate(1,coord);
    };

    TColourRGBA.prototype.SetColourB = function(coord){
        this.SetCoordinate(2,coord);
    };

    TColourRGBA.prototype.SetColourA = function(coord){
        this.SetCoordinate(3,coord);
    };
    
    TColourRGBA.prototype.SetColourRGBA = function(r,g,b,a){
        this.SetColourR(r);
        this.SetColourG(g);
        this.SetColourB(b);
        this.SetColourA(a);
    };
    
    TColourRGBA.prototype.Get24bitColour = function(){
        return 256*256*Math.round(255*this.GetColourR()) + 256*Math.round(255*this.GetColourG()) + Math.round(255*this.GetColourB());
    };

    TColourRGBA.prototype.Get24bitColourHex = function(){
        var txt = '',tmp =  Math.round(255*this.GetColourR());
        var hi = Math.floor(tmp/16);
        var lo = tmp - hi*16;
        txt = txt + hi.toString(16).toUpperCase();
        txt = txt + lo.toString(16).toUpperCase();
        tmp =  Math.round(255*this.GetColourG());
        hi = Math.floor(tmp/16);lo = tmp - hi*16;
        txt = txt + hi.toString(16).toUpperCase();
        txt = txt + lo.toString(16).toUpperCase();
        tmp =  Math.round(255*this.GetColourB());
        hi = Math.floor(tmp/16);lo = tmp - hi*16;
        txt = txt + hi.toString(16).toUpperCase();
        txt = txt + lo.toString(16).toUpperCase();
        return txt;
    };

    TColourRGBA.prototype.Get24bitColourWidthAlphaHex = function(){
        var txt = this.Get24bitColourHex();
        tmp =  Math.round(255*this.GetColourA());
        hi = Math.floor(tmp/16);lo = tmp - hi*16;
        txt = txt + hi.toString(16).toUpperCase();
        txt = txt + lo.toString(16).toUpperCase();
        return txt;
    };

}

TColourRGBA.prototype = new TColour();


function TMatrix(){
    var type = 'TMatrix';
    TMatrix.prototype.InitConstructor = function(){
        TObject.prototype.InitConstructor.call(this);
        
        this.data = [];
        this.n = 0; 
        this.m = 0; 
        this.SetType(type);
            
    };
    this.InitConstructor();

    TMatrix.prototype.Init = function(_object){
        //TODO: Implement Me 
        TObject.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TMatrix') && objM !== null)
        {
            if (typeof _object.n !== 'undefined' && _object.n !== null && IsInt(_object.n) && typeof _object.m !== 'undefined' && _object.m !== null && IsInt(_object.m) && typeof _object.data !== 'undefined' && _object.data !== null && _object.data.length > 0)
            var i,n_ = _object.data.length;
            for(i = 0;i < n_;i++)
                this.data[i] = _object.data[i];
            this.n = _object.n;
            this.m = _object.m;
        }
    };


    TMatrix.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TObject.prototype.IsType.call(this,_type);
    };

    TMatrix.prototype.GetM = function(){
        return this.m;
    };

    TMatrix.prototype.GetN = function(){
        return this.n;
    };

    TMatrix.prototype.GetData = function(x){
        if (typeof x !== 'undefined' && x !== null && IsInt(x))
        {
            if (x >= 0 && x < this.data.length)
            {
                return this.data[x];
            }
        }
        return null;
    };

    TMatrix.prototype.SetData = function(x,data_){
        if (typeof x !== 'undefined' && x !== null && IsInt(x))
        {
            if (typeof data_ !== 'undefined' && data_ !== null && IsNumeric(data_))
            {
                if (x >= 0 && x < this.data.length)
                {
                    this.data[x] = data_;
                }
            }
        }
    };

    TMatrix.prototype.SetMatrixTable = function(data,n_,m_){
        this.data = [];
        if (typeof data !== 'undefined' && data !== null)
        {
            if (data.length > 0)
            {
                if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_) && typeof m_ !== 'undefined' && m_ !== null && IsInt(m_))
                {
                    if (n_ >= 0 && m_ >= 0)
                    {
                        var i,nm = n_*m_;
                        if (nm === data.length)
                        {
                            this.n = n_;
                            this.m = m_;
                            for(i = 0;i < nm;i++)
                                this.data[i] = data[i];
                            return;
                        }
                    }
                }
                this.n = 0;
                this.m = 0;
                this.data = [];
            }
        }
    };

    TMatrix.prototype.SetMatrix = function(data){
        this.data = [];
        if (typeof data !== 'undefined' && data !== null)
        {
            if (data.IsType('TMatrix'))
            {
                var n = data.GetN(),m = data.GetM();
                if (typeof n !== 'undefined' && n !== null && IsInt(n) && typeof m !== 'undefined' && m !== null && IsInt(m))
                {    
                    var i,nm = n*m;
                    for(i = 0;i < nm;i++)
                        this.data[i] = data.GetData(i);
                }else
                {
                    n = 0;m = 0;
                    this.data = [];
                }
                this.n = n;
                this.m = m;
            }
        }
    };

    TMatrix.prototype.SetZerosMatrix = function(n_,m_){
        if (typeof n_ === 'undefined' || n_ === null)
            n_ = this.n;
        if (typeof m_ === 'undefined' || m_ === null)
            m_ = this.m;
        if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_) && typeof m_ !== 'undefined' && m_ !== null && IsInt(m_))
        {
            this.data = [];
            var i,nm = n_*m_;
            for(i = 0;i < nm;i++)
                this.data[i] = 0;
            this.n = n_;
            this.m = m_;
        }
    };

    TMatrix.prototype.SetIdentityMatrix = function(n_,m_){
        if (typeof n_ === 'undefined' || n_ === null)
            n_ = this.n;
        if (typeof m_ === 'undefined' || m_ === null)
            m_ = this.m;
        
        if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_) && typeof m_ !== 'undefined' && m_ !== null && IsInt(m_))
        {
            var i,nm;
            this.SetZerosMatrix(n_,m_);
            
            if (n_ < m_)
                nm = n_;
            else
                nm = m_;
            for (i = 0;i < nm;i++)
                this.data[i + i*m_] = 1;
        }
    };

    TMatrix.prototype.MatrixMultiplication = function(multipier){
        if (typeof multipier !== 'undefined' && multipier !== null)
        {
            if (multipier.IsType('TMatrix'))
            {
                var n0 = this.GetN(),n1 = this.GetM();
                var m0 = multipier.GetN(),m1 = multipier.GetM();
                if (n1 === m0)
                {
                    var i,j,k,s,tmp1,tmp2;
                    var result = [];
                    
                    for (i = 0;i < n0;i++)
                    {
                        for (j = 0;j < m1;j++)
                        {
                            s = 0;
                            for (k = 0;k < n1;k++)
                            {
                                tmp1 = this.data[k + i*n1];
                                tmp2 = multipier.GetData(j + k*m1);
                                s = s + tmp1*tmp2;
                            }
                            result[j + i*m1] = s;
                        }
                    }
                    this.n = n0;
                    this.m = m1;
                    
                    this.data = result;
                    
                }
/*                var n0 = this.GetN(),n1 = this.GetM();
                var m0 = multipier.GetN(),m1 = multipier.GetM();
                if (n0 === m1)
                {
                    var i,j,k,s,tmp1,tmp2;
                    var result = [];
                    
                    for (i = 0;i < n1;i++)
                    {
                        for (j = 0;j < m0;j++)
                        {
                            s = 0;
                            for (k = 0;k < n0;k++)
                            {
                                tmp1 = this.data[k + i*n0];
                                tmp2 = multipier.GetData(j + k*m0);
                                s = s + tmp1*tmp2;
                            }
                            result[i + j*m0] = s;
                        }
                    }
                    this.n = n1;
                    this.m = m0;
                    
                    this.data = result;
                    
                }*/
            }   
        }
    };
      
    TMatrix.prototype.MatrixMultiplicationElement = function(multipier){
        var objM = this.GetObjectManager();
        if (objM !== null &&typeof multipier !== 'undefined' && multipier !== null && multipier.IsType('TMatrix'))
        {
            var n_ = multipier.GetN();
            var m_ = multipier.GetM();
            var n__ = this.GetN();
            var m__ = this.GetM();
            if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_) && typeof m_ !== 'undefined' && m_ !== null && IsInt(m_))
            {
                if (n_ === n__ && m_ === m__)
                {
                    var i,nm = n_*m_;
                    for(i = 0;i < nm;i++)
                        this.data[i] = this.data[i]*multipier.data[i];
                }                
            }
        }
    };

    TMatrix.prototype.MatrixMultiplicationScalar = function(scalar){
        var objM = this.GetObjectManager();
        if (objM !== null &&typeof scalar !== 'undefined' && scalar !== null && IsNumeric(scalar))
        {
            var n_ = this.GetN();
            var m_ = this.GetM();
            if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_) && typeof m_ !== 'undefined' && m_ !== null && IsInt(m_))
            {
                var i,nm = n_*m_;
                for(i = 0;i < nm;i++)
                    this.data[i] = this.data[i]*scalar;
            }
        }
    };

    TMatrix.prototype.MatrixDivisionScalar = function(scalar){
        var objM = this.GetObjectManager();
        if (objM !== null &&typeof scalar !== 'undefined' && scalar !== null && IsNumeric(scalar))
        {
            var n_ = this.GetN();
            var m_ = this.GetM();
            if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_) && typeof m_ !== 'undefined' && m_ !== null && IsInt(m_))
            {
                var i,nm = n_*m_;
                for(i = 0;i < nm;i++)
                    this.data[i] = this.data[i]/scalar;
            }
        }
    };

    TMatrix.prototype.MatrixSubtraction = function(subtrahend){
        var objM = this.GetObjectManager();
        if (objM !== null &&typeof subtrahend !== 'undefined' && subtrahend !== null && subtrahend.IsType('TMatrix'))
        {
            var n_ = subtrahend.GetN();
            var m_ = subtrahend.GetM();
            var n__ = this.GetN();
            var m__ = this.GetM();
            if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_) && typeof m_ !== 'undefined' && m_ !== null && IsInt(m_))
            {
                if (n_ === n__ && m_ === m__)
                {
                    var i,nm = n_*m_;
                    for(i = 0;i < nm;i++)
                        this.data[i] = this.data[i] - subtrahend.data[i];
                }                
            }
        }
    };

    TMatrix.prototype.Transposition = function(){
        var objM = this.GetObjectManager();
        var m_ = this.GetM(),n_ = this.GetN();
        var r = objM.newObject(this.GetType());
        var data = [];
        {
            var i,ii,j,jj;
            var n__ = m_;
            var m__ = n_;
            for (i = 0,ii = 0;i < m_;i++,ii++)
            {
                for (j = 0,jj = 0;j < n_;j++,jj++)
                {
                    data[jj + ii*m__] = this.data[i + j*m_];
                }
            }
            this.SetMatrixTable(data,n__,m__);
        }
    };
        
    TMatrix.prototype.CopyMatrix = function(xFrom,xTo,yFrom,yTo){
        var objM = this.GetObjectManager();
        if (objM !== null &&typeof xFrom !== 'undefined' && xFrom !== null && IsInt(xFrom) && typeof yFrom !== 'undefined' && yFrom !== null && IsInt(yFrom))
            if (typeof xTo !== 'undefined' && xTo !== null && IsInt(xTo) && typeof yTo !== 'undefined' && yTo !== null && IsInt(yTo))
            {
                var m_ = this.GetM(),n_ = this.GetN();
                var r = objM.newObject(this.GetType());
                var data = [];
                if (xTo >= xFrom && xFrom >= 0 && xTo < m_ && yTo >= yFrom && yFrom >= 0 && yTo < n_)
                {
                    var i,ii,j,jj;
                    var n__ = xTo - xFrom + 1;
                    var m__ = yTo - yFrom + 1;
                    for (i = yFrom,ii = 0;i <= yTo;i++,ii++)
                    {
                        for (j = xFrom,jj = 0;j <= xTo;j++,jj++)
                        {
                            data[ii + jj*m__] = this.data[i + j*m_];
                        }
                    }
                    r.SetMatrixTable(data,n__,m__);
                    return r;
                }
                
            }
        return null;
    };
        
    TMatrix.prototype.CopyToMatrix = function(matrix,xFrom,xTo,yFrom,yTo){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof matrix !== 'undefined' && matrix !== null && matrix.IsType('TMatrix'))
        {
            if (typeof xFrom !== 'undefined' && xFrom !== null && IsInt(xFrom) && typeof yFrom !== 'undefined' && yFrom !== null && IsInt(yFrom))
                if (typeof xTo !== 'undefined' && xTo !== null && IsInt(xTo) && typeof yTo !== 'undefined' && yTo !== null && IsInt(yTo))
                {
                    var m_ = this.GetM(),n_ = this.GetN();
                    var m__ = matrix.GetM(),n__ = matrix.GetN();
                    var n2 = xTo - xFrom + 1;
                    var m2 = yTo - yFrom + 1;
                    if (xTo >= xFrom && xFrom >= 0 && xTo < m_ && yTo >= yFrom && yFrom >= 0 && yTo < n_)
                    {
                        if (m2 === m__ && n2 === n__)
                        {
                            var i,ii,j,jj;
                            for (i = yFrom,ii = 0;i <= yTo;i++,ii++)
                            {
                                for (j = xFrom,jj = 0;j <= xTo;j++,jj++)
                                {
                                    this.data[i + j*m_] = matrix.data[ii + jj*m__];
                                }
                            }
                        }
                    }

                }
        }
    };
        
    TMatrix.prototype.Sum2 = function(){
        var n_ = this.GetN();
        var m_ = this.GetM();
        if (typeof n_ !== 'undefined' && n_ !== null && IsInt(n_) && typeof m_ !== 'undefined' && m_ !== null && IsInt(m_))
        {
            var i,nm = n_*m_,s = 0;
            for(i = 0;i < nm;i++)
                s = s + this.data[i];
            return s;
        }
        return null;
    };

    TMatrix.prototype.QR = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            var r = objM.copy(this);
            var q = objM.newObject(this.GetType());
            if (q !== null && r !== null)
            {
                var m_ = this.GetM(),n_ = this.GetN();
                var e,u,ut,H,P,nm;
                var result = [];
                var i,p,norm,norm2,sumuu,subtrahend;
                if (n_ < m_)
                    return null;
                q.SetIdentityMatrix(n_,n_);
                for (i = 0;i < m_;i++)
                {
                    p = r.CopyMatrix(i,n_-1,i,i);
                    if (p === null)
                        return null;
                    norm = objM.copy(p);
                    if (norm === null)
                        return null;
                    norm.MatrixMultiplicationElement(norm);
                    norm = Math.sqrt(norm.Sum2());
                    if (norm === null)
                        return null;
                    if (norm !== 0)
                    {
                        p.MatrixDivisionScalar(norm);
                        e = objM.copy(p);
                        if (e !== null)
                        {
                            e.SetZerosMatrix();
                            e.SetData(0,1);
                            u = objM.copy(p);
                            if (u !== null)
                            {
                                u.MatrixSubtraction(e);
                                norm2 = objM.copy(u);
                                if (norm2 === null)
                                    return null;
                                norm2.MatrixMultiplicationElement(u);
                                norm2 = Math.sqrt(norm2.Sum2());
                                if (norm2 === 0)
                                    u = objM.copy(p);
                                ut = objM.copy(u);
                                sumuu = objM.copy(u);
                                subtrahend = objM.copy(u);
                                H = objM.newObject('TMatrix');                                
                                P = objM.newObject('TMatrix');                                
                                if (P !== null && H !== null && sumuu !== null && subtrahend !== null && ut !== null)
                                {
                                    nm = u.GetN()*u.GetM();
                                    H.SetIdentityMatrix(nm,nm);                                    
                                    ut.Transposition();
                                    subtrahend.MatrixMultiplication(ut);
                                    subtrahend.MatrixMultiplicationScalar(2);
                                    sumuu.MatrixMultiplicationElement(sumuu);
                                    sumuu = sumuu.Sum2(sumuu);
                                    subtrahend.MatrixDivisionScalar(sumuu);
                                    H.MatrixSubtraction(subtrahend);
                                    
                                    P.SetIdentityMatrix(n_,m_);
                                    P.CopyToMatrix(H,i,n_-1,i,m_-1);
                                    q.MatrixMultiplication(P);
                                    
                                    P.MatrixMultiplication(r);
                                    r.SetMatrix(P);
                                    
                                    
                                }else
                                    return null;
                                
                            }else
                                return null;
                        }else
                            return null;
                    }
                }
                result[0] = r;
                result[1] = q;
                return result;
            }
        }
        return null;
    };

    TMatrix.prototype.Det = function(){
        var tab = this.QR();
        if (typeof tab !== 'undefined' && tab !== null && tab.length > 0)
        {
            var r = tab[0];
            if (typeof r !== 'undefined' && r !== null && r.IsType('TMatrix'))
            {
                var i,product,n = r.GetN(),m = r.GetM();
                if (m !== null && m === n)
                {
                    product = 1;
                    for (i = 0;i < m;i++)
                    {
                        product = product*r.GetData(i + i*m);
                    }
                    if (m%2===1)
                        product = -1*product;
                    return product;
                }
            }
        }
        return null;
    };

    TMatrix.prototype.SolutionOfEquations = function(b,tabQR){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof b !== 'undefined' && b !== null && b.IsType('TMatrix') && this.data !== null && this.data.length > 0)
        {
            var n = b.GetN();
            if (n !== null && n === this.GetN() && this.GetN() === this.GetM() && b.GetM() === 1)
            {
                var tab;
                if (typeof tabQR === 'undefined' || tabQR === null || tabQR.length <= 0)        
                    tab = this.QR();
                else
                {
                    var tmp = [];
                    tmp[0] = objM.copy(tabQR[0]);
                    tmp[1] = objM.copy(tabQR[1]);
                    tab = tmp;
                }
                if (typeof tab !== 'undefined' && tab !== null && tab.length >= 2)
                {
                    var r = tab[0],q = tab[1];
                    if (typeof r !== 'undefined' && r !== null && r.IsType('TMatrix') && typeof q !== 'undefined' && q !== null && q.IsType('TMatrix'))
                    {
                        var i,product,n = r.GetN(),m = r.GetM();
                        var result = objM.newObject('TMatrix');
                        var s,j;
                        data = [];
                        if (m !== null && m === n)
                        {
                            product = 1;
                            for (i = 0;i < m;i++)
                            {
                                product = product*r.GetData(i + i*m);
                            }
                            if (product === 0)
                            {
                                for(i = 0;i < m;i++)
                                    data[i] = 'NaN';
                                result.SetMatrixTable(data,n,1);
                                return result;
                            }
                            
                            q.Transposition();
                            q.MatrixMultiplication(b);
                            b = objM.copy(q);
                            
                            data[m-1] = b.GetData(m-1)/r.GetData(m*m - 1);
                            for (i = m-2;i >= 0;i--)
                            {
                                s = 0;
                                for (j = i + 1;j < m;j++)
                                {
                                    s = s + r.GetData(j + i*m)*data[j];
                                }
                                data[i] = (b.GetData(i) - s)/r.GetData(i + i*m);
                            }
                            result.SetMatrixTable(data,m,1);
//                            result.MatrixMultiplicationElement(q);
                            return result;
                            
                        }
                        
                        
                    }
                }
            }
        }
        return null;
    };

    TMatrix.prototype.Inv = function(){
        var objM = this.GetObjectManager();
        if (objM !== null && this.data !== null && this.data.length > 0)
        {
            var n = this.GetN(),m = this.GetM();
            if (n !== null && n === m)
            {
                var i,j,b,tmp;
                var data = [];
                var tab = this.QR();
                if (typeof tab !== 'undefined' && tab !== null && tab.length >= 2)
                {
                    for (i = 0;i < n;i++)
                    {
                        b = objM.newObject('TMatrix');
                        if (b !== null)
                        {
                            b.SetZerosMatrix(n,1);
                            b.SetData(i,1);
                            tmp = this.SolutionOfEquations(b,tab);
                            for (j = 0;j < m;j++)
                            {
                                data[i + j*m] = tmp.GetData(j);
                            }
                        }
                    }
                    this.data = data;
                }
            }            
        }
    };
}

TMatrix.prototype = new TObject();

function TMatrixTransformation(){
    var type = 'TMatrixTransformation';
    TMatrixTransformation.prototype.InitConstructor = function(){
        TMatrix.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TMatrixTransformation.prototype.Init = function(_object){
        //TODO: Implement Me 
        TMatrix.prototype.Init.call(this,_object);
//        TObject.Init(_object);
/*        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TMatrixTransformation') && objM !== null)
        {
        }*/
    };


    TMatrixTransformation.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TMatrix.prototype.IsType.call(this,_type);
    };

    TMatrixTransformation.prototype.GetScale = function(coordinate){
        if (typeof coordinate !== 'undefined' && coordinate !== null && IsInt(coordinate) && coordinate >= 0)
        {
            var n = this.GetM();
            var p = coordinate + coordinate*n;
            if (p >= 0 && p < this.data.length)
                return this.data[p];
        }
        return null;
    };

    TMatrixTransformation.prototype.MatrixVectorMultiplication = function(multipier){
        if (typeof multipier !== 'undefined' && multipier !== null)
        {
            var objM = this.GetObjectManager();
            if (multipier.IsType('TVector') && objM !== null)
            {
                var n0 = this.GetN(),n1 = this.GetM();
                var m0 = multipier.GetN(),m1 = 1;
                if (n1 === m0)
                {
                    var i,j,k,s,tmp1,tmp2;
                    var result = [];
                    var result2 = objM.copy(multipier);
                    
                    for (i = 0;i < n0;i++)
                    {
                        for (j = 0;j < m1;j++)
                        {
                            s = 0;
                            for (k = 0;k < n1;k++)
                            {
                                tmp1 = this.data[k + i*n1];
                                tmp2 = multipier.GetData(j + k*m1);
                                s = s + tmp1*tmp2;
                            }
                            result[i + j*n0] = s;
                        }
                    }
                    
                    for (i = 0;i < result.length;i++)
                    {
                        result2.SetCoordinate(i,result[i]);
                    }
                    return result2;
                    
                }
            }   
        }
    };

    TMatrixTransformation.prototype.SetCoordinates = function(coordinates){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            var i,n = this.GetN(),m = this.GetM();
            for (i = 0;i < n - 1;i++)
            {
                this.data[m - 1 + i*m] = coordinates.GetCoordinate(i);
            }
        }
    };

    TMatrixTransformation.prototype.GetCoordinates = function(){
        var result = this.CreateVector();
        if (result !== null)
        {
            var i,n = this.GetN(),m = this.GetM();
            for (i = 0;i < n - 1;i++)
            {
                result.SetCoordinate(i,this.data[m - 1 + i*m]);
            }
            return result;
        }
        return null;
    };

    TMatrixTransformation.prototype.GetTypeSpace = function(){
        //TODO: Implement Me 
        return null;
    };

    TMatrixTransformation.prototype.CreateVector = function(){
        //TODO: Implement Me 
        return null;
    };

}

TMatrixTransformation.prototype = new TMatrix();



function TMatrixTransformation2D(){
    var type = 'TMatrixTransformation2D';
    TMatrixTransformation2D.prototype.InitConstructor = function(){
        TMatrixTransformation.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TMatrixTransformation2D.prototype.Init = function(_object){
        
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TMatrixTransformation2D'))
            TMatrixTransformation.prototype.Init.call(this,_object);
//        TObject.Init(_object);
/*        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TMatrixTransformation') && objM !== null)
        {
        }*/
    };


    TMatrixTransformation2D.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TMatrixTransformation.prototype.IsType.call(this,_type);
    };

    TMatrixTransformation2D.prototype.SetIdentityMatrix = function(){
        TMatrixTransformation.prototype.SetIdentityMatrix.call(this,3,3);
    };

    TMatrixTransformation2D.prototype.SetTranslationMatrix = function(dx, dy){
        
       this.SetIdentityMatrix();
       this.data[2] = dx;
       this.data[5] = dy;
    };

    TMatrixTransformation2D.prototype.SetScaleMatrix = function(scale){
        
       this.SetIdentityMatrix();
       this.data[0] = scale;
       this.data[4] = scale;
    };

    TMatrixTransformation2D.prototype.GetTypeSpace = function(){
        //TODO: Implement Me 
        return '2D';
    };

    TMatrixTransformation2D.prototype.CreateVector = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            return objM.newObject('TVector2DT');
        }
        return null;
    };
}

TMatrixTransformation2D.prototype = new TMatrixTransformation();

function TMatrixTransformation3D(){
    var type = 'TMatrixTransformation3D';
    TMatrixTransformation3D.prototype.InitConstructor = function(){
        TMatrixTransformation.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TMatrixTransformation3D.prototype.Init = function(_object){
        
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TMatrixTransformation3D'))
            TMatrixTransformation.prototype.Init.call(this,_object);
//        TObject.Init(_object);
/*        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TMatrixTransformation') && objM !== null)
        {
        }*/
    };


    TMatrixTransformation3D.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TMatrixTransformation.prototype.IsType.call(this,_type);
    };

    TMatrixTransformation3D.prototype.SetIdentityMatrix = function(){
        TMatrixTransformation.prototype.SetIdentityMatrix.call(this,4,4);
    };

    TMatrixTransformation3D.prototype.SetTranslationMatrix = function(dx, dy, dz){
        
       this.SetIdentityMatrix();
       this.data[3] = dx;
       this.data[7] = dy;
       this.data[11] = dz;
    };

    TMatrixTransformation3D.prototype.SetScaleMatrix = function(scale){
        if (typeof scale !== 'undefined' && scale !== null && IsNumeric(scale))
        {
            this.SetIdentityMatrix();
            this.data[0] = scale;
            this.data[5] = scale;
            this.data[10] = scale;
        }
    };

    TMatrixTransformation3D.prototype.SetScaleMatrix3D = function(scaleX,scaleY,scaleZ){
        if (typeof scaleX !== 'undefined' && scaleX !== null && IsNumeric(scaleX) && typeof scaleY !== 'undefined' && scaleY !== null && IsNumeric(scaleY) && typeof scaleZ !== 'undefined' && scaleZ !== null && IsNumeric(scaleZ))
        {       
            this.SetIdentityMatrix();
            this.data[0] = scaleX;
            this.data[5] = scaleY;
            this.data[10] = scaleZ;
        }
    };

    TMatrixTransformation3D.prototype.SetRotateXMatrix3D = function(angle){
        if (typeof angle !== 'undefined' && angle !== null && IsNumeric(angle))
        {       
            this.SetIdentityMatrix();
            this.data[5] = Math.cos(angle);
            this.data[6] = -Math.sin(angle);
            this.data[9] = Math.sin(angle);
            this.data[10] = Math.cos(angle);
        }
    };

    TMatrixTransformation3D.prototype.SetRotateYMatrix3D = function(angle){
        if (typeof angle !== 'undefined' && angle !== null && IsNumeric(angle))
        {       
            this.SetIdentityMatrix();
            this.data[0] = Math.cos(angle);
            this.data[2] = Math.sin(angle);
            this.data[8] = -Math.sin(angle);
            this.data[10] = Math.cos(angle);
        }
    };
    
    TMatrixTransformation3D.prototype.SetRotateZMatrix3D = function(angle){
        if (typeof angle !== 'undefined' && angle !== null && IsNumeric(angle))
        {       
            this.SetIdentityMatrix();
            this.data[0] = Math.cos(angle);
            this.data[1] = -Math.sin(angle);
            this.data[4] = Math.sin(angle);
            this.data[5] = Math.cos(angle);
        }
    };

    TMatrixTransformation3D.prototype.GetTypeSpace = function(){
        //TODO: Implement Me 
        return '3D';
    };

    TMatrixTransformation3D.prototype.CreateVector = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            return objM.newObject('TVector3DT');
        }
        return null;
    };
}

TMatrixTransformation3D.prototype = new TMatrixTransformation();


function THitObject(){
    var type = 'THitObject';
    THitObject.prototype.InitConstructor = function(){
        TObject.prototype.InitConstructor.call(this);
        
        this.hit = false;
        this.object = null;
        this.objectParent = null;
        this.idObject = [];
        this.SetType(type);
            
    };
    this.InitConstructor();

    THitObject.prototype.Init = function(_object){
        //TODO: Implement Me 
        TObject.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TFigure') && objM !== null)
        {
            if (typeof _object.hit !== 'undefined' && _object.hit !== null)
                this.hit = _object.hit;
            if (typeof _object.object !== 'undefined' && _object.object !== null)
                this.object = _object.object;
            if (typeof _object.objectParent !== 'undefined' && _object.objectParent !== null)
                this.objectParent = _object.objectParent;
            if (typeof _object.idObject !== 'undefined' && _object.idObject !== null && _object.idObject.length > 0)
            {
                var i;
                for (i = 0;i <  _object.idObject.length;i++)
                    this.idObject[i] = _object.idObject[i];
            }
        }
    };

    THitObject.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TObject.prototype.IsType.call(this,_type);
    };

}

THitObject.prototype = new TObject();


function TFigure(){
    var type = 'TFigure';
    TFigure.prototype.InitConstructor = function(){
        TObject.prototype.InitConstructor.call(this);
        
        this.childs = [];
        this.interactive = false;
        this.parent = null;
        this.area = null;
        this.vertices = [];
        this.SetType(type);
//        var objM = this.GetObjectManager();
//        if (objM !== null)
//            this.transformation = objM.newObject('TMatrixTransformation2D');
//        else
        this.transformation = null;
            
    };
    this.InitConstructor();

    TFigure.prototype.Init = function(_object){
        //TODO: Implement Me 
        TObject.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TFigure') && objM !== null)
        {
            if (typeof _object.transformation !== 'undefined' && _object.transformation !== null)
                this.transformation = objM.copy(_object.transformation);
            if (typeof _object.area !== 'undefined' && _object.area !== null)
                this.area = objM.copy(_object.area);
            if (typeof _object.parent !== 'undefined' && _object.parent !== null)
                this.parent = _object.parent;
            if (typeof _object.interactive !== 'undefined' && _object.interactive !== null)
                this.interactive = _object.interactive;
            
            if (typeof _object.vertices !== 'undefined' && _object.vertices !== null && _object.vertices.length > 0)
            {
                var i,n = _object.vertices.length;
                this.vertices = [];
                for (i = 0;i < n;i++)
                {
                    this.vertices[i] = objM.copy(_object.vertices[i]);                    
                }
            } 
            if (typeof _object.childs !== 'undefined' && _object.childs !== null && _object.childs.length > 0)
            {
                var i,n = _object.childs.length;
                this.childs = [];
                for (i = 0;i < n;i++)
                {
                    this.childs[i] = objM.copy(_object.childs[i]);   
                    if (typeof this.childs[i] !== 'undefined' && this.childs[i] !== null && this.childs[i].IsType('TFigure'))
                        this.childs[i].SetParent(this);
                }
            } 
        }
    };

    TFigure.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TObject.prototype.IsType.call(this,_type);
    };

    TFigure.prototype.CreateTransformationMatrix = function(spaceType_){
        var objM = this.GetObjectManager();
        if (typeof spaceType_ !== 'undefined' && spaceType_ !== null && objM !== null)
        {
            var result;
            switch(spaceType_)
            {
                case '2D':
                    result = objM.newObject('TMatrixTransformation2D');
                    result.SetIdentityMatrix();
                    return result;
                case '3D':
                    result = objM.newObject('TMatrixTransformation3D');
                    result.SetIdentityMatrix();
                    return result;
            }
        }
        return null;
    };

    TFigure.prototype.SetArea = function(typeInteractive){
        return null;
    };
        
    TFigure.prototype.GetArea = function(){
        return this.area;
    };

    TFigure.prototype.SetCoordinates = function(coordinates){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            var objM = this.GetObjectManager();
            if (typeof objM !== 'undefined' && objM !== null)
            {
                if (this.transformation === null)
                    this.transformation = this.CreateTransformationMatrix(coordinates.GetTypeSpace());
                if (this.transformation !== null)
                {
                    this.transformation.SetCoordinates(coordinates);
                    if (this.parent !== null)
                        this.parent.MoveChild();
                }
//                if (this.area !== null)
//                {
//                    this.area.SetCoordinates(coordinates);
//                }
            }
        }
    };

    TFigure.prototype.GetCoordinates = function(){
        var objM = this.GetObjectManager();
        if (typeof objM !== 'undefined' && objM !== null)
        {
            if (this.transformation !== null)
            {
                return this.transformation.GetCoordinates();
            }                        
        }
        return null;
    };

    TFigure.prototype.Draw = function(ctx){
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            ctx.PushMatrix();
            if (this.transformation !== null)
            {
                ctx.MultiplicationMatrix(this.transformation);
            }
            if (this.area !== null)
                this.area.SetTransformation(ctx.GetTransformation());
            this.DrawFigure(ctx);
            var i;
            for (i = 0;i < this.childs.length;i++)
                if (typeof this.childs[i] !== 'undefined' && this.childs[i] !== null && this.childs[i].IsType('TFigure'))
                    this.childs[i].Draw(ctx);
            if (this.area !== null)
                this.area.Draw(ctx);
            ctx.PopMatrix();
        }
    };

    TFigure.prototype.DrawFigure = function(ctx){
    };
   
    TFigure.prototype.SetInteractive = function(yn){
        if (typeof yn !== 'undefined' && yn !== null)
        {
            this.interactive = yn;
            if (yn)
            {
                if ( typeof this.area === 'undefined' || this.area === null)
                {
                    this.area = this.SetArea('Move');
                }
            }else
                this.area = null;
        }
    };

    TFigure.prototype.InArea = function(coordinates){
        if (typeof this.area !== 'undefined' && this.area !== null)
        {
            var objM = this.GetObjectManager();
            if (typeof objM !== 'undefined' && objM !== null)
            {
                var result = objM.newObject('THitObject');
                if (result !== null)
                {
                    result.object = this;
                    result.hit = this.area.InArea(coordinates);
                    return result;
                }
            }            
        }
        return null;
    };

    TFigure.prototype.TypeSelection = function(_type){
        if (typeof this.area !== 'undefined' && this.area !== null)
            this.area.TypeSelection(_type);
    };

    TFigure.prototype.GetTypeSelection = function(){
        if (typeof this.area !== 'undefined' && this.area !== null)
            return this.area.GetTypeSelection();
        return null;
    };

    TFigure.prototype.MouseEvent = function(coordinates,type_,servedYN){
        if (typeof this.area !== 'undefined' && this.area !== null)
            return this.area.MouseEvent(coordinates,type_,servedYN);
        return servedYN;
    };
    
    TFigure.prototype.SetParent = function(parent_){
        if (typeof parent_ !== 'undefined' && parent_ !== null && parent_.IsType('TFigure'))
            this.parent = parent_;
        else
            this.parent = null;
    };

    TFigure.prototype.GetParent = function(){
         return this.parent;
    };

    TFigure.prototype.TypeOfInteraction = function(type_){
        if (typeof type_ !== 'undefined' && type_ !== null)
        {
            if (this.interactive)
            {
                switch(type_)
                {
                    case 'Move':
                    case 'MoveAndResize':
                    case 'Connectors':
                        this.area = this.SetArea(type_);
                        break;
                }
            }
        }
    };

    TFigure.prototype.AddChild = function(child,position){
        if (typeof position === 'undefined' || position === null || !IsInt(position))
            position = this.childs.length;
        if (position >= 0)
        {
            var objM = this.GetObjectManager();
            if (typeof child !== 'undefined' && child !== null && child.IsType('TFigure') && objM !== null)
                this.childs[position] = child;
            if (child === null)
                this.childs[position] = null;
        }
    };

    TFigure.prototype.GetChild = function(position){
        if (typeof position !== 'undefined' && position !== null && IsInt(position) && position >= 0 && position < this.childs.length)
            return this.childs[position];
        return null;
    };

    TFigure.prototype.GetNumberOfChilds = function(){
        return this.childs.length;
    };
    
    TFigure.prototype.SetSelection = function(selectYN){
        if (this.area !== null)
            this.area.SetSelection(selectYN);
        var i;
        for (i = 0;i < this.childs.length;i++)
        {
            if (typeof this.childs[i] !== 'undefined' && this.childs[i] !== null && this.childs[i].IsType('TFigure'))
            {
                this.childs[i].SetSelection(selectYN);
            }
        }
    };
    
    TFigure.prototype.SetVerticle = function(position,coordinates){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (typeof position !== 'undefined' && position !== null && IsInt(position) && position >= 0)
            {
                var objM = this.GetObjectManager();
                if (this.vertices !== null && objM !== null)
                {
                    this.vertices[position] = objM.copy(coordinates);
                }
            }
            
        }
        
    };
   
    TFigure.prototype.GetVerticle = function(position){
        var objM = this.GetObjectManager();
        if (typeof position !== 'undefined' && position !== null && IsInt(position) && position >= 0 && objM !== null)
        {
            return objM.copy(this.vertices[position]);
        }
        return null;
        
    };    
    
    TFigure.prototype.GetNumberOfVerticles = function(){
        if (typeof this.vertices !== 'undefined' && this.vertices !== null)
        {
            return this.vertices.length;
        }
        return 0;
        
    };

    TFigure.prototype.MoveChild = function(){
    };
    
    TFigure.prototype.SetTransformation = function(matrix){
        var objM = this.GetObjectManager();
        if (typeof matrix !== 'undefined' && matrix !== null && matrix.IsType('TMatrixTransformation') && objM !== null)
        {
//            this.transformation = objM.copy(matrix);
            this.transformation = objM.copy(matrix);
        }
    };
    
    TFigure.prototype.GetTransformation = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
            return  objM.copy(this.transformation);
        return null;
    };
    
}

TFigure.prototype = new TObject();

function TVisibleFigure(){
    var type = 'TVisibleFigure';
    TVisibleFigure.prototype.InitConstructor = function(){
        TFigure.prototype.InitConstructor.call(this);
        
        this.visible = true;
        this.colourLine = null;
        this.colourBackground = null;
        this.lineWidth = 1;
        this.lineType='solid';
        this.backgroundType='fill';
        this.SetType(type);
            
    };
    this.InitConstructor();

    TVisibleFigure.prototype.Init = function(_object){
        //TODO: Implement Me 
        TFigure.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TVisibleFigure') && objM !== null)
        {
            if (typeof _object.colourLine !== 'undefined' && _object.colourLine !== null)
                this.colourLine = objM.copy(_object.colourLine);
            if (typeof _object.colourBackground !== 'undefined' && _object.colourBackground !== null)
                this.colourBackground = objM.copy(_object.colourBackground);
            if (typeof _object.visible !== 'undefined' && _object.visible !== null)
                this.visible = _object.visible;
            if (typeof _object.lineWidth !== 'undefined' && _object.lineWidth !== null)
                this.lineWidth = _object.lineWidth;
            if (typeof _object.lineType !== 'undefined' && _object.lineType !== null)
            {
                this.lineType = new String(_object.lineType);
                if (typeof this.lineType !== 'undefined' && this.lineType !== null)
                    this.lineType = this.lineType.toString();

            }
            if (typeof _object.backgroundType !== 'undefined' && _object.backgroundType !== null)
            {
                this.backgroundType = new String(_object.backgroundType);
                if (typeof this.backgroundType !== 'undefined' && this.backgroundType !== null)
                    this.backgroundType = this.backgroundType.toString();

            }
        }
    };


    TVisibleFigure.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TFigure.prototype.IsType.call(this,_type);
    };

    TVisibleFigure.prototype.SetVisible = function(v){
        if (typeof v !== 'undefined' && v !== null)
        {
            this.visible = v;
        }
    };

    TVisibleFigure.prototype.DrawFigure = function(ctx){
        //TODO: Implement Me 
    };
    
    TVisibleFigure.prototype.SetBackgroundColour = function(colour){
        var objM = this.GetObjectManager();
        if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour') && objM !== null)
        {
            this.colourBackground = objM.copy(colour);
        }else
            this.colourBackground = null;
    };
    
    TVisibleFigure.prototype.GetBackgroundColour = function(){
        var objM = this.GetObjectManager();
        if (objM !== null && this.colourBackground !== null)
            return objM.copy(this.colourBackground);
        else
            return null;
    };
    
    TVisibleFigure.prototype.SetLineColour = function(colour){
        var objM = this.GetObjectManager();
        if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour') && objM !== null)
        {
            this.colourLine = objM.copy(colour);
        }else
            this.colourLine = null;
    };
    
    TVisibleFigure.prototype.GetLineColour = function(){
        var objM = this.GetObjectManager();
        if (objM !== null && this.colourLine !== null)
            return objM.copy(this.colourLine);
        else
            return null;
    };

    TVisibleFigure.prototype.SetLineWidth = function(width){
        if (typeof width !== 'undefined' && width !== null && IsNumeric(width))
        {
            this.lineWidth = width;
        }else
            this.lineWidth = 1;
    };
    
    TVisibleFigure.prototype.GetLineWidth = function(){
        return this.lineWidth;
    };

    TVisibleFigure.prototype.SetLineType = function(type){
        if (typeof type !== 'undefined' && type !== null)
        {
            this.lineType = new String(type);
            if (typeof this.lineType !== 'undefined' && this.lineType !== null)
                this.lineType = this.lineType.toString();
            
        }
    };

    TVisibleFigure.prototype.GetLineType = function(){
        var tmp = new String(this.lineType);
        if (typeof tmp !== 'undefined' && tmp !== null)
        {
            return tmp.toString();
        }
        return null;
    };

    TVisibleFigure.prototype.SetBackgroundType = function(type){
        if (typeof type !== 'undefined' && type !== null)
        {
            this.backgroundType = new String(type);
            if (typeof this.backgroundType !== 'undefined' && this.backgroundType !== null)
                this.backgroundType = this.backgroundType.toString();
            
        }
    };

    TVisibleFigure.prototype.GetBackgroundType = function(){
        var tmp = new String(this.backgroundType);
        if (typeof tmp !== 'undefined' && tmp !== null)
        {
            return tmp.toString();
        }
        return null;
    };

    TVisibleFigure.prototype.SetColour = function(colour){
        this.SetBackgroundColour(colour);
    };


    TVisibleFigure.prototype.GetColour = function(){
        return this.GetBackgroundColour();
    };
    
}

TVisibleFigure.prototype = new TFigure();

function TArrow(){
    var type = 'TArrow';
    TArrow.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.width = 15;
        this.height = 10;
        this.beginYN = null;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TArrow.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TArrow') && objM !== null)
        {
            if (typeof _object.width !== 'undefined' && _object.width !== null && IsNumeric(_object.width))
                this.width = _object.width;            
            if (typeof _object.height !== 'undefined' && _object.height !== null && IsNumeric(_object.height))
                this.height = _object.height;            
            if (typeof _object.beginYN !== 'undefined' && _object.beginYN !== null)
                this.beginYN = _object.beginYN;            
        }
    };


    TArrow.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TArrow.prototype.SetWidth = function(w){
        //TODO: Implement Me 
        if (typeof w !== 'undefined' && w !== null && IsNumeric(w))
            this.width = w;
    };

    TArrow.prototype.GetWidth = function(){
        return this.width;
    };

    TArrow.prototype.SetHeight = function(h){
        //TODO: Implement Me 
        if (typeof h !== 'undefined' && h !== null && IsNumeric(h))
            this.height = h;
    };

    TArrow.prototype.GetHeight = function(){
        return this.height;
    };

    TArrow.prototype.CalculateVerices = function(shift){
        //TODO: Implement Me 
    };

    TArrow.prototype.SetBegin = function(beginYN_){
        //TODO: Implement Me 
        if (typeof beginYN_ !== 'undefined' && beginYN_ !== null)
            this.beginYN = beginYN_;
    };

    TArrow.prototype.DrawFigure = function(ctx){
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            var matrix = ctx.GetTransformation();
            if (typeof matrix !== 'undefined' && matrix !== null && matrix.IsType('TMatrixTransformation'))
            {
                if (matrix.IsType('TMatrixTransformation2D'))
                {
                    if (matrix.GetData(0) < 0)
                        matrix.SetData(0,-1);
                    else
                        matrix.SetData(0,1);
                    if (matrix.GetData(4) < 0)
                        matrix.SetData(4,-1);
                    else
                        matrix.SetData(4,1);
                }
                if (matrix.IsType('TMatrixTransformation3D'))
                {
                    if (matrix.GetData(0) < 0)
                        matrix.SetData(0,-1);
                    else
                        matrix.SetData(0,1);
                    if (matrix.GetData(5) < 0)
                        matrix.SetData(5,-1);
                    else
                        matrix.SetData(5,1);
                    if (matrix.GetData(10) < 0)
                        matrix.SetData(10,-1);
                    else
                        matrix.SetData(10,1);
                }
                ctx.SetTransformation(matrix);
            }
        }
    };
    
}

TArrow.prototype = new TVisibleFigure();

function TArrowTriangle(){
    var type = 'TArrowTriangle';
    TArrowTriangle.prototype.InitConstructor = function(){
        TArrow.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TArrowTriangle.prototype.Init = function(_object){
        //TODO: Implement Me 
        TArrow.prototype.Init.call(this,_object);
//        TObject.Init(_object);
/*        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TArrowTriangle') && objM !== null)
        {
        }*/
    };


    TArrowTriangle.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TArrow.prototype.IsType.call(this,_type);
    };

    TArrowTriangle.prototype.CalculateVertices = function(shift){
        var line = this.GetParent();
        if (typeof line !== 'undefined' && line !== null && line.IsType('TLine'))
        {
            if (typeof shift === 'undefined' || shift === null)
                shift = 1;
            var n = line.GetNumberOfVerticles();
            var objM = this.GetObjectManager();
            if (objM !== null && n !== null && this.GetWidth() !== null && this.height !== null && this.beginYN !== null && n >= 2)
            {
                var P0,Pn;
 
                if (this.beginYN)
                {
                    P0 = line.GetVerticle(0);
                    Pn = line.GetVerticle(1);
                }else
                {
                    Pn = line.GetVerticle(n-2);
                    P0 = line.GetVerticle(n-1);
                    
                }

                var matrix,tmpX,tmpY,tmpZ;
//                var matrix2 = this.GetTransformation();
                tmpX = P0.GetX();
                tmpY = P0.GetY();
                if (P0.IsType('TVector2DT'))// && matrix2 !== null && matrix2.IsType('TMatrixTransformation2D'))
                {
                    matrix = objM.newObject('TMatrixTransformation2D');
                    matrix.SetTranslationMatrix(tmpX,tmpY);
                }else
                {
                    if (P0.IsType('TVector3DT'))// && matrix2 !== null && matrix2.IsType('TMatrixTransformation3D'))
                    {
                        tmpZ = P0.GetZ();
                        matrix = objM.newObject('TMatrixTransformation3D');
                        matrix.SetTranslationMatrix(tmpX,tmpY,tmpZ);
                    }else
                        matrix.SetIdentityMatrix();
                }
                    
                Pn.Subtraction(P0);
                P0.SetZeros(P0.GetN());
                    
                this.SetTransformation(matrix);
              
                if (P0 !== null && Pn !== null)
                {
                    var Psub = objM.copy(Pn),deltaP0;
                    Psub.Subtraction(P0);
                    deltaP0 = objM.copy(Psub);
                    var norm = Psub.Norm();
                    if (norm !== 0)
                    {
                        Psub.MultiplicationScalar(this.GetWidth()/norm);
                        deltaP0.MultiplicationScalar(-2*shift/norm);//
                        var x0 = Psub.GetCoordinate(0);
                        var y0 = Psub.GetCoordinate(1);
                        if (x0 !== 0 || y0 !== 0)
                        {
                            var Psub_ = objM.newObject(Psub.GetType());
                            if (x0 > 0 && y0 > 0)
                            {
                                Psub_.SetCoordinate(0,x0);
                                Psub_.SetCoordinate(1,-y0);
                            }
                            if (x0 === 0 && y0 > 0)
                            {
                                Psub_.SetCoordinate(0,y0);
                                Psub_.SetCoordinate(1,0);
                            }
                            if (x0 > 0 && y0 < 0)
                            {
                                Psub_.SetCoordinate(0,-x0);
                                Psub_.SetCoordinate(1,y0);
                            }
                            if (x0 > 0 && y0 === 0)
                            {
                                Psub_.SetCoordinate(0,0);
                                Psub_.SetCoordinate(1,-x0);
                            }
                            if (x0 < 0 && y0 < 0)
                            {
                                Psub_.SetCoordinate(0,x0);
                                Psub_.SetCoordinate(1,-y0);
                            }
                            if (x0 === 0 && y0 < 0)
                            {
                                Psub_.SetCoordinate(0,y0);
                                Psub_.SetCoordinate(1,0);
                            }
                            if (x0 < 0 && y0 > 0)
                            {
                                Psub_.SetCoordinate(0,-x0);
                                Psub_.SetCoordinate(1,y0);
                            }
                            if (x0 < 0 && y0 === 0)
                            {
                                Psub_.SetCoordinate(0,0);
                                Psub_.SetCoordinate(1,-x0);
                            }
                            var Psub2;
                            if (Psub_.ScalarProduct(Psub) === 0)
                            {
                                Psub2 = objM.copy(Psub_);
                            }else
                            {
                                var c = Psub.VectorComponent(Psub_);
                                var tmp = objM.copy(Psub);
                                tmp.MultiplicationScalar(c);
                                Psub2 = objM.copy(Psub_);
                                Psub2.Subtraction(tmp);
                            }
                            norm = Psub2.Norm();
                            Psub2.MultiplicationScalar((this.height + shift)/(2*norm));//
//                            Psub2.MultiplicationScalar((this.height)/(2*norm));
                            var P1 = objM.copy(P0);
                            P1.Addition(Psub);
                            P1.Addition(Psub2);
                            var P2 = objM.copy(P0);
                            P2.Addition(Psub);
                            Psub2.MultiplicationScalar(-1);
                            P2.Addition(Psub2);
                            P0.Addition(deltaP0);//
                            this.SetVerticle(0,P0);
                            this.SetVerticle(1,P1);
                            this.SetVerticle(2,P2);
                       }
                    }
                }
            }
        }
    };

    TArrowTriangle.prototype.DrawFigure = function(ctx){
        TArrow.prototype.DrawFigure.call(this,ctx);
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            if (this.GetLineColour() !== null)
            {
                var i,n = this.GetNumberOfVerticles(),coord,x,y,z;
                ctx.Begin('lineClosed');
                    ctx.SetColour(this.GetLineColour());
                    ctx.SetLineWidth(this.GetLineWidth());
                    for (i = 0;i < n;i++)
                    {
                        coord = this.GetVerticle(i);
                        if (typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector'))
                        {
                            if (coord.IsType('TVector2DT'))
                            {
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y))
                                    ctx.Vertex2D(x,y);
                            }
                            if (coord.IsType('TVector3DT'))
                            {
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                z = coord.GetCoordinate(2);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y) && z !== null && IsNumeric(z))
                                    ctx.Vertex3D(x,y,z);
                            }
                        }
                    }
                ctx.End();
            }
            if (this.GetBackgroundColour() !== null)
            {
                var i,n = this.GetNumberOfVerticles(),coord,x,y;
                ctx.Begin('rectangle');
                    ctx.SetColour(this.GetBackgroundColour());
                    for (i = 0;i < n;i++)
                    {
                        coord = this.GetVerticle(i);
                        if (typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector'))
                        {
                            if (coord.IsType('TVector2DT'))
                            {
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y))
                                    ctx.Vertex2D(x,y);
                            }
                            if (coord.IsType('TVector3DT'))
                            {
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                z = coord.GetCoordinate(2);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y) && z !== null && IsNumeric(z))
                                    ctx.Vertex3D(x,y,z);                                
                            }
                        }
                    }
                ctx.End();
            }
        }
    };

}

TArrowTriangle.prototype = new TArrow();


function TThreeArrowTriangle(){
    var type = 'TThreeArrowTriangle';
    TThreeArrowTriangle.prototype.InitConstructor = function(){
        TArrow.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TThreeArrowTriangle.prototype.Init = function(_object){
        //TODO: Implement Me 
        TArrow.prototype.Init.call(this,_object);
//        TObject.Init(_object);
/*        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TArrowTriangle') && objM !== null)
        {
        }*/
    };


    TThreeArrowTriangle.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TArrow.prototype.IsType.call(this,_type);
    };

    TThreeArrowTriangle.prototype.CalculateVertices = function(shift){
        var line = this.GetParent();
        if (typeof line !== 'undefined' && line !== null && line.IsType('TThreeLine'))
        {
            shift=0;
            if (typeof shift === 'undefined' || shift === null)
                shift = 1;
            var n = line.GetNumberOfVerticles();
            var objM = this.GetObjectManager();
            if (objM !== null && n !== null && this.GetWidth() !== null && this.height !== null && this.beginYN !== null && n >= 2)
            {
                var P0,Pn;
 
                if (this.beginYN)
                {
                    P0 = line.GetVerticle(0);
                    Pn = line.GetVerticle(1);
                }else
                {
                    Pn = line.GetVerticle(n-2);
                    P0 = line.GetVerticle(n-1);
                    
                }

                var matrix,tmpX,tmpY,tmpZ;
//                var matrix2 = this.GetTransformation();
                tmpX = P0.GetX();
                tmpY = P0.GetY();
                if (P0.IsType('TVector2DT'))// && matrix2 !== null && matrix2.IsType('TMatrixTransformation2D'))
                {
                    matrix = objM.newObject('TMatrixTransformation2D');
                    matrix.SetTranslationMatrix(tmpX,tmpY);
                }else
                {
                    if (P0.IsType('TVector3DT'))// && matrix2 !== null && matrix2.IsType('TMatrixTransformation3D'))
                    {
                        tmpZ = P0.GetZ();
                        matrix = objM.newObject('TMatrixTransformation3D');
                        matrix.SetTranslationMatrix(tmpX,tmpY,tmpZ);
                    }else
                        matrix.SetIdentityMatrix();
                }
                    
                Pn.Subtraction(P0);
                P0.SetZeros(P0.GetN());
                    
                this.SetTransformation(matrix);
              
                if (P0 !== null && Pn !== null)
                {
                    var YN = false;
                    if (Pn.GetCoordinate(0) === 0 && Pn.GetCoordinate(1) === 0 && Pn.GetCoordinate(2) !== 0)
                    {
                        var x = Pn.GetCoordinate(0),z = Pn.GetCoordinate(2);
                        Pn.SetCoordinate(0,z);
                        Pn.SetCoordinate(2,x);
                        x = P0.GetCoordinate(0);
                        z = P0.GetCoordinate(2);
                        P0.SetCoordinate(0,z);
                        P0.SetCoordinate(2,x);
                        YN = true;
                    }
                    var Psub = objM.copy(Pn),deltaP0;
                    Psub.Subtraction(P0);
                    deltaP0 = objM.copy(Psub);
                    var norm = Psub.Norm();
                    if (norm !== 0)
                    {
                        Psub.MultiplicationScalar(this.GetWidth()/norm);
                        deltaP0.MultiplicationScalar(-2*shift/norm);//
                        var x0 = Psub.GetCoordinate(0);
                        var y0 = Psub.GetCoordinate(1);
                        if (x0 !== 0 || y0 !== 0)
                        {
                            var Psub_ = objM.newObject(Psub.GetType());
                            if (x0 > 0 && y0 > 0)
                            {
                                Psub_.SetCoordinate(0,x0);
                                Psub_.SetCoordinate(1,-y0);
                            }
                            if (x0 === 0 && y0 > 0)
                            {
                                Psub_.SetCoordinate(0,y0);
                                Psub_.SetCoordinate(1,0);
                            }
                            if (x0 > 0 && y0 < 0)
                            {
                                Psub_.SetCoordinate(0,-x0);
                                Psub_.SetCoordinate(1,y0);
                            }
                            if (x0 > 0 && y0 === 0)
                            {
                                Psub_.SetCoordinate(0,0);
                                Psub_.SetCoordinate(1,-x0);
                            }
                            if (x0 < 0 && y0 < 0)
                            {
                                Psub_.SetCoordinate(0,x0);
                                Psub_.SetCoordinate(1,-y0);
                            }
                            if (x0 === 0 && y0 < 0)
                            {
                                Psub_.SetCoordinate(0,y0);
                                Psub_.SetCoordinate(1,0);
                            }
                            if (x0 < 0 && y0 > 0)
                            {
                                Psub_.SetCoordinate(0,-x0);
                                Psub_.SetCoordinate(1,y0);
                            }
                            if (x0 < 0 && y0 === 0)
                            {
                                Psub_.SetCoordinate(0,0);
                                Psub_.SetCoordinate(1,-x0);
                            }
                            var Psub2;
                            if (Psub_.ScalarProduct(Psub) === 0)
                            {
                                Psub2 = objM.copy(Psub_);
                            }else
                            {
                                var c = Psub.VectorComponent(Psub_);
                                var tmp = objM.copy(Psub);
                                tmp.MultiplicationScalar(c);
                                Psub2 = objM.copy(Psub_);
                                Psub2.Subtraction(tmp);
                            }
                            norm = Psub2.Norm();
                            Psub2.MultiplicationScalar((this.height + shift)/(2*norm));//
//                            Psub2.MultiplicationScalar((this.height)/(2*norm));
                            var P1 = objM.copy(P0);
                            P1.Addition(Psub);
                            P1.Addition(Psub2);
                            var P2 = objM.copy(P0);
                            P2.Addition(Psub);
                            Psub2.MultiplicationScalar(-1);
                            P2.Addition(Psub2);
                            P0.Addition(deltaP0);//
                            if (YN)
                            {
                                x = P0.GetCoordinate(0);
                                z = P0.GetCoordinate(2);
                                P0.SetCoordinate(0,z);
                                P0.SetCoordinate(2,x);
                                x = P1.GetCoordinate(0);
                                z = P1.GetCoordinate(2);
                                P1.SetCoordinate(0,z);
                                P1.SetCoordinate(2,x);
                                x = P2.GetCoordinate(0);
                                z = P2.GetCoordinate(2);
                                P2.SetCoordinate(0,z);
                                P2.SetCoordinate(2,x);
                            }
                            this.SetVerticle(0,P0);
                            this.SetVerticle(1,P1);
                            this.SetVerticle(2,P2);
                       }
                    }
                }
            }
        }
    };

    TThreeArrowTriangle.prototype.DrawFigure = function(scene){
        TArrow.prototype.DrawFigure.call(this,scene);
        if (typeof scene !== 'undefined' && scene !== null && scene.IsType('TThreeScene'))
        {
            if (this.GetLineColour() !== null)
            {
//                this.CalculateVertices();
                var coord1 = this.GetVerticle(0);
                var coord2 = this.GetVerticle(1);
                var coord3 = this.GetVerticle(2);
                if (coord1 !== null && coord2 !== null && coord2 !== null && coord1.IsType('TVector') && coord2.IsType('TVector') && coord3.IsType('TVector'))
                {
                    var geometryObject = new THREE.Geometry(); 
                    var transformation = scene.GetTransformation();

                    var result = transformation.MatrixVectorMultiplication(coord1);
                        geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 
                    result = transformation.MatrixVectorMultiplication(coord2);
                        geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 
                    result = transformation.MatrixVectorMultiplication(coord3);
                        geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 

                    geometryObject.faces.push(new THREE.Face3(0, 1, 2)); 

                    var triangleMaterial;
                    var colour = this.GetLineColour();
                    if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColourRGBA'))
                    {
                        var tmp = colour.Get24bitColour();
                        triangleMaterial = new THREE.MeshBasicMaterial({ 
                            color:tmp, 
                            side:THREE.DoubleSide 
                        });                                         

                    }else
                        triangleMaterial = new THREE.MeshBasicMaterial({ 
                            color:0x000000, 
                            side:THREE.DoubleSide 
                        });                                         


                    var triangleMesh = new THREE.Mesh(geometryObject, triangleMaterial); 
                    triangleMesh.position.set(0,0, 0);
                    var scene_ = scene.GetScene();
                    scene_.add(triangleMesh);         
                }
                
//                var i,n = this.GetNumberOfVerticles(),coord,x,y,z;
/*                ctx.Begin('lineClosed');
                    ctx.SetColour(this.GetLineColour());
                    ctx.SetLineWidth(this.GetLineWidth());
                    for (i = 0;i < n;i++)
                    {
                        coord = this.GetVerticle(i);
                        if (typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector'))
                        {
                            if (coord.IsType('TVector2DT'))
                            {
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y))
                                    ctx.Vertex2D(x,y);
                            }
                            if (coord.IsType('TVector3DT'))
                            {
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                z = coord.GetCoordinate(2);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y) && z !== null && IsNumeric(z))
                                    ctx.Vertex3D(x,y,z);
                            }
                        }
                    }
                ctx.End();
            }
            if (this.GetBackgroundColour() !== null)
            {
                var i,n = this.GetNumberOfVerticles(),coord,x,y;
                ctx.Begin('rectangle');
                    ctx.SetColour(this.GetBackgroundColour());
                    for (i = 0;i < n;i++)
                    {
                        coord = this.GetVerticle(i);
                        if (typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector'))
                        {
                            if (coord.IsType('TVector2DT'))
                            {
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y))
                                    ctx.Vertex2D(x,y);
                            }
                            if (coord.IsType('TVector3DT'))
                            {
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                z = coord.GetCoordinate(2);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y) && z !== null && IsNumeric(z))
                                    ctx.Vertex3D(x,y,z);                                
                            }
                        }
                    }
                ctx.End();*/
            }
        }
    };

}

TThreeArrowTriangle.prototype = new TArrow();

function TLine(){
    var type = 'TLine';
    TLine.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        this.beginArrowWidth = 15;
        this.beginArrowHeight = 10;
        this.endArrowWidth = 15;
        this.endArrowHeight = 10;
        this.beginLength = 1;
        this.endLength = 1;
        this.dashedType = null;
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TLine.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TLine') && objM !== null)
        {
            if (typeof _object.beginArrowWidth !== 'undefined' && _object.beginArrowWidth !== null && IsNumeric(_object.beginArrowWidth))
                this.beginArrowWidth = _object.beginArrowWidth;
            if (typeof _object.beginArrowHeight !== 'undefined' && _object.beginArrowHeight !== null && IsNumeric(_object.beginArrowHeight))
                this.beginArrowHeight = _object.beginArrowHeight;
            if (typeof _object.endArrowWidth !== 'undefined' && _object.endArrowWidth !== null && IsNumeric(_object.endArrowWidth))
                this.endArrowWidth = _object.endArrowWidth;
            if (typeof _object.endArrowHeight !== 'undefined' && _object.endArrowHeight !== null && IsNumeric(_object.endArrowHeight))
                this.endArrowHeight = _object.endArrowHeight;
            if (typeof _object.beginLength !== 'undefined' && _object.beginLength !== null && IsNumeric(_object.beginLength))
                this.beginLength = _object.beginLength;
            if (typeof _object.endLength !== 'undefined' && _object.endLength !== null && IsNumeric(_object.endLength))
                this.endLength = _object.endLength;
            if (typeof _object.dashedType !== 'undefined' && _object.dashedType !== null)
            {
                this.dashedType = new String(_object.dashedType);
                if (this.dashedType !== null)
                    this.dashedType = this.dashedType.toString();
            }
        }
    };


    TLine.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TLine.prototype.DrawFigure = function(ctx){
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            if (this.GetLineColour() !== null)
            {
                var i,n = this.GetNumberOfVerticles(),coord,coord2,x,y,z;
                var coord3;
                ctx.SetDashedType(this.dashedType);
                ctx.Begin('line');
                    ctx.SetColour(this.GetLineColour());
                    ctx.SetLineWidth(this.GetLineWidth());
                    for (i = 0;i < n;i++)
                    {
                        coord = this.GetVerticle(i);
                        coord2 = null;
                        coord3 = null;
                        if (this.beginLength < 1)
                        {
                            if (i === 0 && i + 1 < n)
                                coord2 = this.GetVerticle(i + 1);
                        }
                        if (this.endLength < 1)
                        {
                            if (i > 0 && i === n - 1)
                                coord3 = this.GetVerticle(i-1);
                        }
                        if (typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector'))
                        {
                            if (coord.IsType('TVector2DT'))
                            {                            
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y))
                                    ctx.Vertex2D(x,y);
                            }
                            if (coord.IsType('TVector3DT'))
                            {                            
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                z = coord.GetCoordinate(2);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y) && z !== null && IsNumeric(z))
                                    ctx.Vertex3D(x,y,z);
                            }                            
                        }
                    }
                ctx.End();
                ctx.SetDashedType(null);
            }
        }
    };

    TLine.prototype.SetArrow = function(arrow_,beginYN){
        var objM = this.GetObjectManager(),obj;
        if (objM !== null && typeof arrow_ !== 'undefined' && arrow_ !== null)
        {
            if (typeof beginYN !== 'undefined' && beginYN !== null)
            {
                var arrow = objM.newObject(arrow_);
                if (beginYN)
                    arrow.SetBegin(true);
                else
                    arrow.SetBegin(false);
                arrow.SetParent(this);
//                var tmp = objM.newObject('TColourRGBA');
//                tmp.SetColourRGBA(0,0,0,1);
                arrow.SetBackgroundColour(this.GetLineColour());
//                tmp = objM.newObject('TColourRGBA');
//                tmp.SetColourRGBA(0,0,0,1);
                arrow.SetLineColour(this.GetLineColour());
                arrow.SetLineWidth(1);
                arrow.CalculateVertices(this.GetLineWidth());
                if (beginYN)
                {
                    this.AddChild(arrow,0);
                    obj = this.GetChild(0);
                    if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
                    {
                        obj.SetWidth(this.beginArrowWidth);
                        obj.SetHeight(this.beginArrowHeight);
                    }
                }else
                {
                    this.AddChild(arrow,1);
                    obj = this.GetChild(1);
                    if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
                    {
                        obj.SetWidth(this.endArrowWidth);
                        obj.SetHeight(this.endArrowHeight);
                    }
                }
                
                return;
            }
        }
        
        if (beginYN)
            this.AddChild(null,0);
        else
            this.AddChild(null,1);
    };

    TLine.prototype.SetBeginArrowWidth = function(width)
    {
        if (typeof width !== 'undefined' && width !== null && IsNumeric(width))
        {
            var obj = this.GetChild(0);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                if (width !== obj.GetWidth())
                {
                    obj.SetWidth(width);
                    obj.CalculateVertices(this.GetLineWidth());
                }
            }
            this.beginArrowWidth = parseFloat(width);
        }
    };

    TLine.prototype.GetBeginArrowWidth = function()
    {
        return this.beginArrowWidth;
    };

    TLine.prototype.SetBeginArrowHeight = function(height)
    {
        if (typeof height !== 'undefined' && height !== null && IsNumeric(height))
        {
            var obj = this.GetChild(0);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                if (height !== obj.GetHeight())
                {
                    obj.SetHeight(height);
                    obj.CalculateVertices(this.GetLineWidth());
                }                
            }
            this.beginArrowHeight = parseFloat(height);
        }
    };

    TLine.prototype.GetBeginArrowHeight = function()
    {
        return this.beginArrowHeight;
    };

    TLine.prototype.SetEndArrowWidth = function(width)
    {
        if (typeof width !== 'undefined' && width !== null && IsNumeric(width))
        {
            var obj = this.GetChild(1);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                if (width !== obj.GetWidth())
                {
                    obj.SetWidth(width);
                    obj.CalculateVertices(this.GetLineWidth());
                }
            }
            this.endArrowWidth = parseFloat(width);
        }
    };

    TLine.prototype.GetEndArrowWidth = function()
    {
        return this.endArrowWidth;
    };

    TLine.prototype.SetEndArrowHeight = function(height)
    {
        if (typeof height !== 'undefined' && height !== null && IsNumeric(height))
        {
            var obj = this.GetChild(1);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                if (height !== obj.GetHeight())
                {
                    obj.SetHeight(height);
                    obj.CalculateVertices(this.GetLineWidth());
                }                
            }
            this.endArrowHeight = parseFloat(height);
        }
    };

    TLine.prototype.GetEndArrowHeight = function()
    {
        return this.endArrowHeight;
    };

    TLine.prototype.SetLineColour = function(colour){
        TVisibleFigure.prototype.SetLineColour.call(this,colour);
        var obj = this.GetChild(0);
        if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
        {
            obj.SetLineColour(colour);
            obj.GetBackgroundColour(colour);
        }
        obj = this.GetChild(1);
        if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
        {
            obj.SetLineColour(colour);
            obj.GetBackgroundColour(colour);
        }
    };

    TLine.prototype.SetBeginLength = function(l)
    {
        if (typeof l !== 'undefined' && l !== null && IsNumeric(l))
        {
            if (l > 1)
                l = 1;
            if (l < 0)
                l = 0;
            
            this.beginLength = l;
            var obj = this.GetChild(0);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                obj.CalculateVertices(this.GetLineWidth());
            }            
        }
    };

    TLine.prototype.SetEndLength = function(l)
    {
        if (typeof l !== 'undefined' && l !== null && IsNumeric(l))
        {
            if (l > 1)
                l = 1;
            if (l < 0)
                l = 0;

            this.endLength = l;
            var obj = this.GetChild(1);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                obj.CalculateVertices(this.GetLineWidth());
            }
        }
    };
    
    TLine.prototype.GetVerticle = function(position)
    {
        var coord,coord2;
        if (position === 0 && this.GetNumberOfVerticles() > 1)
        {
            if (this.beginLength < 1)
            {
                coord = TVisibleFigure.prototype.GetVerticle.call(this,0);
                coord2 = TVisibleFigure.prototype.GetVerticle.call(this,1);
                if (coord !== null && coord2 !== null)
                {
                    coord.Subtraction(coord2);
                    coord.MultiplicationScalar(this.beginLength);
                    coord2.Addition(coord);
                    return coord2;                 
                }
            }            
        }
        if (position === this.GetNumberOfVerticles() - 1 && this.GetNumberOfVerticles() > 1)
        {
            if (this.endLength < 1)
            {
                coord = TVisibleFigure.prototype.GetVerticle.call(this,position);
                coord2 = TVisibleFigure.prototype.GetVerticle.call(this,position - 1);
                if (coord !== null && coord2 !== null)
                {
                    coord.Subtraction(coord2);
                    coord.MultiplicationScalar(this.endLength);
                    coord2.Addition(coord);
                    return coord2;                 
                }
            }
            
        }
        
        
        return TVisibleFigure.prototype.GetVerticle.call(this,position);
    };

    TLine.prototype.SetDashedType = function(type){
        if (typeof type !== 'undefined' && type !== null)
        {
            this.dashedType = new String(type);
            if (this.dashedType !== null)
                this.dashedType = this.dashedType.toString();
        }
        if (type === null)
            this.dashedType = null;
    };

}

TLine.prototype = new TVisibleFigure();


function TPolygon(){
    var type = 'TPolygon';
    TPolygon.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TPolygon.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TPolygon') && objM !== null)
        {
        }
    };


    TPolygon.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TPolygon.prototype.DrawFigure = function(ctx){
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            if (this.GetColour() !== null)
            {
                var i,n = this.GetNumberOfVerticles(),coord,coord2,x,y,z;
                var coord3;
//                ctx.SetDashedType(this.dashedType);
                ctx.Begin('polygon');
                    ctx.SetDefaultBackgroundColour(this.GetColour());
                    ctx.SetColour(this.GetLineColour());
//                    ctx.SetLineWidth(this.GetLineWidth());
                    for (i = 0;i < n;i++)
                    {
                        coord = this.GetVerticle(i);
                        coord2 = null;
                        coord3 = null;
                        if (this.beginLength < 1)
                        {
                            if (i === 0 && i + 1 < n)
                                coord2 = this.GetVerticle(i + 1);
                        }
                        if (this.endLength < 1)
                        {
                            if (i > 0 && i === n - 1)
                                coord3 = this.GetVerticle(i-1);
                        }
                        if (typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector'))
                        {
                            if (coord.IsType('TVector2DT'))
                            {                            
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y))
                                    ctx.Vertex2D(x,y);
                            }
                            if (coord.IsType('TVector3DT'))
                            {                            
                                x = coord.GetCoordinate(0);
                                y = coord.GetCoordinate(1);
                                z = coord.GetCoordinate(2);
                                if (x !== null && IsNumeric(x) && y !== null && IsNumeric(y) && z !== null && IsNumeric(z))
                                    ctx.Vertex3D(x,y,z);
                            }                            
                        }
                    }
                ctx.End();
                ctx.SetDashedType(null);
            }
        }
    };


}

TPolygon.prototype = new TVisibleFigure();

function TRationalBezierCurve(){
    var type = 'TRationalBezierCurve';
    TRationalBezierCurve.prototype.InitConstructor = function(){
        TLine.prototype.InitConstructor.call(this);
      
        this.w0 = 1;
        this.w1 = 0.5;
        this.w2 = 1;
        this.density = 0.2;
        this.nVerticlesBezier = null;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TRationalBezierCurve.prototype.Init = function(_object){
        //TODO: Implement Me 
        TLine.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TLine') && objM !== null)
        {
            if (typeof _object.w0 !== 'undefined' && _object.w0 !== null && IsNumeric(_object.w0))
                this.w0 = _object.w0;
            if (typeof _object.w1 !== 'undefined' && _object.w1 !== null && IsNumeric(_object.w1))
                this.w1 = _object.w1;
            if (typeof _object.w2 !== 'undefined' && _object.w2 !== null && IsNumeric(_object.w2))
                this.w2 = _object.w2;
            if (typeof _object.density !== 'undefined' && _object.density !== null && IsNumeric(_object.density))
                this.density = _object.density;
            if (typeof _object.nVerticlesBezier !== 'undefined' && _object.nVerticlesBezier !== null && IsInt(_object.nVerticlesBezier))
                this.nVerticlesBezier = _object.nVerticlesBezier;
        }
    };


    TRationalBezierCurve.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TLine.prototype.IsType.call(this,_type);
    };

    TRationalBezierCurve.prototype.Factorial = function(n){
        if (typeof n !== 'undefined' && n !== null && IsInt(n))
        {
            var i,out;
            if (n <= 1)
                return 1;
            out = 1;
            for (i=2;i <= n;i++)
                out = out*i;
            return out;
        }
        return null;
    };

    TRationalBezierCurve.prototype.B = function(i,n,t,j){
        //TODO: Implement Me 
        if (typeof i !== 'undefined' && i !== null && IsInt(i))
        {
            if (typeof n !== 'undefined' && n !== null && IsInt(n))
            {
                if (typeof t !== 'undefined' && t !== null && IsNumeric(t))
                {
                    if (typeof j !== 'undefined' && j !== null && IsInt(j))
                    {
                        if (i < 0 || i > n)
                            return 0;
                        var tmp = this.Factorial(n) / (this.Factorial(i) * this.Factorial(n - i));
                        return tmp*(Math.pow(t,i)*Math.pow(1-t,n-i));
                    }
                }
            }
        }
        return null;
    };

    TRationalBezierCurve.prototype.SetW0 = function(w){
        //TODO: Implement Me 
        if (typeof w !== 'undefined' && w !== null && IsNumeric(w))
            this.w0 = w;
    };

    TRationalBezierCurve.prototype.SetW1 = function(w){
        //TODO: Implement Me 
        if (typeof w !== 'undefined' && w !== null && IsNumeric(w))
            this.w1 = w;
    };

    TRationalBezierCurve.prototype.SetW2 = function(w){
        //TODO: Implement Me 
        if (typeof w !== 'undefined' && w !== null && IsNumeric(w))
            this.w2 = w;
    };

    TRationalBezierCurve.prototype.SetDensity = function(den){
        //TODO: Implement Me 
        if (typeof den !== 'undefined' && den !== null && IsNumeric(den))
            this.density = den;
    };

    TRationalBezierCurve.prototype.DrawFigure = function(ctx){
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext') && this.GetLineType() !== 'none')
        {
            var nV = this.GetNumberOfVerticles();
            var P0 = this.GetVerticle(0);
            var P1 = this.GetVerticle(1);
            var P2 = this.GetVerticle(2);
            if (this.GetLineColour() !== null && nV >= 3 && P0 !== null && P0.IsType('TVector') && P1 !== null && P1.IsType('TVector') && P2 !== null && P2.IsType('TVector'))
            {
                var dist = P1.Distance(P0) + P2.Distance(P1);
                if (dist !== null && IsNumeric(dist) && dist > 0)
                {
                    var n;
                    if (this.nVerticlesBezier !== null)
                        n = this.nVerticlesBezier;
                    else
                        n = dist*this.density;
                    var lx,ly,m,t,i;
                    var inc = 1/(n - 1);
                    ctx.Begin('line');
                        ctx.SetColour(this.GetLineColour());
                        ctx.SetLineWidth(this.GetLineWidth());
                        for (t = 0, i = 0; i < n; t = t + inc, i++) {
                            lx = this.w0*P0.GetCoordinate(0)*this.B(0, 2, t, i) + this.w1*P1.GetCoordinate(0)*this.B(1, 2, t, i) + this.w2*P2.GetCoordinate(0)*this.B(2, 2, t, i);
                            ly = this.w0*P0.GetCoordinate(1)*this.B(0, 2, t, i) + this.w1*P1.GetCoordinate(1)*this.B(1, 2, t, i) + this.w2*P2.GetCoordinate(1)*this.B(2, 2, t, i);
//                            lz = this.w0*P0.GetCoordinate(2)*this.B(0, 2, t, i) + this.w1*P1.GetCoordinate(2)*this.B(1, 2, t, i) + this.w2*P2.GetCoordinate(2)*this.B(2, 2, t, i);
                            m = this.w0*this.B(0, 2, t, i) + this.w1*this.B(1, 2, t, i) + this.w2*this.B(2, 2, t, i); 
                            if (P0.IsType('TVector3DT'))
                                ctx.Vertex3D(lx/m,ly/m,0);
                            else
                                ctx.Vertex2D(lx/m,ly/m);
                        }
                    ctx.End();
                }
            }
        }
    };

    TRationalBezierCurve.prototype.SetNVerticles = function(n){
        //TODO: Implement Me 
        if (typeof n !== 'undefined' && n !== null && IsInt(n))
            this.nVerticlesBezier = n;
        if (n === null)
            this.nVerticlesBezier = null;
    };

}

TRationalBezierCurve.prototype = new TLine();


function TRectangle(){
    var type = 'TRectangle';
    TRectangle.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.width = 0;
        this.height = 0;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TRectangle.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TRectangle') && objM !== null)
        {
            if (typeof _object.width !== 'undefined' && _object.width !== null && IsNumeric(_object.width))
                this.width = _object.width;
            if (typeof _object.height !== 'undefined' && _object.height !== null && IsNumeric(_object.height))
                this.height = _object.height;
            
        }
    };
    
    TRectangle.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TRectangle.prototype.SetArea = function(typeInteractive){
        var objM = this.GetObjectManager();        
        if (objM !== null)
        {
            var area_ = null;        
            switch(typeInteractive)
            {
                case 'Move':
                    area_ = objM.newObject('TAreaRectangle');
                if (area_ !== null)
                {
                    area_.SetCoordinates(this.GetCoordinates());
                    area_.SetWidth(this.GetWidth());
                    area_.SetHeight(this.GetHeight());
                    area_.SetParent(this);
                }
                break;
            }
            return area_;
        }
        return null;
    };

    TRectangle.prototype.TypeSelection = function(_type){
        TVisibleFigure.prototype.TypeSelection.call(this,_type);
        if (typeof _type !== 'undefined' && _type !== null)
        {
            var objM = this.GetObjectManager();     
            if  (objM !== null)
            {
                var area_;
                switch (_type)
                {
                    case 'Move':
                        area_ = objM.newObject('TAreaRectangle');
                        break;
                    default:
                        area_ = objM.newObject('TAreaRectangle');
                }
                if (area_ !== null)
                {
                    area_.SetCoordinates(this.GetCoordinates());
                    area_.SetWidth(this.GetWidth());
                    area_.SetHeight(this.GetHeight());
                }
                return area_;
            }
        }
        return null;
    };

    TRectangle.prototype.SetWidth = function(width_){
        if (typeof width_ !== 'undefined' && width_ !== null && IsNumeric(width_))
        {
            this.width = width_;
            var tmp = this.GetArea();
            if (tmp !== null)
            {
                tmp.SetWidth(this.width);
            }
        }
    };

    TRectangle.prototype.SetHeight = function(height_){
        if (typeof height_ !== 'undefined' && height_ !== null && IsNumeric(height_))
        {
            this.height = height_;
            var tmp = this.GetArea();
            if (tmp !== null)
            {
                tmp.SetHeight(this.height);
            }
        }
    };

    TRectangle.prototype.GetWidth = function(){
        return this.width;
    };

    TRectangle.prototype.GetHeight = function(){
        return this.height;
    };

    TRectangle.prototype.DrawFigure = function(ctx){
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            var coord = this.GetCoordinates();
            if (coord !== null)
            {
                var colour = this.GetBackgroundColour();
                if (colour !== null && colour.GetColourA() > 0 && this.GetBackgroundType() !== 'none')
                {
                    ctx.Begin('rectangle');
                        ctx.SetColour(this.GetBackgroundColour());
                        if (coord.IsType('TVector2DT'))
                        {                            
                            ctx.Vertex2D(-this.width/2,-this.height/2);
                            ctx.Vertex2D(this.width/2,-this.height/2);
                            ctx.Vertex2D(this.width/2,this.height/2);
                            ctx.Vertex2D(-this.width/2,this.height/2);
                        }
                        if (coord.IsType('TVector3DT'))
                        {                            
                            ctx.Vertex3D(-this.width/2,-this.height/2,0);
                            ctx.Vertex3D(this.width/2,-this.height/2,0);
                            ctx.Vertex3D(this.width/2,this.height/2,0);
                            ctx.Vertex3D(-this.width/2,this.height/2,0);
                        }
                    ctx.End();
                }
                colour = this.GetLineColour();
                if (colour !== null && colour.GetColourA() > 0 && this.GetLineType() !== 'none')
                {
                    ctx.Begin('line');
                        ctx.SetColour(this.GetLineColour());
                        ctx.SetLineWidth(this.GetLineWidth());
                        if (coord.IsType('TVector2DT'))
                        {                            
                            ctx.Vertex2D(-this.width/2,-this.height/2);
                            ctx.Vertex2D(this.width/2,-this.height/2);
                            ctx.Vertex2D(this.width/2,this.height/2);
                            ctx.Vertex2D(-this.width/2,this.height/2);
                            ctx.Vertex2D(-this.width/2,-this.height/2);
                            ctx.Vertex2D(this.width/2,-this.height/2);
                       }
                        if (coord.IsType('TVector3DT'))
                        {                            
                            ctx.Vertex3D(-this.width/2,-this.height/2,0);
                            ctx.Vertex3D(this.width/2,-this.height/2,0);
                            ctx.Vertex3D(this.width/2,this.height/2,0);
                            ctx.Vertex3D(-this.width/2,this.height/2,0);
                            ctx.Vertex3D(-this.width/2,-this.height/2,0);
                            ctx.Vertex3D(this.width/2,-this.height/2,0);
                        }
    //                    ctx.Vertex2D(-this.width/2,-this.height/2);
                    ctx.End();
                }
            }
/*            var ctx_ = ctx.GetContext();
            if (typeof ctx_ !== 'undefined' && ctx_ !== null)
            {
                if (this.width !== null && this.height !== null)
                {
                    ctx_.beginPath();
                    ctx_.moveTo(-this.width/2,-this.height/2);
                    ctx_.lineTo(this.width/2,-this.height/2);
                    ctx_.lineTo(this.width/2,this.height/2);
                    ctx_.lineTo(-this.width/2,this.height/2);
//                    ctx_.lineTo(-this.width/2,-this.height/2);
                    ctx_.fill();
                }
            }*/
        }
    };
}

TRectangle.prototype = new TVisibleFigure();


function TCircle(){
    var type = 'TCircle';
    TCircle.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.radius = 0;
        this.nVertex = 10;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TCircle.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TCircle') && objM !== null)
        {
            if (typeof _object.radius !== 'undefined' && _object.radius !== null && IsNumeric(_object.radius))
                this.radius = _object.radius;
            if (typeof _object.nVertex !== 'undefined' && _object.nVertex !== null && IsInt(_object.nVertex))
                this.nVertex = _object.nVertex;
            
        }
    };
    
    TCircle.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };


    TCircle.prototype.SetRadius = function(r){
        if (typeof r !== 'undefined' && r !== null && IsNumeric(r))
        {
            this.radius = r;
        }
    };

    TCircle.prototype.GetRadius = function(){
        return this.radius;
    };

    TCircle.prototype.SetNVertex = function(n){
        if (typeof n !== 'undefined' && n !== null && IsInt(n))
        {
            this.nVertex = n;
        }
    };

    TCircle.prototype.GetNVertex = function(){
        return this.nVertex;
    };


    TCircle.prototype.DrawFigure = function(ctx){
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
//            var coord = this.GetCoordinates();
            var coord = this.GetVerticle(0);
            if (coord !== null)
            {
//                var colour = this.GetBackgroundColour();
//                if (colour !== null && colour.GetColourA() > 0 && this.GetBackgroundType() !== 'none')
                {
/*                    ctx.Begin('rectangle');
                        ctx.SetColour(this.GetBackgroundColour());
                        if (coord.IsType('TVector2DT'))
                        {                            
                            ctx.Vertex2D(-this.width/2,-this.height/2);
                            ctx.Vertex2D(this.width/2,-this.height/2);
                            ctx.Vertex2D(this.width/2,this.height/2);
                            ctx.Vertex2D(-this.width/2,this.height/2);
                        }
                        if (coord.IsType('TVector3DT'))
                        {                            
                            ctx.Vertex3D(-this.width/2,-this.height/2,0);
                            ctx.Vertex3D(this.width/2,-this.height/2,0);
                            ctx.Vertex3D(this.width/2,this.height/2,0);
                            ctx.Vertex3D(-this.width/2,this.height/2,0);
                        }
                    ctx.End();*/
                }
 //               var colour = this.GetLineColour();
//                if (colour !== null && colour.GetColourA() > 0 && this.GetLineType() !== 'none')
                {
                    ctx.Begin('circle');
                        ctx.SetColour(this.GetLineColour());
                        ctx.SetDefaultBackgroundColour(this.GetBackgroundColour());
                        ctx.SetLineWidth(this.GetLineWidth());
                        ctx.Vertex(coord);
                        ctx.SetParameter(this.GetRadius());
                    ctx.End();
                }
            }
/*            var ctx_ = ctx.GetContext();
            if (typeof ctx_ !== 'undefined' && ctx_ !== null)
            {
                if (this.width !== null && this.height !== null)
                {
                    ctx_.beginPath();
                    ctx_.moveTo(-this.width/2,-this.height/2);
                    ctx_.lineTo(this.width/2,-this.height/2);
                    ctx_.lineTo(this.width/2,this.height/2);
                    ctx_.lineTo(-this.width/2,this.height/2);
//                    ctx_.lineTo(-this.width/2,-this.height/2);
                    ctx_.fill();
                }
            }*/
        }
    };
}

TCircle.prototype = new TVisibleFigure();

function TEllipse(){
    var type = 'TEllipse';
    TEllipse.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.radiusX = 0;
        this.radiusY = 0;
        this.nVertex = 10;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TEllipse.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TEllipse') && objM !== null)
        {
            if (typeof _object.radiusX !== 'undefined' && _object.radiusX !== null && IsNumeric(_object.radiusX))
                this.radiusX = _object.radiusX;
            if (typeof _object.radiusY !== 'undefined' && _object.radiusY !== null && IsNumeric(_object.radiusY))
                this.radiusY = _object.radiusY;
            if (typeof _object.nVertex !== 'undefined' && _object.nVertex !== null && IsInt(_object.nVertex))
                this.nVertex = _object.nVertex;
            
        }
    };
    
    TEllipse.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };


    TEllipse.prototype.SetRadius = function(rx,ry){
        if (typeof rx !== 'undefined' && rx !== null && IsNumeric(rx) && typeof ry !== 'undefined' && ry !== null && IsNumeric(ry))
        {
            this.radiusX = rx;
            this.radiusY = ry;
        }
    };

    TEllipse.prototype.GetRadiusX = function(){
        return this.radiusX;
    };

    TEllipse.prototype.GetRadiusY = function(){
        return this.radiusY;
    };

    TEllipse.prototype.SetNVertex = function(n){
        if (typeof n !== 'undefined' && n !== null && IsInt(n))
        {
            this.nVertex = n;
        }
    };

    TEllipse.prototype.GetNVertex = function(){
        return this.nVertex;
    };


    TEllipse.prototype.DrawFigure = function(ctx){
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            var coord = this.GetVerticle(0);
            if (coord !== null)
            {
                ctx.Begin('ellipse');
                    ctx.SetColour(this.GetLineColour());
                    ctx.SetDefaultBackgroundColour(this.GetBackgroundColour());
                    ctx.SetLineWidth(this.GetLineWidth());
                    ctx.Vertex(coord);
                    ctx.SetParameter(this.GetRadiusX(),0);
                    ctx.SetParameter(this.GetRadiusY(),1);
                ctx.End();
            }
        }
    };
}

TEllipse.prototype = new TVisibleFigure();

function TThreeTransformation(){
    var type = 'TThreeTransformation';
    TThreeTransformation.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.SetType(type);
        this.coordinates = null;
        this.alpha=0;
        this.beta=0;
        this.gamma=0;
        this.scaleX=1;
        this.scaleY=1;
        this.scaleZ=1;
            
    };
    this.InitConstructor();

    TThreeTransformation.prototype.Init = function(_object){
        TVisibleFigure.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TThreeTransformation') && objM !== null)
        {            
            if (typeof _object.coordinates !== 'undefined' && _object.coordinates !== null && coordinates.IsType('TVector3DT'))
                this.coordinates = objM.copy(_object.coordinates);
            if (typeof _object.alpha !== 'undefined' && _object.alpha !== null && IsNumeric(_object.alpha ))
                this.alpha = _object.alpha;
            if (typeof _object.beta !== 'undefined' && _object.beta !== null && IsNumeric(_object.beta))
                this.beta = _object.beta;
            if (typeof _object.gamma !== 'undefined' && _object.gamma !== null && IsNumeric(_object.gamma))
                this.gamma = _object.gamma;
            if (typeof _object.scaleX !== 'undefined' && _object.scaleX !== null && IsNumeric(_object.scaleX))
                this.scaleX = _object.scaleX;
            if (typeof _object.scaleY !== 'undefined' && _object.scaleY !== null && IsNumeric(_object.scaleY))
                this.scaleY = _object.scaleY;
            if (typeof _object.scaleZ !== 'undefined' && _object.scaleZ !== null && IsNumeric(_object.scaleZ))
                this.scaleZ = _object.scaleZ;
        }
    };
    
    TThreeTransformation.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TThreeTransformation.prototype.SetCoordinates = function(coord){
        var objM = this.GetObjectManager();
        if (typeof objM !== 'undefined' && objM !== null && typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector3DT'))
            this.coordinates = objM.copy(coord);
        if (coord === null)
            this.coordinates = null;
    };

    TThreeTransformation.prototype.GetCoordinates = function(){
        var objM = this.GetObjectManager();
        if (typeof objM !== 'undefined' && objM !== null)
        {
            var tmp = objM.copy(this.coordinates);
            return tmp;
        }
    };

    TThreeTransformation.prototype.SetAlpha = function(alpha_){
        if (typeof alpha_ !== 'undefined' && alpha_ !== null && IsNumeric(alpha_))
            this.alpha = alpha_;
    };

    TThreeTransformation.prototype.GetAlpha = function(){
        return this.alpha;
    };
    
    TThreeTransformation.prototype.SetBeta = function(beta_){
        if (typeof beta_ !== 'undefined' && beta_ !== null && IsNumeric(beta_))
            this.beta = beta_;
    };

    TThreeTransformation.prototype.GetBeta = function(){
        return this.beta;
    };
    
    TThreeTransformation.prototype.SetGamma = function(gamma_){
        if (typeof gamma_ !== 'undefined' && gamma_ !== null && IsNumeric(gamma_))
            this.gamma = gamma_;
    };

    TThreeTransformation.prototype.GetGamma = function(){
        return this.gamma;
    };
    
    TThreeTransformation.prototype.SetScaleX = function(scale){
        if (typeof scale !== 'undefined' && scale !== null && IsNumeric(scale))
            this.scaleX = scale;
    };

    TThreeTransformation.prototype.GetScaleX = function(){
        return this.scaleX;
    };
    
    TThreeTransformation.prototype.SetScaleY = function(scale){
        if (typeof scale !== 'undefined' && scale !== null && IsNumeric(scale))
            this.scaleY = scale;
    };

    TThreeTransformation.prototype.GetScaleY = function(){
        return this.scaleY;
    };
    
    TThreeTransformation.prototype.SetScaleZ = function(scale){
        if (typeof scale !== 'undefined' && scale !== null && IsNumeric(scale))
            this.scaleZ = scale;
    };

    TThreeTransformation.prototype.GetScaleZ = function(){
        return this.scaleZ;
    };
    
    TThreeTransformation.prototype.SetScale = function(scale){
        if (typeof scale !== 'undefined' && scale !== null && IsNumeric(scale))
        {
            this.scaleX = scale;
            this.scaleY = scale;
            this.scaleZ = scale;
        }
    };

}

TThreeTransformation.prototype = new TVisibleFigure();


function TThreeTriangle(){
    var type = 'TThreeTriangle';
    TThreeTriangle.prototype.InitConstructor = function(){
        TThreeTransformation.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TThreeTriangle.prototype.Init = function(_object){
        TThreeTransformation.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && objM !== null && _object !== null && _object.IsType('TThreeTriangle') && objM !== null)
        {            
        }
    };
    
    TThreeTriangle.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TThreeTransformation.prototype.IsType.call(this,_type);
    };

    TThreeTriangle.prototype.DrawFigure = function(scene){
        if (typeof scene !== 'undefined' && scene !== null && scene.IsType('TThreeScene'))
        {
//            var coord = this.GetCoordinates();
            var coord1 = this.GetVerticle(0);
            var coord2 = this.GetVerticle(1);
            var coord3 = this.GetVerticle(2);
            if (coord1 !== null && coord2 !== null && coord3 !== null && coord1.IsType('TVector') && coord2.IsType('TVector') && coord3.IsType('TVector'))
            {
                var geometryObject = new THREE.Geometry(); 
                var transformation = scene.GetTransformation();

                var result = transformation.MatrixVectorMultiplication(coord1);
                    geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 
                result = transformation.MatrixVectorMultiplication(coord2);
                    geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 
                result = transformation.MatrixVectorMultiplication(coord3);
                    geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 

                geometryObject.faces.push(new THREE.Face3(0, 1, 2)); 

                var triangleMaterial;
                var colour = this.GetColour();
                if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColourRGBA'))
                {
                    var tmp = colour.Get24bitColour();
		    var a = colour.GetColourA();
		    if (a < 1)
		    {
                        triangleMaterial = new THREE.MeshLambertMaterial({ 
                            color:tmp,
			    transparent: true, opacity: a,
                            side:THREE.DoubleSide 
                        });
		    }else
		    {
                        triangleMaterial = new THREE.MeshBasicMaterial({ 
                            color:tmp, 
                            side:THREE.DoubleSide 
                        });
		    }                                         
                    
                }else
                    triangleMaterial = new THREE.MeshBasicMaterial({ 
                        color:0xFFFFFF, 
                        side:THREE.DoubleSide 
                    });                                         

                                        
                var triangleMesh = new THREE.Mesh(geometryObject, triangleMaterial); 
                triangleMesh.position.set(0,0, 0);
                var scene_ = scene.GetScene();
                scene_.add(triangleMesh);         
            

/*                scene.Begin('triangle');
//                    scene.SetColour(this.GetLineColour());
//                    scene.SetBackgroundColour(this.GetBackgroundColour());
//                    scene.SetLineWidth(this.GetLineWidth());
                    scene.Vertex(coord1);
                    scene.Vertex(coord2);
                    scene.Vertex(coord3);
                scene.End();*/
            }
        }
    };
}

TThreeTriangle.prototype = new TThreeTransformation();

function TThreeSphere(){
    var type = 'TThreeSphere';
    TThreeSphere.prototype.InitConstructor = function(){
        TThreeTransformation.prototype.InitConstructor.call(this);
        
        this.SetType(type);
        this.radius = 1;
	this.segments=16;
      	this.rings=16;      
      	this.wireframe=false;      
    };
    this.InitConstructor();

    TThreeSphere.prototype.Init = function(_object){
        TThreeTransformation.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && objM !== null && _object !== null && _object.IsType('TThreeSphere') && objM !== null)
        {            
            if (typeof _object.radius !== 'undefined' && _object.radius !== null && IsNumeric(_object.radius))
                this.radius = _object.radius;
        }
    };
    
    TThreeSphere.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TThreeTransformation.prototype.IsType.call(this,_type);
    };

    TThreeSphere.prototype.SetRadius = function(_radius){
        //TODO: Implement Me 
        if (_radius !== 'undefined' && _radius !== null && IsNumeric(_radius))
        {
	    this.radius = _radius;
        }
    };

    TThreeSphere.prototype.SetWireframe = function(wireframe){
        //TODO: Implement Me 
        if (wireframe !== 'undefined' && wireframe !== null)
        {
	    this.wireframe = wireframe;
        }
    };

    TThreeSphere.prototype.DrawFigure = function(scene){
        if (typeof scene !== 'undefined' && scene !== null && scene.IsType('TThreeScene'))
        {
//            var coord = this.GetCoordinates();
            var transformation = scene.GetTransformation();
            var coord = this.GetVerticle(0);
            if (coord !== null && coord.IsType('TVector'))
            {

                var sphereMaterial;
                var colour = this.GetColour();
                if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColourRGBA'))
                {
                    var tmp = colour.Get24bitColour();
		    var a = colour.GetColourA();
		    if (a < 1)
		    {
                        sphereMaterial = new THREE.MeshLambertMaterial({ 
                            color:tmp,
			    transparent: true, opacity: a,wireframe:this.wireframe
                        });
		    }else
		    {
                        sphereMaterial = new THREE.MeshBasicMaterial({ 
                            color:tmp, 
                            side:THREE.DoubleSide 
                        });
		    }                                         
                    
                }else
                    sphereMaterial = new THREE.MeshBasicMaterial({ 
                        color:0xFFFFFF, 
                        side:THREE.DoubleSide,wireframe:this.wireframe
                    });                                         

                var coord1 = transformation.CreateVector();
                var coord2 = transformation.CreateVector();
                coord2.SetCoordinate(0,this.radius);
                var result1 = transformation.MatrixVectorMultiplication(coord1);
                var result2 = transformation.MatrixVectorMultiplication(coord2);
                result2.Subtraction(result1);
		var sphere = new THREE.Mesh(new THREE.SphereGeometry(result2.Norm(),this.segments,this.rings),sphereMaterial);
                var result = transformation.MatrixVectorMultiplication(coord);
                sphere.position.set(result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2));
                var scene_ = scene.GetScene();
                scene_.add(sphere);         
            }
        }
    };
}

TThreeSphere.prototype = new TThreeTransformation();


function TThreeLine(){
    var type = 'TThreeLine';
    TThreeLine.prototype.InitConstructor = function(){
        TThreeTransformation.prototype.InitConstructor.call(this);
        
        this.SetType(type);
        this.beginArrowWidth = 0.15;
        this.beginArrowHeight = 0.10;
        this.endArrowWidth = 0.15;
        this.endArrowHeight = 0.10;
        this.beginLength = 1;
        this.endLength = 1;
            
    };
    this.InitConstructor();

    TThreeLine.prototype.Init = function(_object){
        TThreeTransformation.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TThreeLine') && objM !== null)
        {            
            if (typeof _object.beginArrowWidth !== 'undefined' && _object.beginArrowWidth !== null && IsNumeric(_object.beginArrowWidth))
                this.beginArrowWidth = _object.beginArrowWidth;
            if (typeof _object.beginArrowHeight !== 'undefined' && _object.beginArrowHeight !== null && IsNumeric(_object.beginArrowHeight))
                this.beginArrowHeight = _object.beginArrowHeight;
            if (typeof _object.endArrowWidth !== 'undefined' && _object.endArrowWidth !== null && IsNumeric(_object.endArrowWidth))
                this.endArrowWidth = _object.endArrowWidth;
            if (typeof _object.endArrowHeight !== 'undefined' && _object.endArrowHeight !== null && IsNumeric(_object.endArrowHeight))
                this.endArrowHeight = _object.endArrowHeight;
            if (typeof _object.beginLength !== 'undefined' && _object.beginLength !== null && IsNumeric(_object.beginLength))
                this.beginLength = _object.beginLength;
            if (typeof _object.endLength !== 'undefined' && _object.endLength !== null && IsNumeric(_object.endLength))
                this.endLength = _object.endLength;
        }
    };
    
    TThreeLine.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TThreeTransformation.prototype.IsType.call(this,_type);
    };

    TThreeLine.prototype.DrawFigure = function(scene){
        if (typeof scene !== 'undefined' && scene !== null && scene.IsType('TThreeScene'))
        {
            var geometryObject = new THREE.Geometry(); 
            var transformation = scene.GetTransformation();
            
            var i,n = this.GetNumberOfVerticles(),coord,result;
/*            var obj = this.GetChild(0);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
                obj.CalculateVertices(this.GetLineWidth());
            obj = this.GetChild(1);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
                obj.CalculateVertices(this.GetLineWidth());*/
            
            for (i = 0;i < n;i++)
            {
                coord = this.GetVerticle(i);
                result = transformation.MatrixVectorMultiplication(coord);
                geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 
            }

            var colour = this.GetLineColour();
            var material;
            if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColourRGBA'))
            {
                var tmp = colour.Get24bitColour();
                material = new THREE.LineBasicMaterial({ 
                    color:tmp
                });                                         

            }else
                material = new THREE.MeshBasicMaterial({ 
                    color:0x000000
                });            
//            material.type = THREE.Lines;
            var line = new THREE.Line(geometryObject,material);
            //            var coord = this.GetCoordinates();
            var scene_ = scene.GetScene();
            scene_.add(line);         
            
        }
    };


    TThreeLine.prototype.SetArrow = function(arrow_,beginYN){
        var objM = this.GetObjectManager(),obj;
        if (objM !== null && typeof arrow_ !== 'undefined' && arrow_ !== null)
        {
            if (typeof beginYN !== 'undefined' && beginYN !== null)
            {
                var arrow = objM.newObject(arrow_);
                if (beginYN)
                    arrow.SetBegin(true);
                else
                    arrow.SetBegin(false);
                arrow.SetParent(this);
//                var tmp = objM.newObject('TColourRGBA');
//                tmp.SetColourRGBA(0,0,0,1);
                arrow.SetBackgroundColour(this.GetLineColour());
//                tmp = objM.newObject('TColourRGBA');
//                tmp.SetColourRGBA(0,0,0,1);
                arrow.SetLineColour(this.GetLineColour());
                arrow.SetLineWidth(1);
                arrow.CalculateVertices(this.GetLineWidth());
                if (beginYN)
                {
                    this.AddChild(arrow,0);
                    obj = this.GetChild(0);
                    if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
                    {
                        obj.SetWidth(this.beginArrowWidth);
                        obj.SetHeight(this.beginArrowHeight);
                    }
                }else
                {
                    this.AddChild(arrow,1);
                    obj = this.GetChild(1);
                    if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
                    {
                        obj.SetWidth(this.endArrowWidth);
                        obj.SetHeight(this.endArrowHeight);
                    }
                }
                
                return;
            }
        }
        
        if (beginYN)
            this.AddChild(null,0);
        else
            this.AddChild(null,1);
    };

    TThreeLine.prototype.SetBeginArrowWidth = function(width)
    {
        if (typeof width !== 'undefined' && width !== null && IsNumeric(width))
        {
            var obj = this.GetChild(0);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                if (width !== obj.GetWidth())
                {
                    obj.SetWidth(width);
                    obj.CalculateVertices(this.GetLineWidth());
                }
            }
            this.beginArrowWidth = parseFloat(width);
        }
    };

    TThreeLine.prototype.GetBeginArrowWidth = function()
    {
        return this.beginArrowWidth;
    };

    TThreeLine.prototype.SetBeginArrowHeight = function(height)
    {
        if (typeof height !== 'undefined' && height !== null && IsNumeric(height))
        {
            var obj = this.GetChild(0);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                if (height !== obj.GetHeight())
                {
                    obj.SetHeight(height);
                    obj.CalculateVertices(this.GetLineWidth());
                }                
            }
            this.beginArrowHeight = parseFloat(height);
        }
    };

    TThreeLine.prototype.GetBeginArrowHeight = function()
    {
        return this.beginArrowHeight;
    };

    TThreeLine.prototype.SetEndArrowWidth = function(width)
    {
        if (typeof width !== 'undefined' && width !== null && IsNumeric(width))
        {
            var obj = this.GetChild(1);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                if (width !== obj.GetWidth())
                {
                    obj.SetWidth(width);
                    obj.CalculateVertices(this.GetLineWidth());
                }
            }
            this.endArrowWidth = parseFloat(width);
        }
    };

    TThreeLine.prototype.GetEndArrowWidth = function()
    {
        return this.endArrowWidth;
    };

    TThreeLine.prototype.SetEndArrowHeight = function(height)
    {
        if (typeof height !== 'undefined' && height !== null && IsNumeric(height))
        {
            var obj = this.GetChild(1);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                if (height !== obj.GetHeight())
                {
                    obj.SetHeight(height);
                    obj.CalculateVertices(this.GetLineWidth());
                }                
            }
            this.endArrowHeight = parseFloat(height);
        }
    };

    TThreeLine.prototype.GetEndArrowHeight = function()
    {
        return this.endArrowHeight;
    };

    TThreeLine.prototype.SetLineColour = function(colour){
        TThreeTransformation.prototype.SetLineColour.call(this,colour);
        var obj = this.GetChild(0);
        if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
        {
            obj.SetLineColour(colour);
            obj.GetBackgroundColour(colour);
        }
        obj = this.GetChild(1);
        if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
        {
            obj.SetLineColour(colour);
            obj.GetBackgroundColour(colour);
        }
    };

    TThreeLine.prototype.SetBeginLength = function(l)
    {
        if (typeof l !== 'undefined' && l !== null && IsNumeric(l))
        {
            if (l > 1)
                l = 1;
            if (l < 0)
                l = 0;
            
            this.beginLength = l;
            var obj = this.GetChild(0);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                obj.CalculateVertices(this.GetLineWidth());
            }            
        }
    };

    TThreeLine.prototype.SetEndLength = function(l)
    {
        if (typeof l !== 'undefined' && l !== null && IsNumeric(l))
        {
            if (l > 1)
                l = 1;
            if (l < 0)
                l = 0;

            this.endLength = l;
            var obj = this.GetChild(1);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
            {
                obj.CalculateVertices(this.GetLineWidth());
            }
        }
    };
    
    TThreeLine.prototype.GetVerticle = function(position)
    {
        var coord,coord2;
        if (position === 0 && this.GetNumberOfVerticles() > 1)
        {
            if (this.beginLength < 1)
            {
                coord = TThreeTransformation.prototype.GetVerticle.call(this,0);
                coord2 = TThreeTransformation.prototype.GetVerticle.call(this,1);
                if (coord !== null && coord2 !== null)
                {
                    coord.Subtraction(coord2);
                    coord.MultiplicationScalar(this.beginLength);
                    coord2.Addition(coord);
                    return coord2;                 
                }
            }            
        }
        if (position === this.GetNumberOfVerticles() - 1 && this.GetNumberOfVerticles() > 1)
        {
            if (this.endLength < 1)
            {
                coord = TThreeTransformation.prototype.GetVerticle.call(this,position);
                coord2 = TThreeTransformation.prototype.GetVerticle.call(this,position - 1);
                if (coord !== null && coord2 !== null)
                {
                    coord.Subtraction(coord2);
                    coord.MultiplicationScalar(this.endLength);
                    coord2.Addition(coord);
                    return coord2;                 
                }
            }
            
        }
        
        
        return TThreeTransformation.prototype.GetVerticle.call(this,position);
    };

    TThreeLine.prototype.SetVerticle = function(position,coordinates){
        TThreeTransformation.prototype.SetVerticle.call(this,position,coordinates);
            var obj = this.GetChild(0);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
                obj.CalculateVertices(this.GetLineWidth());
            obj = this.GetChild(1);
            if (typeof obj !== 'undefined' && obj !== null && obj.IsType('TArrow'))
                obj.CalculateVertices(this.GetLineWidth());
    };

}

TThreeLine.prototype = new TThreeTransformation();


function TThreeText(){
    var type = 'TThreeText';
    TThreeText.prototype.InitConstructor = function(){
        TThreeTransformation.prototype.InitConstructor.call(this);
        
        this.SetType(type);
        this.text = null;
        this.fontSize = 1;
        this.curveSegments = 1;
        this.height = 0.1;
        this.colourText = null;
        this.colourSide = null;
        this.font = null;
        this.fontStyle = 'normal';
        this.fontWeight = 'normal';
        this.alignmentX = 'center';
        this.alignmentY = 'center';
        this.rotate = 0;
    };
    this.InitConstructor();

    TThreeText.prototype.Init = function(_object){
        TThreeTransformation.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TThreeText') && objM !== null)
        {
            if (typeof _object.text !== 'undefined' && _object.txt !== null)
            {
                this.text = new String(_object.text);
                if (this.text !== null)
                    this.text = this.text.toString();
            }
            if (typeof _object.fontSize !== 'undefined' && _object.fontSize !== null && IsNumeric(_object.fontSize))
                this.fontSize = _object.fontSize;
            if (typeof _object.curveSegments !== 'undefined' && _object.curveSegments !== null && IsNumeric(_object.curveSegments))
                this.curveSegments = _object.curveSegments;
            if (typeof _object.height !== 'undefined' && _object.height !== null && IsNumeric(_object.height))
                this.height = _object.height;
            if (typeof _object.colourText !== 'undefined' && _object.colourText !== null && _object.colourText.IsType('TColourRGBA'))
                this.colourText = objM.copy(_object.colourText);
            if (typeof _object.colourSide !== 'undefined' && _object.colourSide !== null && _object.colourSide.IsType('TColourRGBA'))
                this.colourSide = objM.copy(_object.colourSide);
            if (typeof _object.font !== 'undefined' && _object.font !== null)
            {
                this.font = new String(_object.font);
                if (this.font !== null)
                    this.font = this.font.toString();
            }
            if (typeof _object.fontStyle !== 'undefined' && _object.fontStyle !== null)
            {
                this.fontStyle = new String(_object.fontStyle);
                if (this.fontStyle !== null)
                    this.fontStyle = this.fontStyle.toString();
            }
            if (typeof _object.fontWeight !== 'undefined' && _object.fontWeight !== null)
            {
                this.fontWeight = new String(_object.fontWeight);
                if (this.fontWeight !== null)
                    this.fontWeight = this.fontWeight.toString();
            }
            if (typeof _object.alignmentX !== 'undefined' && _object.alignmentX !== null)
            {
                this.alignmentX = new String(_object.alignmentX);
                if (this.alignmentX !== null)
                    this.alignmentX = this.alignmentX.toString();
            }
            if (typeof _object.alignmentY !== 'undefined' && _object.alignmentY !== null)
            {
                this.alignmentY = new String(_object.alignmentY);
                if (this.alignmentY !== null)
                    this.alignmentY = this.alignmentY.toString();
            }
            if (typeof _object.rotate !== 'undefined' && _object.rotate !== null && IsNumeric(_object.rotate))
                this.rotate = _object.rotate;
        }
    };
    
    TThreeText.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TThreeTransformation.prototype.IsType.call(this,_type);
    };

    TThreeText.prototype.DrawFigure = function(scene){
        if (typeof scene !== 'undefined' && scene !== null && scene.IsType('TThreeScene'))
        {
            var coord = this.GetCoordinates();
            if (coord !== null && coord.IsType('TVector3DT') && typeof this.colourText !== 'undefined' && this.colourText !== null && this.colourText.IsType('TColourRGBA'))
            {
                if (typeof this.colourSide === 'undefined' || this.colourSide === null || !this.colourSide.IsType('TColourRGBA'))
                    this.SetSideColourText(this.colourText);
/*            var info = document.createElement( 'div' );
            info.style.position = 'absolute';
            info.style.top = '10px';
            info.style.width = '100%';
            info.style.textAlign = 'center';
            info.innerHTML = 'Simple Dynamic 3D Text Example by <a href="http://www.lab4games.net/zz85/blog">zz85</a><br>Drag to spin the text';
            container.appendChild( info );*/
/*				var theText = "Hello three.js! :)";

				var hash = document.location.hash.substr( 1 );

				if ( hash.length !== 0 ) {

					theText = hash;

				}*/

                                var fontNumber = GetFontNumner(this.font,this.style,this.weight);
				var geometry = new THREE.TextGeometry( this.text, {

					font: fontsThreePointer[fontNumber],
					size: this.fontSize,
					height: this.height,
					curveSegments: this.curveSegments

				});

				geometry.computeBoundingBox();

                                var offsetX = -0.5 * ( geometry.boundingBox.max.x - geometry.boundingBox.min.x );
                                switch(this.alignmentX)
                                {
                                    case 'right':
                                        offsetX = -( geometry.boundingBox.max.x - geometry.boundingBox.min.x );
                                        break;
                                    case 'left':
                                        offsetX = 0;
                                        break;
                                }
                                var offsetY = -0.5 * ( geometry.boundingBox.max.y - geometry.boundingBox.min.y );
                                switch(this.alignmentY)
                                {
                                    case 'bottom':
                                        offsetY = -( geometry.boundingBox.max.y - geometry.boundingBox.min.y );
                                        break;
                                    case 'top':
                                        offsetY = 0;
                                        break;
                                }

                                var tmpC = this.colourText.Get24bitColour();

				var material = new THREE.MultiMaterial( [
					new THREE.MeshBasicMaterial( { color: tmpC, overdraw: 0.5 } ),
					new THREE.MeshBasicMaterial( { color: this.colourSide.Get24bitColour(), overdraw: 0.5 } )
				] );

				var mesh = new THREE.Mesh( geometry, material );

				mesh.position.x = coord.GetX() + offsetX;
				mesh.position.y = coord.GetY() + offsetY;
				mesh.position.z = coord.GetZ();

				mesh.rotation.x = this.GetAlpha();
				mesh.rotation.y = this.GetBeta();
				mesh.rotation.z = this.GetGamma();

				mesh.scale.x = this.GetScaleX();
				mesh.scale.y = this.GetScaleY();
				mesh.scale.z = this.GetScaleZ();

                                var group = new THREE.Group();
				group.add( mesh );

                                var scene_ = scene.GetScene();
				scene_.add( group );
            
/*  var canvas = document.createElement('canvas');
  canvas.width = 128;
  canvas.height = 64;
  var context = canvas.getContext('2d');
  context.fillText("Game Over", 0, 0);
  //context.font = '48px';
  var texture = new THREE.Texture(canvas);
  texture.needsUpdate = true;
  var cover = new THREE.MeshBasicMaterial({map: texture});
  var shape = new THREE.PlaneGeometry(1, 1);
  var banner = new THREE.Mesh(shape, cover);
  banner.rotation.x = 1;
  banner.position.y = 1;
  
  var scene_ = scene.GetScene();
  scene_.add(banner);            */
            
/*  var number = document.createElement( 'div' );
	number.className = 'number';
	number.textContent = "THREE.JS";
  var object = new THREE.CSS3DObject( number );

  var glScene = scene.GetScene();
glScene.add(object);            
*/


/*            var textShapes = THREE.FontUtils.generateShapes( this.text, { size: 10, height: 5, curveSegments: 6, font: "helvetiker", weight: "normal", style: "normal" } );
            var text = new THREE.ShapeGeometry( textShapes );
            var textMesh = new THREE.Mesh( text, new THREE.MeshBasicMaterial( { color: 0xff0000 } ) ) ;
            var scene_ = scene.GetScene();
            scene_.add(textMesh);*/
/*//            var coord = this.GetCoordinates();
            var coord1 = this.GetVerticle(0);
            var coord2 = this.GetVerticle(1);
            var coord3 = this.GetVerticle(2);
            if (coord1 !== null && coord2 !== null && coord2 !== null && coord1.IsType('TVector') && coord2.IsType('TVector') && coord3.IsType('TVector'))
            {
                var geometryObject = new THREE.Geometry(); 
                var transformation = scene.GetTransformation();

                var result = transformation.MatrixVectorMultiplication(coord1);
                    geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 
                result = transformation.MatrixVectorMultiplication(coord2);
                    geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 
                result = transformation.MatrixVectorMultiplication(coord3);
                    geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 

                geometryObject.faces.push(new THREE.Face3(0, 1, 2)); 

                var triangleMaterial;
                var colour = this.GetColour();
                if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColourRGBA'))
                {
                    var tmp = colour.Get24bitColour();
                    triangleMaterial = new THREE.MeshBasicMaterial({ 
                        color:tmp, 
                        side:THREE.DoubleSide 
                    });                                         
                    
                }else
                    triangleMaterial = new THREE.MeshBasicMaterial({ 
                        color:0xFFFFFF, 
                        side:THREE.DoubleSide 
                    });                                         

                                        
                var triangleMesh = new THREE.Mesh(geometryObject, triangleMaterial); 
                triangleMesh.position.set(0,0, 0);
                var scene_ = scene.GetScene();
                scene_.add(triangleMesh);         
            

            }*/
            }
        }
    };

    TThreeText.prototype.SetText = function(txt){
        if (typeof txt !== 'undefined' && txt !== null)
        {
            this.text = new String(txt);
            if (this.text !== null)
                this.text = this.text.toString();
        }
        if (txt === null)
            this.text = null;
    };
    
    TThreeText.prototype.SetFontSize = function(size){
        if (typeof size !== 'undefined' && size !== null && IsNumeric(size))
            this.fontSize = size;
    };

    TThreeText.prototype.SetHeight = function(height_){
        if (typeof height_ !== 'undefined' && height_ !== null && IsNumeric(height_))
            this.height = height_;
    };

    TThreeText.prototype.SetCurveSegments = function(segm){
        if (typeof segm !== 'undefined' && segm !== null && IsNumeric(segm))
            this.curveSegments = segm;
    };

    TThreeText.prototype.SetColourText = function(colour){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof colour !== 'undefined' && colour !== null)
            this.colourText = objM.copy(colour);        
    };

    TThreeText.prototype.SetSideColourText = function(colour){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof colour !== 'undefined' && colour !== null)
            this.colourSide = objM.copy(colour);        
    };

    TThreeText.prototype.SetFont = function(font_){
        if (typeof font_ !== 'undefined' && font_ !== null)
        {
            this.font = new String(font_);
            if (this.font !== null)
                this.font = this.font.toString();
        }
        if (font_ === null)
            this.font = null;
    };

    TThreeText.prototype.SetFontStyle = function(style_){
        if (typeof style_ !== 'undefined' && style_ !== null)
        {
            this.style = new String(style_);
            if (this.style !== null)
                this.style = this.style.toString();
        }
    };

    TThreeText.prototype.SetFontWeight = function(weight_){
        if (typeof weight_ !== 'undefined' && weight_ !== null)
        {
            this.weight = new String(weight_);
            if (this.weight !== null)
                this.weight = this.weight.toString();
        }
    };

    TThreeText.prototype.SetAlignX = function(align){
        if (typeof align !== 'undefined' && align !== null)
        {
            this.alignmentX = new String(align);
            if (this.alignmentX !== null)
                this.alignmentX = this.alignmentX.toString();
        }
    };

    TThreeText.prototype.SetAlignY = function(align){
        if (typeof align !== 'undefined' && align !== null)
        {
            this.alignmentY = new String(align);
            if (this.alignmentY !== null)
                this.alignmentY = this.alignmentY.toString();
        }
    };
    
    TThreeText.prototype.SetRotate = function(r){
        if (typeof r !== 'undefined' && r !== null && IsNumeric(r))
            this.rotate = r;
    };
    
}

TThreeText.prototype = new TThreeTransformation();


function TThreeHTML(){
    var type = 'TThreeHTML';
    TThreeHTML.prototype.InitConstructor = function(){
        TThreeTransformation.prototype.InitConstructor.call(this);
        
        this.SetType(type);
        this.HTML = null;
        this.coordinates = null;
    };
    this.InitConstructor();

    TThreeHTML.prototype.Init = function(_object){
        TThreeTransformation.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TThreeHTML') && objM !== null)
        {
            if (typeof _object.HTML !== 'undefined' && _object.HTML !== null)
            {
                this.HTML = new String(_object.HTML);
                if (this.HTML !== null)
                    this.HTML = this.HTML.toString();
            }
            if (typeof _object.coordinates !== 'undefined' && _object.coordinates !== null && coordinates.IsType('TVector3DT'))
                this.coordinates = objM.copy(_object.coordinates);
        }
    };
    
    TThreeHTML.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TThreeTransformation.prototype.IsType.call(this,_type);
    };

    TThreeHTML.prototype.DrawFigure = function(scene){
        if (typeof scene !== 'undefined' && scene !== null && scene.IsType('TThreeScene'))
        {
            var container = document.createElement( 'div' );
            document.body.appendChild( container );

            if (typeof this.coordinates !== 'undefined' && this.coordinates !== null && this.coordinates.IsType('TVector3DT'))
            {
            
    //HTML
    var element = document.createElement('div');
    element.innerHTML = '\\(\\frac{a}{b}\\)';
    element.className = 'three-div';
    
    //CSS Object
    var div = new THREE.CSS3DObject(element);
    div.position.x = 1;
    div.position.y = 2;
    div.position.z = -20;
    var CSSScene = scene.GetSceneCSS();
    CSSScene.add(div);            
            
/*  var canvas = document.createElement('canvas');
  canvas.width = 128;
  canvas.height = 64;
  var context = canvas.getContext('2d');
  context.fillText("Game Over", 0, 0);
  //context.font = '48px';
  var texture = new THREE.Texture(canvas);
  texture.needsUpdate = true;
  var cover = new THREE.MeshBasicMaterial({map: texture});
  var shape = new THREE.PlaneGeometry(1, 1);
  var banner = new THREE.Mesh(shape, cover);
  banner.rotation.x = 1;
  banner.position.y = 1;
  
  var scene_ = scene.GetScene();
  scene_.add(banner);            */
            
/*  var number = document.createElement( 'div' );
	number.className = 'number';
	number.textContent = "THREE.JS";
  var object = new THREE.CSS3DObject( number );

  var glScene = scene.GetScene();
glScene.add(object);            
*/


/*            var textShapes = THREE.FontUtils.generateShapes( this.text, { size: 10, height: 5, curveSegments: 6, font: "helvetiker", weight: "normal", style: "normal" } );
            var text = new THREE.ShapeGeometry( textShapes );
            var textMesh = new THREE.Mesh( text, new THREE.MeshBasicMaterial( { color: 0xff0000 } ) ) ;
            var scene_ = scene.GetScene();
            scene_.add(textMesh);*/
/*//            var coord = this.GetCoordinates();
            var coord1 = this.GetVerticle(0);
            var coord2 = this.GetVerticle(1);
            var coord3 = this.GetVerticle(2);
            if (coord1 !== null && coord2 !== null && coord2 !== null && coord1.IsType('TVector') && coord2.IsType('TVector') && coord3.IsType('TVector'))
            {
                var geometryObject = new THREE.Geometry(); 
                var transformation = scene.GetTransformation();

                var result = transformation.MatrixVectorMultiplication(coord1);
                    geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 
                result = transformation.MatrixVectorMultiplication(coord2);
                    geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 
                result = transformation.MatrixVectorMultiplication(coord3);
                    geometryObject.vertices.push(new THREE.Vector3( result.GetCoordinate(0),  result.GetCoordinate(1), result.GetCoordinate(2))); 

                geometryObject.faces.push(new THREE.Face3(0, 1, 2)); 

                var triangleMaterial;
                var colour = this.GetColour();
                if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColourRGBA'))
                {
                    var tmp = colour.Get24bitColour();
                    triangleMaterial = new THREE.MeshBasicMaterial({ 
                        color:tmp, 
                        side:THREE.DoubleSide 
                    });                                         
                    
                }else
                    triangleMaterial = new THREE.MeshBasicMaterial({ 
                        color:0xFFFFFF, 
                        side:THREE.DoubleSide 
                    });                                         

                                        
                var triangleMesh = new THREE.Mesh(geometryObject, triangleMaterial); 
                triangleMesh.position.set(0,0, 0);
                var scene_ = scene.GetScene();
                scene_.add(triangleMesh);         
            

            }*/
            }
        }
    };

    TThreeHTML.prototype.SetHTML = function(html_){
        if (typeof html_ !== 'undefined' && html_ !== null)
        {
            this.HTML = new String(html_);
            if (this.HTML !== null)
                this.HTML = this.HTML.toString();
        }
        if (html_ === null)
            this.HTML = null;
    };
    
    TThreeHTML.prototype.SetCoordinates = function(coord){
        var objM = this.GetObjectManager();
        if (typeof objM !== 'undefined' && typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector3DT'))
            this.coordinates = objM.copy(coord);
        if (coord === null)
            this.coordinates = null;
    };

}

TThreeHTML.prototype = new TThreeTransformation();


function TText(){
    var type = 'TText';
    TText.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.text = '';
        this.font = 'Arial';
        this.fontSize = null;
        this.fontRelativeSize = 'normalsize';
        this.alignmentX = 'center';
        this.alignmentY = 'center';
        this.maxWidth = null;
        this.styleScaleTextYN = true;
        this.textStyle = [];
        this.colour = null;
        this.SetType(type);
        this.rotate = 0;            
    };
    this.InitConstructor();

    TText.prototype.InitConstructor2 = function(){
        TVisibleFigure.prototype.InitConstructor2.call(this);
        var objM = this.GetObjectManager();
        if (typeof objM !== null)
        {
            this.colour = objM.newObject('TColourRGBA');
            if (this.colour !== null)
                this.colour.SetColourRGBA(0,0,0,1);
        }
    };

    TText.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
        //        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TText') && objM !== null)
        {
            var i;
            if (typeof _object.text !== 'undefined' && _object.text !== null)
            {
                this.text = new String(_object.text);
                if (this.text !== null)
                    this.text = this.text.toString();
            }
            if (typeof _object.font !== 'undefined' && _object.font !== null)
            {
                this.font = new String(_object.font);
                if (this.font !== null)
                    this.font = this.font.toString();
            }else
                this.font = null;
            if (typeof _object.fontSize !== 'undefined' && _object.fontSize !== null && IsNumeric(_object.fontSize))
                this.fontSize =  _object.fontSize;
            else
                this.fontSize = null;
            if (typeof _object.font !== 'undefined' && _object.font !== null)
            {
                this.fontRelativeSize = new String(_object.fontRelativeSize);
                if (this.fontRelativeSize !== null)
                    this.fontRelativeSize = this.fontRelativeSize.toString();
            }
            if (typeof _object.alignmentX !== 'undefined' && _object.alignmentX !== null)
            {
                this.alignmentX = new String(_object.alignmentX);
                if (this.alignmentX !== null)
                    this.alignmentX = this.alignmentX.toString();
            }
            if (typeof _object.alignmentY !== 'undefined' && _object.alignmentY !== null)
            {
                this.alignmentY = new String(_object.alignmentY);
                if (this.alignmentY !== null)
                    this.alignmentY = this.alignmentY.toString();
            }
            if (typeof _object.maxWidth !== 'undefined' && _object.maxWidth !== null && IsNumeric(_object.maxWidth))
                this.maxWidth =  _object.maxWidth;
            else
                this.maxWidth = null;
            if (typeof _object.styleScaleTextYN !== 'undefined' && _object.styleScaleTextYN !== null)
                this.styleScaleTextYN = _object.styleScaleTextYN;
            if (typeof _object.textStyle !== 'undefined' && _object.elementTextStyle !== null)
            {
                for (i = 0;i < _object.textStyle.length;i++)
                {
                    if (typeof _object.textStyle[i] !== 'undefined' && _object.textStyle[i] !== null)
                    {
                        this.textStyle[i] = new String(_object.textStyle[i]);
                        if (this.textStyle[i] !== null)
                            this.textStyle[i] = this.textStyle[i].toString();
                    }
                }
            }
            if (typeof _object.colour !== 'undefined' && _object.colour !== null && _object.colour.IsType('TColour'))
                this.colour = objM.copy(_object.colour);
            if (typeof _object.rotate !== 'undefined' && _object.rotate !== null && IsNumeric(_object.rotate))
                this.rotate = _object.rotate;
        }
    };


    TText.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TText.prototype.SetText = function(coordinates,text){
        if (typeof text !== 'undefined' && text !== null)
        {
            this.text = new String(text);
            if (this.text !== null)
                this.text.toString();
        }
        TVisibleFigure.prototype.SetCoordinates.call(this,coordinates);
    };

    TText.prototype.GetText = function(){
        var tmp = new String(this.text);
        if (typeof tmp !== 'undefined' && tmp !== null)
            return tmp.toString();
        else
            return null;
    };

    TText.prototype.DrawFigure = function(ctx){
        if (this.text !== null && typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            var scaleX = 1,scaleY = 1;
            if (typeof this.transformation !== 'undefined' && this.transformation !== null && this.transformation.IsType('TMatrixTransformation'))
            {
                scaleX = this.transformation.GetScale(0);
                scaleY = this.transformation.GetScale(1);
            }
            var x = 0;
            var width = ctx.GetTextWidth(this.text.toString(),this.GetFont(),this.GetFontSize(),this.textStyle);
            if (typeof width !== 'undefined' && width !== null && IsNumeric(width) && typeof this.alignmentX !== 'undefined' && this.alignmentX !== null)
            {
                switch(this.alignmentX)
                {
                    case 'left':
                        x = 0;
                        break;
                    case 'right':
                        x = -scaleX*width;
                        break;
                    default:
                        x = -scaleX*width/2;
                        if (typeof this.maxWidth !== 'undefined' && this.maxWidth !== null)
                        {
                            if (-x > this.maxWidth/2)
                                x = -this.maxWidth/2;
                        }
                        break;
                }
            }
            if (this.font !== null)
                ctx.SetFont(this.font);
            if (this.textStyle !== null)
                ctx.SetFontStyle(this.textStyle);
            if (this.fontSize !== null)
                ctx.SetFontSize(this.fontSize);
            if (this.fontRelativeSize !== null)
                ctx.SetFontRelativeSize(this.fontRelativeSize);
            ctx.SetAlignmentX(this.alignmentX);
            ctx.SetTextBaseLine(this.alignmentY);
            var coord = this.GetCoordinates();
            if (coord !== null)
                coord.SetZeros(coord.GetN());
            ctx.SetScaleTextYN(this.styleScaleTextYN);
//            ctx.SetDefaultTextColour(this.colour); // ?????????????????
            if (typeof this.maxWidth !== 'undefined' && this.maxWidth !== null)
                ctx.Text(coord,this.text.toString(),null,scaleX*this.maxWidth);
            else
                ctx.Text(coord,this.text.toString());
        }
    };
    
    TText.prototype.SetFont = function(font_){
        if (typeof font_ !== 'undefined' && font_ !== null)
        {
            this.font = new String(font_);
            if (this.font !== null)
                this.font = this.font.toString();
        }else
            this.font = null;
    };

    TText.prototype.SetFontSize = function(fontSize_){
        if (typeof fontSize_ !== 'undefined' && fontSize_ !== null && IsNumeric(fontSize_))
            this.fontSize = fontSize_;
        else
            this.fontSize = null;
    };

    TText.prototype.GetFont = function(){
        if (this.font === null)
            return null;
        var tmp = new String(this.font);
        if (tmp !== null)
            return tmp.toString();
        else
            return null;
        
    };

    TText.prototype.GetFontSize = function(){
        return this.fontSize;
        
    };

    TText.prototype.SetAlignmentX = function(alignment){
        if (typeof alignment !== 'undefined' && alignment !== null)
        {
            this.alignmentX = new String(alignment);
            if (this.alignmentX !== null)
                this.alignmentX = this.alignmentX.toString();
        }
    };

    TText.prototype.GetAlignmentX = function(){
        if (this.alignmentX === null)
            return null;
        var tmp = new String(this.alignmentX);
        if (typeof tmp !== 'undefined' && tmp !== null)
            return tmp.toString();
        else
            return null;
    };
    
    TText.prototype.SetAlignmentY = function(alignment){
        if (typeof alignment !== 'undefined' && alignment !== null)
        {
            this.alignmentY = new String(alignment);
            if (this.alignmentY !== null)
                this.alignmentY = this.alignmentY.toString();
        }
    };

    TText.prototype.GetAlignmentY = function(){
        if (this.alignmentY === null)
            return null;
        var tmp = new String(this.alignmentY);
        if (typeof tmp !== 'undefined' && tmp !== null)
            return tmp.toString();
        else
            return null;
    };

    TText.prototype.SetMaxWidth = function(max){
        if (typeof max !== 'undefined' && max !== null && IsNumeric(max))
            this.maxWidth = max;
        else
            this.maxWidth = null;
    };

    TText.prototype.SetFontRelativeSize = function(size){
        if (typeof size !== 'undefined' && size !== null)
        {
            this.fontRelativeSize = new String(size);
            if (this.fontRelativeSize !== null)
                this.fontRelativeSize = this.fontRelativeSize.toString();
        }
        if (size === null)
            this.fontRelativeSize = null;
    };

    TText.prototype.SetScaleTextYN = function(yn){
        if (typeof yn !== 'undefined' && yn !== null)
            this.styleScaleTextYN = yn;
    };

    TText.prototype.SetTextStyle = function(style){
        if (typeof style !== 'undefined' && style !== null)
        {
            var i;
            this.textStyle = [];
            for (i = 0;i < style.length;i++)
            {
                if (typeof style[i] !== 'undefined' && style[i] !== null)
                {
                    this.textStyle[i] = new String(style[i]);
                    if (this.textStyle[i] !== null)
                        this.textStyle[i] = this.textStyle[i].toString();
                }
            }
        }
    };

    TText.prototype.SetTextColour = function(colour_){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof colour_ !== 'undefined' && colour_ !== null && colour_.IsType('TColour'))
            this.colour = objM.copy(colour_);
    };
    
    TText.prototype.SetRotate = function(r){
        if (typeof r !== 'undefined' && r !== null && IsNumeric(r))
            this.rotate = r;
    };

}

TText.prototype = new TVisibleFigure();


function TTextFigure(){
    var type = 'TTextFigure';
    TTextFigure.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.marginX = 2;
        this.marginY = this.marginX;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TTextFigure.prototype.InitConstructor2 = function(){
        TVisibleFigure.prototype.InitConstructor2.call(this);
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            var text = objM.newObject('TText');
            this.AddChild(text,1);
        }
    };
        
    TTextFigure.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TTextFigure') && objM !== null)
        {
            if (typeof _object.marginX !== 'undefined' && _object.marginX !== null && IsNumeric(_object.marginX))
                this.marginX = _object.marginX;
            if (typeof _object.marginY !== 'undefined' && _object.marginY !== null && IsNumeric(_object.marginY))
                this.marginY = _object.marginY;
        }
    };


    TTextFigure.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TTextFigure.prototype.SetTextCoordinates = function(){
    };

    TTextFigure.prototype.CorrectTextCoordinate = function(){
    };


    TTextFigure.prototype.SetBackgroundColour = function(colour){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
            figure.SetBackgroundColour(colour);
    };
    
    TTextFigure.prototype.SetLineColour = function(colour){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
            figure.SetLineColour(colour);
    };
    
    TTextFigure.prototype.SetLineWidth = function(width_){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
            figure.SetLineWidth(width_);
    };

    TTextFigure.prototype.GetBackgroundColour = function(){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
            return figure.GetBackgroundColour();
        else
            return null;
    };
    
    TTextFigure.prototype.GetLineColour = function(){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
            return figure.GetLineColour();
        else
            return null;
    };
    
    TTextFigure.prototype.GetLineWidth = function(){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
            return figure.GetLineWidth();
        else
            return null;
    };

    TTextFigure.prototype.GetLineColour = function(colour){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
            figure.SetLineColour(colour);
    };

    TTextFigure.prototype.SetMarginX = function(margin){
        if (typeof margin !== 'undefined' && margin !== null && IsNumeric(margin))
        {
            this.marginX = margin;
            var text = this.GetChild(1);
            if (typeof text !== 'undefined' && text !== null && text.IsType('TText'))
            {
                var coord = this.CorrectTextCoordinate();
                text.SetCoordinates(coord);
            }
        }
    };

    TTextFigure.prototype.GetMarginX = function(){
        return this.marginX;
    };

    TTextFigure.prototype.SetMarginY = function(margin){
        if (typeof margin !== 'undefined' && margin !== null && IsNumeric(margin))
        {
            this.marginY = margin;
            var text = this.GetChild(1);
            if (typeof text !== 'undefined' && text !== null && text.IsType('TText'))
            {
                var coord = this.CorrectTextCoordinate();
                text.SetCoordinates(coord);
            }
        }
    };

    TTextFigure.prototype.GetMarginY = function(){
        return this.marginY;
    };

    TTextFigure.prototype.SetAlignmentX = function(alignment){
        var text = this.GetChild(1);
        if (typeof text !== 'undefined' && text !== null && text.IsType('TText'))
        {
            text.SetAlignmentX(alignment);
            var coord = this.CorrectTextCoordinate();
            text.SetCoordinates(coord);
        }
    };

    TTextFigure.prototype.GetAlignmentX = function(){
        var text = this.GetChild(1);
        if (typeof text !== 'undefined' && text !== null && text.IsType('TText'))
            return text.GetAlignmentX();
        else
            return null;
    };
    
    TTextFigure.prototype.SetAlignmentY = function(alignment){
        var text = this.GetChild(1);
        if (typeof text !== 'undefined' && text !== null && text.IsType('TText'))
        {
            text.SetAlignmentY(alignment);
            var coord = this.CorrectTextCoordinate();
            text.SetCoordinates(coord);
        }
    };

    TTextFigure.prototype.GetAlignmentY = function(){
        var text = this.GetChild(1);
        if (typeof text !== 'undefined' && text !== null && text.IsType('TText'))
            return text.GetAlignmentY();
        else
            return null;
    };

    TTextFigure.prototype.SetText = function(coordinates,text){
        TVisibleFigure.prototype.SetCoordinates.call(this,coordinates);
        var text_ = this.GetChild(1);
        var figure_ = this.GetChild(0);
        if (typeof text_ !== 'undefined' && text_ !== null && text_.IsType('TText'))
        {
            var objM = this.GetObjectManager();
            if (objM !== null)
            {
                var coord = this.CorrectTextCoordinate();
                text_.SetText(coord,text);
                if (figure_ !== null)
                {
                    coord.SetZeros(coord.GetN());
                    figure_.SetCoordinates(coord);
                }
            }
        }
    };

    TTextFigure.prototype.SetFontSize = function(size){
        //TODO: Implement Me 
        if (typeof size !== 'undefined' && size !== null && IsNumeric(size))
        {
            var text = this.GetChild(1);
            if (typeof text !== 'undefined' && text !== null && text.IsType('TText'))
                text.SetFontSize(size);
        }
    };
    
    TTextFigure.prototype.SetArea = function(typeInteractive){
        if (typeof typeInteractive === 'undefined' || typeInteractive === null)
            typeInteractive = 'Move';
        var objM = this.GetObjectManager();        
        if (objM !== null)
        {
            var area_ = null;        
            switch(typeInteractive)
            {
                case 'Move':
                case 'Connectors':
                    area_ = objM.newObject('TAreaRectangle');
                    if (area_ !== null)
                    {
//                        area_.SetCoordinates(this.GetCoordinates());
                        area_.SetWidth(this.GetWidth());
                        area_.SetHeight(this.GetHeight());
                        area_.SetParent(this);
                    }
                    break;
                case 'MoveAndResize':
                    area_ = objM.newObject('TAreaRectangleResize');
                    if (area_ !== null)
                    {
//                        area_.SetCoordinates(this.GetCoordinates());
                        area_.SetWidth(this.GetWidth());
                        area_.SetHeight(this.GetHeight());
                        area_.SetParent(this);
                    }
                    break;
            }
            return area_;
        }
        return null;
    };
    
    
/*   TTextFigure.prototype.InArea = function(coordinates){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
            return figure.InArea(coordinates);
        return null;
    };*/

    TTextFigure.prototype.TypeSelection = function(_type){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
            figure.TypeSelection(_type);
    };

    TTextFigure.prototype.GetText = function(){
        var text_ = this.GetChild(1);
        if (typeof text_ !== 'undefined' && text_ !== null && text_.IsType('TText'))
        {
            return text_.GetText();
        }
        return null;
    };

    TTextFigure.prototype.SetScaleTextYN = function(yn){
        var figure = this.GetChild(1);
        if (figure !== null && figure.IsType('TText'))
        {
            figure.SetScaleTextYN(yn);
        }
    };
    
    TTextFigure.prototype.SetLineType = function(type){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
        {
            figure.SetLineType(type);
        }
    };
    
    TTextFigure.prototype.SetBackgroundType = function(type){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TVisibleFigure'))
        {
            figure.SetBackgroundType(type);
        }
    };
    
    TTextFigure.prototype.SetTextStyle = function(style){
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TText'))
        {
            figure.SetTextStyle(style);
        }
    };


    TTextFigure.prototype.SetFontRelativeSize = function(size){
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TText'))
        {
            figure.SetFontRelativeSize(size);
        }
    };

    TTextFigure.prototype.SetTextColour = function(colour){
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TText'))
            figure.SetTextColour(colour);
    };

    TTextFigure.prototype.SetFont = function(font_){
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TText'))
            figure.SetFont(font_);
    };

}
TTextFigure.prototype = new TVisibleFigure();



function TTextRectangle(){
    var type = 'TTextRectangle';
    TTextRectangle.prototype.InitConstructor = function(){
        TTextFigure.prototype.InitConstructor.call(this);

        this.SetType(type);
            
    };
    this.InitConstructor();

    TTextRectangle.prototype.InitConstructor2 = function(){
        TTextFigure.prototype.InitConstructor2.call(this);
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            var figure = objM.newObject('TRectangle');
            this.AddChild(figure,0);
        }
    };


    TTextRectangle.prototype.Init = function(_object){
        //TODO: Implement Me 
        TTextFigure.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TTextRectangle') && objM !== null)
        {
        }
    };


    TTextRectangle.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TTextFigure.prototype.IsType.call(this,_type);
    };
    
    TTextRectangle.prototype.SetTextCoordinates = function(ctx){
        var objM = this.GetObjectManager();
        var figure = this.GetChild(0);
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext') && typeof figure !== 'undefined' && figure !== null && figure.IsType('TRectangle') && objM !== null)
        {
            var txt = this.GetText();
            var coord = objM.copy(this.GetCoordinates());
            if (typeof txt !== 'undefined' && txt !== null && typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector'))
            {
                var pos,tmp = this.GetAlignmentX(),margin = this.GetMarginX();
                if (typeof tmp !== 'undefined' && tmp !== null && typeof margin !== 'undefined' && margin !== null && IsNumeric(margin))
                {
                    var w = this.GetWidth();
                    var textWidth = ctx.GetTextWitdth(txt);
                    if (typeof w !== 'undefined' && w !== null && IsNumeric(w) && typeof textWidth !== 'undefined' && textWidth !== null && IsNumeric(textWidth))
                    {
                        switch(tmp)
                        {
                            case 'center':
//                                pos = 
                                break;
                        }
                    }
                }
            }
        }
    };

    TTextRectangle.prototype.CorrectTextCoordinate = function(){
        var objM = this.GetObjectManager();
        var coordinate = this.GetCoordinates();
        if (objM !== null && typeof coordinate !== 'undefined' && coordinate !== null && coordinate.IsType('TVector'))
        {
            coordinate.SetZeros(coordinate.GetN());
            var x = coordinate.GetCoordinate(0);
            if (typeof x !== 'undefined' && x !== null && IsNumeric(x))
            {
                switch(this.GetAlignmentX())
                {
                    case 'left':
                        x = x - this.GetWidth()/2 + this.GetMarginX();
                        break;
                    case 'right':
                        x = x + this.GetWidth()/2 - this.GetMarginX();
                        break;
                    default:
                        x = 0;
                }
                coordinate.SetCoordinate(0,x);
            }
            var y = coordinate.GetCoordinate(1);
            if (typeof y !== 'undefined' && y !== null && IsNumeric(y))
            {
                switch(this.GetAlignmentY())
                {
                    case 'top':
                    case 'hanging':
                        y = y - this.GetHeight()/2 + this.GetMarginY();
                        break;
                    case 'bottom':
                        y = y + this.GetHeight()/2 - this.GetMarginY();
                        break;
                    default:
                        y = 0;
                }
                coordinate.SetCoordinate(1,y);
            }
            return coordinate;
        }
        return null;
    };


    TTextRectangle.prototype.DrawFigure = function(ctx){
        TTextFigure.prototype.DrawFigure.call(this,ctx);
    };

    TTextRectangle.prototype.SetWidth = function(width_){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TRectangle'))
        {
            figure.SetWidth(width_);
            var text = this.GetChild(1);
            if (typeof text !== 'undefined' && text !== null && text.IsType('TText'))
            {
                text.SetMaxWidth(width_ - 2*this.GetMarginX());
            }    
        }
    };

    TTextRectangle.prototype.SetHeight = function(height_){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TRectangle'))
            figure.SetHeight(height_);
    };

    TTextRectangle.prototype.GetWidth = function(){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TRectangle'))
            return figure.GetWidth();
    };

    TTextRectangle.prototype.GetHeight = function(){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TRectangle'))
            return figure.GetHeight();
    };

    TTextRectangle.prototype.SetMarginX = function(margin){
        TTextFigure.prototype.SetMarginX.call(this,margin);
        var text = this.GetChild(1);
        if (typeof text !== 'undefined' && text !== null && text.IsType('TText'))
        {
            text.SetMaxWidth(this.GetWidth() - 2*this.GetMarginX());
        }    
    };

}

TTextRectangle.prototype = new TTextFigure();

/*function TSelection(){
    var type = 'TSelection';
    TSelection.prototype.InitConstructor = function(){
        TFigure.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TSelection.prototype.Init = function(_object){
        //TODO: Implement Me 
        TFigure.prototype.Init.call(this,_object);
    };


    TSelection.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TFigure.prototype.IsType.call(this,_type);
    };

}

TSelection.prototype = new TFigure();

function TSelectionRectnagleResize(){
    var type = 'TSelectionRectnagleResize';
    TSelectionRectnagleResize.prototype.InitConstructor = function(){
        TSelection.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TSelectionRectnagleResize.prototype.Init = function(_object){
        //TODO: Implement Me 
        TSelection.prototype.Init.call(this,_object);
//        TObject.Init(_object);
    };


    TSelectionRectnagleResize.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TSelection.prototype.IsType.call(this,_type);
    };

}

TSelectionRectnagleResize.prototype = new TSelection();
*/


function TDrawImage(){
    var type = 'TDrawImage';
    TDrawImage.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.wh = null;
        this.scale = 1;
        this.scaleTikZ=1; 
        this.fileName = null;
        this.alignX = 'left';
        this.alignY = 'top';
        this.img = null;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TDrawImage.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TDrawImage') && objM !== null)
        {
            if (typeof _object.wh !== 'undefined' && _object.wh !== null && _object.wh.IsType('TVector'))
                this.wh = objM.copy(_object.wh);            
            if (typeof _object.scale !== 'undefined' && _object.scale !== null && IsNumeric(_object.scale))
                this.scale = _object.scale;            
            if (typeof _object.fileName !== 'undefined' && _object.fileName !== null)
            {
                this.fileName = new String(_object.fileName);
                if (this.fileName !== null)
                    this.fileName = this.fileName.toString();
            }
            if (typeof _object.alignX !== 'undefined' && _object.alignX !== null)
            {
                this.alignX = new String(_object.alignX);
                if (this.alignX !== null)
                    this.alignX = this.alignX.toString();
            }
            if (typeof _object.alignY !== 'undefined' && _object.alignY !== null)
            {
                this.alignY = new String(_object.alignY);
                if (this.alignY !== null)
                    this.alignY = this.alignY.toString();
            }
            if (typeof _object.img !== 'undefined' && _object.img !== null)
                this.img = _object.img;
            if (typeof _object.scaleTikZ !== 'undefined' && _object.scaleTikZ !== null && IsNumeric(_object.scaleTikZ))
                this.scaleTikZ = _object.scaleTikZ;            
        }
    };


    TDrawImage.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TDrawImage.prototype.SetWidth = function(w){
        //TODO: Implement Me 
        if (typeof w !== 'undefined' && w !== null && IsNumeric(w) && this.wh !== null)
            this.wh.SetCoordinate(0,w);
    };

    TDrawImage.prototype.GetWidth = function(){
        if (this.wh !== null)
            return this.wh.GetCoordinate(0);
    };

    TDrawImage.prototype.SetHeight = function(h){
        //TODO: Implement Me 
        if (typeof h !== 'undefined' && h !== null && IsNumeric(h) && this.wh !== null)
            this.wh.SetCoordinate(1,h);
    };

    TDrawImage.prototype.GetHeight = function(){
        if (this.wh !== null)
            return this.wh.GetCoordinate(1);
    };

    TDrawImage.prototype.SetWidthHeight = function(wh_){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof wh_ !== 'undefined' && wh_ !== null && wh_.IsType('TVector'))
        {
            this.wh = objM.copy(wh_);
        }
        if (wh_ === null)
            this.wh_ = null;
    };

    TDrawImage.prototype.SetScale = function(s){
        //TODO: Implement Me 
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.scale = s;
    };

    TDrawImage.prototype.SetFileName = function(file){
        if (typeof file !== 'undefined' && file !== null)
        {
            this.fileName = new String(file);
            if (this.fileName !== null)
                this.fileName = this.fileName.toString();
        }
        if (file === null)
            this.fileName = null;
    };

    TDrawImage.prototype.DrawFigure = function(ctx){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
/*            var trans = this.GetTransformation();
            if (trans !== null)
            {
                var o = trans.CreateVector();
                if (o !== null)
                {
                    switch (o.GetType())
                    {
                        case 'TVector2DT':
                            ctx.DrawImage(this.fileName,this.GetVerticle(0),this.GetVerticle(1),this.scale,this.alignX,this.alignY,this.img);
                            break;
                        case 'TVector3DT':*/
            if (this.img !== null)
            { 
                ctx.DrawTableImage(this.GetVerticle(0),this.img);
            }else
                ctx.DrawImage(this.fileName,this.GetVerticle(0),this.GetVerticle(1),this.scaleTikZ,this.alignX,this.alignY,this.img);
/*                            break;
                    }
                }
            }*/
        }
    };

    TDrawImage.prototype.SetAlignX = function(align){
        if (typeof align !== 'undefined' && align !== null)
        {
            this.alignX = new String(align);
            if (this.alignX !== null)
                this.alignX = this.alignX.toString();
        }
    };

    TDrawImage.prototype.SetAlignY = function(align){
        if (typeof align !== 'undefined' && align !== null)
        {
            this.alignY = new String(align);
            if (this.alignY !== null)
                this.alignY = this.alignY.toString();
        }
    };

    TDrawImage.prototype.SetImage = function(img_){
        if (typeof img_ !== 'undefined' && img_ !== null)
        {
            this.img = img_;
        }
        if (img_ === null)
            this.img = null;
    };

    TDrawImage.prototype.SetScaleTikZ = function(s){
        //TODO: Implement Me 
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.scaleTikZ = s;
    };

}


TDrawImage.prototype = new TVisibleFigure();

function TFigureForeignObject(){
    var type = 'TFigureForeignObject';
    TFigureForeignObject.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.width = 0;
        this.height = 0;
        this.object = null;
        this.SetType(type);
        this.alignX = null;
        this.alignY = null;            
    };
    this.InitConstructor();

    TFigureForeignObject.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TFigureForeignObject') && objM !== null)
        {
            if (typeof _object.width !== 'undefined' && _object.width !== null && IsNumeric(_object.width))
                this.width = _object.width;            
            if (typeof _object.height !== 'undefined' && _object.height !== null && IsNumeric(_object.height))
                this.height = _object.height;            
            if (typeof _object.fileName !== 'undefined' && _object.fileName !== null)
            {
                this.object = new String(_object.object);
                if (this.object !== null)
                    this.object = this.object.toString();
            }
            if (typeof _object.alignX !== 'undefined' && _object.alignX !== null)
            {
                this.alignX = new String(_object.alignX);
                if (this.alignX !== null)
                    this.alignX = this.alignX.toString();
            }
            if (typeof _object.alignY !== 'undefined' && _object.alignY !== null)
            {
                this.alignY = new String(_object.alignY);
                if (this.alignY !== null)
                    this.alignY = this.alignY.toString();
            }
        }
    };


    TFigureForeignObject.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TFigureForeignObject.prototype.SetWidth = function(w){
        //TODO: Implement Me 
        if (typeof w !== 'undefined' && w !== null && IsNumeric(w))
            this.width = w;
    };

    TFigureForeignObject.prototype.GetWidth = function(){
        return this.width;
    };

    TFigureForeignObject.prototype.SetHeight = function(h){
        //TODO: Implement Me 
        if (typeof h !== 'undefined' && h !== null && IsNumeric(h))
            this.height = h;
    };

    TFigureForeignObject.prototype.GetHeight = function(){
        return this.height;
    };

    TFigureForeignObject.prototype.SetObject = function(txt){
        if (typeof txt !== 'undefined' && txt !== null)
        {
            this.object = new String(txt);
            if (this.object !== null)
                this.object = this.object.toString();
        }
        if (txt === null)
            this.object = null;
    };

    TFigureForeignObject.prototype.DrawFigure = function(ctx){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            var tmp = objM.copy(this.GetVerticle(0));
            if (tmp !== null && this.object !== null)
            {
                tmp.SetZeros(tmp.GetN());
                tmp.SetCoordinate(0,this.width);
                tmp.SetCoordinate(1,this.height);
                ctx.ForeignObject(this.GetVerticle(0),tmp,this.object,this.alignX,this.alignY);
            }

/*            var matrix = ctx.GetTransformation();
            if (typeof matrix !== 'undefined' && matrix !== null && matrix.IsType('TMatrixTransformation'))
            {
                if (matrix.IsType('TMatrixTransformation2D'))
                {
                    if (matrix.GetData(0) < 0)
                        matrix.SetData(0,-1);
                    else
                        matrix.SetData(0,1);
                    if (matrix.GetData(4) < 0)
                        matrix.SetData(4,-1);
                    else
                        matrix.SetData(4,1);
                }
                if (matrix.IsType('TMatrixTransformation3D'))
                {
                    if (matrix.GetData(0) < 0)
                        matrix.SetData(0,-1);
                    else
                        matrix.SetData(0,1);
                    if (matrix.GetData(5) < 0)
                        matrix.SetData(5,-1);
                    else
                        matrix.SetData(5,1);
                    if (matrix.GetData(10) < 0)
                        matrix.SetData(10,-1);
                    else
                        matrix.SetData(10,1);
                }
                ctx.SetTransformation(matrix);
            }*/
        }
    };

    TFigureForeignObject.prototype.SetAlignX = function(align){
        if (typeof align !== 'undefined' && align !== null)
        {
            this.alignX = new String(align);
            if (this.alignX !== null)
                this.alignX = this.alignX.toString();
        }
        if (align === null)
            this.alignX = null;
    };

    TFigureForeignObject.prototype.SetAlignY = function(align){
        if (typeof align !== 'undefined' && align !== null)
        {
            this.alignY = new String(align);
            if (this.alignY !== null)
                this.alignY = this.alignY.toString();
        }
        if (align === null)
            this.alignY = null;
    };
    
}

TFigureForeignObject.prototype = new TVisibleFigure();


function TAreaObject(){
    var type = 'TAreaObject';
    TAreaObject.prototype.InitConstructor = function(){
        TFigure.prototype.InitConstructor.call(this);
        
        this.coordinatesStart = null;
        this.transformation = null;
        this.invTransformation = null;
        this.selectionYN = false;
        this.noSelection = 0;
        this.typeSelection = '';
        this.SetType(type);
            
    };
    this.InitConstructor();

    TAreaObject.prototype.Init = function(_object){
        //TODO: Implement Me 
        TFigure.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TAreaObject') && objM !== null)
        {
            if (typeof _object.transformation !== 'undefined' && _object.transformation !== null)
                this.transformation = objM.copy(_object.transformation);
            if (typeof _object.invTransformation !== 'undefined' && _object.invTransformation !== null)
                this.invTransformation = objM.copy(_object.invTransformation);
            if (typeof _object.coordinatesStart !== 'undefined' && _object.coordinatesStart !== null)
                this.coordinatesStart = objM.copy(_object.coordinatesStart);
            if (typeof _object.selectionYN !== 'undefined' && _object.selectionYN !== null)
                this.selectionYN = _object.selectionYN;
            if (typeof _object.noSelection !== 'undefined' && _object.noSelection !== null && isNaN(_object.noSelection))
                this.noSelection = _object.noSelection;
            if (typeof _object.typeSelection !== 'undefined' && _object.typeSelection !== null)
            {
                this.typeSelection = new String(_object.typeSelection);
                if (this.typeSelection !== null)
                    this.typeSelection = this.typeSelection.toString();
            }            
        }
    };


    TAreaObject.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TFigure.prototype.IsType.call(this,_type);
    };

    TAreaObject.prototype.CalculateCoordinates = function(coordinates){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (typeof this.invTransformation !== 'undefined' && this.invTransformation !== null && this.invTransformation.IsType('TMatrixTransformation'))
            {
//                var table = [1,2,3,1,3,3,3,4,1];
//                this.transformation.SetMatrixTable(table,3,3);
//                var b = this.GetObjectManager().newObject('TMatrix');
//                b.SetMatrixTable([1,4,2],3,1);
//                var r = this.transformation.Inv();
                return this.invTransformation.MatrixVectorMultiplication(coordinates);
            }
            
        }
        return null;
    };
    
    TAreaObject.prototype.SetTransformation = function(matrix){
        var objM = this.GetObjectManager();
        if (typeof matrix !== 'undefined' && matrix !== null && matrix.IsType('TMatrixTransformation') && objM !== null)
        {
//            this.transformation = objM.copy(matrix);
            this.invTransformation = objM.copy(matrix);
            this.invTransformation.Inv();
        }
    };

    TAreaObject.prototype.InArea = function(coordinates){
        return false;
    };

    TAreaObject.prototype.TypeSelection = function(_type){
        if (typeof _type !== 'undefined' && _type !== null)
        {
            this.typeSelection = new String(_type);
            if (this.typeSelection !== null)
                this.typeSelection = this.typeSelection.toString();
        }else
            this.typeSelection = '';
    };

    TAreaObject.prototype.GetTypeSelection = function(){
        if (typeof this.typeSelection !== 'undefined' && this.typeSelection !== null)
        {
            var tmp = new String(this.typeSelection);
            if (tmp !== null)
                return tmp.toString();
        }
        return null;
    };

    TAreaObject.prototype.MouseEvent = function(coordinates,type_,servedYN){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (typeof coordinates === 'undefined' || coordinates === null)
                servedYN = false;
            var objM = this.GetObjectManager();
            if (objM !== null && typeof type_ !== 'undefined' && type_ !== null)
            {
                switch(type_)
                {
                    case 'LeftButtonDown':
                        if (!servedYN && this.InArea(coordinates))
                        {
                            this.coordinatesStart = objM.copy(coordinates);
                            return true;
                        }else
                            this.coordinatesStart = null;
                        break;
                    case 'LeftButtonUp':
                        if (this.coordinatesStart !== null)
                        {
                            var coord = objM.copy(this.coordinatesStart);
                            var coord2 = objM.newObject(coord.GetType());
                            coord2 = this.CalculateCoordinates(coord2);
                            coord.Subtraction(coordinates);
                            coord = this.CalculateCoordinates(coord);
                            coord2.Subtraction(coord);
/*                            var coord = objM.copy(coordinates);
                            coord.Subtraction(this.coordinatesStart);
                            coord = this.CalculateCoordinates(coord);
                            this.Move(coord);*/
                            this.coordinatesStart = null;
                        }
                        break;
                    case 'MouseMove':
                        if (this.coordinatesStart !== null)
                        {
                            var coord = objM.copy(this.coordinatesStart);
                            var coord2 = objM.newObject(coord.GetType());
                            coord2 = this.CalculateCoordinates(coord2);
                            coord.Subtraction(coordinates);
                            coord = this.CalculateCoordinates(coord);
                            coord2.Subtraction(coord);
                            this.Move(coord2);
                            this.coordinatesStart = objM.copy(coordinates);
                        }
                        break;
                }
                
            }
        }
        return servedYN;
    };

    TAreaObject.prototype.Move = function(coordinates){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (this.parent !== null && this.parent.IsType('TFigure'))
            {
                var coord = this.parent.GetCoordinates();
                if (coord !== null)
                {
                    coord.Addition(coordinates);
                    this.parent.SetCoordinates(coord);
                }
            }
        }
    };

    TAreaObject.prototype.SetSelection = function(selectYN){
        if (typeof selectYN !== 'undefined' && selectYN !== null)
        {
            this.selectionYN = selectYN;
        }else
            this.selectionYN = false;
    };

    TAreaObject.prototype.GetSelection = function(){
        return this.selectionYN;
    };

    TAreaObject.prototype.Draw = function(ctx){
        if (this.selectionYN)
            TFigure.prototype.Draw.call(this,ctx);
    };

}

TAreaObject.prototype = new TFigure();

function TAreaRectangle(){
    var type = 'TAreaRectangle';
    TAreaRectangle.prototype.InitConstructor = function(){
        TAreaObject.prototype.InitConstructor.call(this);
        
        this.width = 0;
        this.height = 0;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TAreaRectangle.prototype.Init = function(_object){
        //TODO: Implement Me 
        TAreaObject.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TAreaRectangle') && objM !== null)
        {
            if (typeof _object.width !== 'undefined' && _object.width !== null && IsNumeric(_object.width))
                this.width = _object.width;
            if (typeof _object.height !== 'undefined' && _object.height !== null && IsNumeric(_object.height))
                this.height = _object.height;
        }
    };


    TAreaRectangle.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TAreaObject.prototype.IsType.call(this,_type);
    };

    TAreaRectangle.prototype.SetWidth = function(width_){
        if (typeof width_ !== 'undefined' && width_ !== null && IsNumeric(width_))
        {
            this.width = width_;
        }
    };

    TAreaRectangle.prototype.SetHeight = function(height_){
        if (typeof height_ !== 'undefined' && height_ !== null && IsNumeric(height_))
        {
            this.height = height_;
        }
    };

    TAreaRectangle.prototype.InArea = function(coordinates){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            var coord = this.CalculateCoordinates(coordinates);
            if (typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector'))
            {
                var x = coord.GetCoordinate(0),y = coord.GetCoordinate(1);
                if (typeof x !== 'undefined' && x !== null && IsNumeric(x) && typeof y !== 'undefined' && y !== null && IsNumeric(y))
                {
                    if (this.width !== null && this.height !== null)
                    {
                        if (x >= -this.width/2 && x <= this.width/2)
                        {
                            if (y >= -this.height/2 && y <= this.height/2)
                                return true;
                        }
                    }
                }
            }
        }
        return false;
    };

}

TAreaRectangle.prototype = new TAreaObject();

function TPointSelected(){
    var type = 'TPointSelected';
    TPointSelected.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.selectionYN = false;
        this.coordinatesStart = null;
        this.typeSelected = '';
        this.typeFigure = 'Square';
        this.width = 15;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TPointSelected.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TPointSelected') && objM !== null)
        {
            if (typeof _object.typeSelected !== 'undefined' && _object.typeSelected !== null)
            {
                this.typeSelected = new String(_object.typeSelected);
                if (this.typeSelected !== null)
                    this.typeSelected.toString();
            }
            if (typeof _object.typeFigure !== 'undefined' && _object.typeFigure !== null)
            {
                this.typeFigure = new String(_object.typeFigure);
                if (this.typeFigure !== null)
                    this.typeFigure.toString();
            }
            if (typeof _object.selectionYN !== 'undefined' && _object.selectionYN !== null)
                this.selectionYN = _object.selectionYN;
            if (typeof _object.width !== 'undefined' && _object.width !== null && IsNumeric(_object.width))
                this.width = _object.width;
            if (typeof _object.coordinatesStart !== 'undefined' && _object.coordinatesStart !== null)
                this.coordinatesStart = objM.copy(_object.width);
        }
    };


    TPointSelected.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TPointSelected.prototype.NewPoint = function(){
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            var point;
            switch(this.typeFigure)
            {
                case 'Square':
                    point = objM.newObject('TRectangle');
                    if (point !== null)
                    {
                        point.SetWidth(this.width);
                        point.SetHeight(this.width);
                        var tmp = objM.newObject('TColourRGBA');
                        tmp.SetColourRGBA(0.10,0.10,0.90,0.5);
                        point.SetBackgroundColour(tmp);
                        tmp = objM.newObject('TColourRGBA');
                        tmp.SetColourRGBA(0,0,0,1);
                        point.SetLineColour(tmp);
                        point.SetLineWidth(1);
                        this.AddChild(point,0);
                        this.SetInteractive(true);
                    }
                    break;
            }
        }
    };
    
    TPointSelected.prototype.SetTypeSelected = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            this.typeSelected = new String(_type);
            if (this.typeSelected !== null)
            {
                this.typeSelected.toString();
                this.NewPoint();
            }
        }
    };

    TPointSelected.prototype.Draw = function(ctx){
        if (this.selectionYN)
        {
            var figure = this.GetChild(0);
            if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TRectangle'))
            {
                if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
                {
                    var scale_ = ctx.GetScale();
                    if (typeof scale_ !== 'undefined' && scale_ !== null && IsNumeric(scale_) && scale_ !== 0)
                    {
                        figure.SetWidth(this.width/scale_);
                        figure.SetHeight(this.width/scale_);
                        var area_ = this.GetArea();
                        if (typeof area_ !== 'undefined' && area_ !== null && area_.IsType('TAreaObject'))
                        {
                            area_.SetWidth(this.width/scale_);
                            area_.SetHeight(this.width/scale_);
                        }
                    }

                }
            }
            TVisibleFigure.prototype.Draw.call(this,ctx);        
        }
    };

    TPointSelected.prototype.MouseEvent = function(coordinates,type_,servedYN){
        var figure = this.GetChild(0);
        var objM = this.GetObjectManager();
        if (objM !== null && typeof figure !== 'undefined' && figure !== null && figure.IsType('TRectangle'))
        {
            var area_ = this.GetArea();
            if (typeof type_ !== 'undefined' && type_ !== null && typeof area_ !== 'undefined' && area_ !== null && area_.IsType('TAreaObject'))
            {
                switch(type_)
                {
                    case 'LeftButtonDown':
                        if (!servedYN)
                        {
                            var hit = this.InArea(coordinates);
                            if (hit.hit)
                            {
                                servedYN = true;
//                                this.coordinatesStart = area_.CalculateCoordinates(coordinates);
                                this.coordinatesStart = objM.copy(coordinates);
                            }else
                                this.coordinatesStart = null;
                        }
                        break;
                    case 'LeftButtonUp':
                        if (this.coordinatesStart !== null)
                        {
/*                            var coord = objM.copy(this.coordinatesStart);
                            var coord2 = objM.newObject(coord.GetType());
                            coord2 = area_.CalculateCoordinates(coord2);
                            coord.Subtraction(coordinates);
                            coord = area_.CalculateCoordinates(coord);
                            coord2.Subtraction(coord);*/
                            this.coordinatesStart = null;
                        }
                        break;
                    case 'MouseMove':
                        if (this.coordinatesStart !== null)
                        {
                            var coord = objM.copy(this.coordinatesStart);
                            var coord2 = objM.newObject(coord.GetType());
                            coord2 = area_.CalculateCoordinates(coord2);
                            coord.Subtraction(coordinates);
                            coord = area_.CalculateCoordinates(coord);
                            coord2.Subtraction(coord);
                            area_.Move(coord2);
                            this.coordinatesStart = objM.copy(coordinates);
                            if (this.parent !== null)
                                this.parent.Resize();
                        }
                        break;
 /*                   case 'MouseMove':
                    case 'LeftButtonUp':
                        if (this.coordinatesStart !== null)
                        {
                            var coord = area_.CalculateCoordinates(coordinates);
                            var coord2 = area_.CalculateCoordinates(coordinates);
//                            var coord = objM.copy(coordinates);
                            coord.Subtraction(this.coordinatesStart);
                            area_.Move(coord);
                            if (type_ === 'LeftButtonUp')
                                this.coordinatesStart  = null;
                            else
//                                this.coordinatesStart = objM.copy(coordinates);
                                this.coordinatesStart = objM.copy(coord2);
                        }
                        break;*/
                }
            }
        }
        return servedYN;
    };

    TPointSelected.prototype.SetArea = function(typeInteractive){
        var objM = this.GetObjectManager();        
        if (objM !== null)
        {
            var area_ = null;        
                area_ = objM.newObject('TAreaRectangle');
            if (area_ !== null)
            {
                area_.SetCoordinates(this.GetCoordinates());
                area_.SetWidth(this.width);
                area_.SetHeight(this.width);
                area_.SetParent(this);
            }
            return area_;
        }
        return null;
    };

    TPointSelected.prototype.SetSelection = function(selectYN){
        if (typeof selectYN !== 'undefined' && selectYN !== null)
        {
            this.selectionYN = selectYN;
        }else
            this.selectionYN = false;
    };

}

TPointSelected.prototype = new TVisibleFigure();


function TAreaObjectResize(){
    var type = 'TAreaObjectResize';
    TAreaObjectResize.prototype.InitConstructor = function(){
        TAreaObject.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TAreaObjectResize.prototype.Init = function(_object){
        //TODO: Implement Me 
        TAreaObject.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TAreaObjectResize') && objM !== null)
        {
        }
    };


    TAreaObjectResize.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TAreaObject.prototype.IsType.call(this,_type);
    };

    TAreaObjectResize.prototype.MouseEvent = function(coordinates,type_,servedYN){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            var i,n = this.GetNumberOfChilds(),child_,YN2 = servedYN,YN_pocz = servedYN;
            for (i = 0;i < n;i++)
            {
                child_ = this.GetChild(i);
                if (typeof child_ !== 'undefined' && child_ !== null && child_.IsType('TPointSelected'))
                    YN2 = child_.MouseEvent(coordinates,type_,YN2);
            }

            var YN = TAreaObject.prototype.MouseEvent.call(this,coordinates,type_,YN2);
            var objM = this.GetObjectManager();
            if (objM !== null && typeof type_ !== 'undefined' && type_ !== null)
            {
                switch(type_)
                {
                    case 'LeftButtonDown':
                        if (!servedYN && this.InArea(coordinates))
                        {
                            this.SetSelection(true);
                            return YN;
                        }
                        if (!YN2)
                            this.SetSelection(false);
                        if (YN_pocz)
                            this.SetSelection(false);
                        break;
                }
                
            }
        }
        return YN;
    };

    TAreaObjectResize.prototype.SetPoint = function(position,coordinates,type_){
        if (typeof position !== 'undefined' && position !== null && IsInt(position) && position >= 0)        
            if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
            {
                var objM = this.GetObjectManager();
                if (objM !== null)
                {
                    if (typeof type_ === 'undefined' || type_ === null)
                        type_ = 'Resize';
                    var point = objM.newObject('TPointSelected');
                    if(point !== null)
                    {
                        point.SetCoordinates(coordinates);
                        point.SetTypeSelected(type_);
                        point.SetParent(this);
                        point.SetSelection(true);
                        this.AddChild(point,position);
                    }
                }
            }  
    };

    TAreaObjectResize.prototype.Resize = function(){
    };
    
}

TAreaObjectResize.prototype = new TAreaObject();

function TAreaRectangleResize(){
    var type = 'TAreaRectangleResize';
    TAreaRectangleResize.prototype.InitConstructor = function(){
        TAreaObjectResize.prototype.InitConstructor.call(this);
        
        this.width = 0;
        this.height = 0;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TAreaRectangleResize.prototype.Init = function(_object){
        //TODO: Implement Me 
        TAreaObjectResize.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TAreaRectangle') && objM !== null)
        {
            if (typeof _object.width !== 'undefined' && _object.width !== null && IsNumeric(_object.width))
                this.width = _object.width;
            if (typeof _object.height !== 'undefined' && _object.height !== null && IsNumeric(_object.height))
                this.height = _object.height;
        }
    };


    TAreaRectangleResize.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TAreaObjectResize.prototype.IsType.call(this,_type);
    };

    TAreaRectangleResize.prototype.SetWidth = function(width_){
        var objM = this.GetObjectManager();
        if (typeof width_ !== 'undefined' && width_ !== null && IsNumeric(width_) && objM !== null)
        {
            this.width = width_;
            var coord = objM.newObject('TVector');
            if (coord !== null)
            {
                coord.SetCoordinate(0,-this.width/2);
                coord.SetCoordinate(1,-this.height/2);
                this.SetPoint(0,coord);
                coord.SetCoordinate(0,this.width/2);
                coord.SetCoordinate(1,this.height/2);
                this.SetPoint(1,coord);
            }
//            this.SetPoint(0,)
        }
    };

    TAreaRectangleResize.prototype.SetHeight = function(height_){
        var objM = this.GetObjectManager();
        if (typeof height_ !== 'undefined' && height_ !== null && IsNumeric(height_) && objM !== null)
        {
            this.height = height_;
            var coord = objM.newObject('TVector2DT');
            if (coord !== null)
            {
                coord.SetCoordinate(0,-this.width/2);
                coord.SetCoordinate(1,-this.height/2);
                this.SetPoint(0,coord);
                coord.SetCoordinate(0,this.width/2);
                coord.SetCoordinate(1,this.height/2);
                this.SetPoint(1,coord);
            }
        }
    };

    TAreaRectangleResize.prototype.InArea = function(coordinates){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            var coord = this.CalculateCoordinates(coordinates);
            if (typeof coord !== 'undefined' && coord !== null && coord.IsType('TVector'))
            {
                var x = coord.GetCoordinate(0),y = coord.GetCoordinate(1);
                if (typeof x !== 'undefined' && x !== null && IsNumeric(x) && typeof y !== 'undefined' && y !== null && IsNumeric(y))
                {
                    if (this.width !== null && this.height !== null)
                    {
                        if (x >= -this.width/2 && x <= this.width/2)
                        {
                            if (y >= -this.height/2 && y <= this.height/2)
                                return true;
                        }
                    }
                }
            }
        }
        return false;
    };

    TAreaRectangleResize.prototype.Resize = function(){
        var i,n = this.GetNumberOfChilds();
        if (n >= 1)
        {
            var maxX,maxY,minX,minY,startYN = true,p = [],pp,tmp3,ob = [];
            for (i = 0;i < n;i++)
            {
                ob[i] = this.GetChild(i);
                if (typeof ob[i] !== 'undefined' && ob[i] !== null && ob[i].IsType('TFigure'))
                {
                    p[i] = ob[i].GetCoordinates();
                    if (typeof p[i] !== 'undefined' && p[i] !== null && p[i].IsType('TVector') && p[i].GetN() >= 2)
                    {
                        if (startYN)
                        {
                            startYN = false;
                            maxX = p[i].GetCoordinate(0);
                            minX = maxX;
                            maxY = p[i].GetCoordinate(1);
                            minY = maxY;
                        }else
                        {
                            tmp3 = p[i].GetCoordinate(0);
                            if (tmp3 > maxX)
                                maxX = tmp3;
                            if (tmp3 < minX)
                                minX = tmp3;
                            tmp3 = p[i].GetCoordinate(1);
                            if (tmp3 > maxY)
                                maxY = tmp3;
                            if (tmp3 < minY)
                                minY = tmp3;
                        }
                    }
                }
            }
            if (!startYN)
            {
                if (this.parent !== null)
                {
//                    this.SetWidth(maxX-minX);
//                    this.SetHeight(maxY-minY);
                    this.parent.SetWidth(maxX-minX);
                    this.parent.SetHeight(maxY-minY);                    
                    pp = this.parent.GetCoordinates();
                    if (typeof pp !== 'undefined' && pp !== null && pp.IsType('TVector') && pp.GetN() >= 2)
                    {
                        
                        tmp3 = this.parent.GetCoordinates();
                        tmp3.SetCoordinate(0,(maxX+minX)/2);
                        tmp3.SetCoordinate(1,(maxY+minY)/2);
                        pp.Addition(tmp3);
//                    this.SetCoordinates(tmp2);
                        this.parent.SetCoordinates(pp);
//                        this.SetCoordinates(pp);
                        if (p[0] !== null && p[1] !== null)
                        {
                            if (p[0].GetCoordinate(0) > p[1].GetCoordinate(0))
                            {
                                p[0].SetCoordinate(0,(maxX-minX)/2);
                                p[1].SetCoordinate(0,-(maxX-minX)/2);
                            }else
                            {
                                p[1].SetCoordinate(0,(maxX-minX)/2);
                                p[0].SetCoordinate(0,-(maxX-minX)/2);                                
                            }
                            if (p[0].GetCoordinate(1) > p[1].GetCoordinate(1))
                            {
                                p[0].SetCoordinate(1,(maxY-minY)/2);
                                p[1].SetCoordinate(1,-(maxY-minY)/2);
                            }else
                            {
                                p[1].SetCoordinate(1,(maxY-minY)/2);
                                p[0].SetCoordinate(1,-(maxY-minY)/2);                                
                            }
                            ob[0].SetCoordinates(p[0]);
                            ob[1].SetCoordinates(p[1]);
                        }
                    }
                }
            }
        }
    };

    TAreaRectangleResize.prototype.MouseEvent = function(coordinates,type_,servedYN){
        var YN = TAreaObjectResize.prototype.MouseEvent.call(this,coordinates,type_,servedYN);

//        if (YN && !servedYN)
        {
            var objM = this.GetObjectManager();
            if (objM !== null && typeof type_ !== 'undefined' && type_ !== null && this.parent !== null)
            {
                switch(type_)
                {
                    case 'LeftButtonUp':
                        this.width = this.parent.GetWidth();
                        this.height = this.parent.GetHeight();
                        break;
                }
                
            }
        }
        return YN;
    };


}

TAreaRectangleResize.prototype = new TAreaObjectResize();

function TListFigure(){
    var type = 'TListFigure';
    TListFigure.prototype.InitConstructor = function(){
        TList.prototype.InitConstructor.call(this);
        
        this.SetType(type);
            
    };
    this.InitConstructor();

    TListFigure.prototype.Init = function(_object){
        //TODO: Implement Me 
        TList.prototype.Init.call(this,_object);
//        TObject.Init(_object);
/*        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TMatrixTransformation') && objM !== null)
        {
        }*/
    };


    TListFigure.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TList.prototype.IsType.call(this,_type);
    };

    TListFigure.prototype.Add = function(ob){
        if (typeof ob !== 'undefined' && ob !== null && ob.IsType('TFigure'))
            TList.prototype.Add.call(this,ob);        
    };

    TListFigure.prototype.GetData = function(){
        return TList.prototype.GetData.call(this);
    };

    TListFigure.prototype.Draw = function(ctx){
        var elem,object;
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
            for (elem = this.First();elem !== null;elem = this.Next())
            {
                if(elem !== null)
                {
                    object = elem.GetObject();
                    if (typeof object !== 'undefined' && object !== null && object.IsType('TVisibleFigure'))
                    {
                        object.Draw(ctx);
                    }
                }
            }
    };

    TListFigure.prototype.InArea = function(coordinates){
        var elem,object,result = null;
        for (elem = this.First();elem !== null;elem = this.Next())
        {
            if(elem !== null)
            {
                object = elem.GetObject();
                if (typeof object !== 'undefined' && object !== null && object.IsType('TVisibleFigure'))
                {
                    result = object.InArea(coordinates);
                    if (result !== null && result.hit)
                    {
                        return result;
                    }
                }
            }
        }
        return null;
    };

    TListFigure.prototype.MouseEvent = function(coordinates,type_,servedYN){
        var elem,object;
        for (elem = this.Last();elem !== null;elem = this.Previous())
        {
            if(elem !== null)
            {
                object = elem.GetObject();
                if (typeof object !== 'undefined' && object !== null && object.IsType('TVisibleFigure'))
                {
                    servedYN = object.MouseEvent(coordinates,type_,servedYN);
                }
            }
        }
        return servedYN;
    };

    TListFigure.prototype.TypeOfInteraction = function(type_){
        if (typeof type_ !== 'undefined' && type_ !== null)
        {
            var elem,object;
            for (elem = this.First();elem !== null;elem = this.Next())
            {
                if(elem !== null)
                {
                    object = elem.GetObject();
                    if (typeof object !== 'undefined' && object !== null && object.IsType('TVisibleFigure'))
                    {
                        object.TypeOfInteraction(type_);
                    }
                }
            }
        }
    };

    TListFigure.prototype.SetSelection = function(selectYN){
        if (typeof selectYN !== 'undefined' && selectYN !== null)
        {
            var elem,object;
            for (elem = this.First();elem !== null;elem = this.Next())
            {
                if(elem !== null)
                {
                    object = elem.GetObject();
                    if (typeof object !== 'undefined' && object !== null && object.IsType('TVisibleFigure'))
                    {
                        object.SetSelection(selectYN);
                    }
                }
            }
        }
    };

    TListFigure.prototype.SetSelectionFigureType = function(selectYN,type_){
        if (typeof selectYN !== 'undefined' && selectYN !== null && typeof type_ !== 'undefined' && type_ !== null)
        {
            var elem,object;
            for (elem = this.First();elem !== null;elem = this.Next())
            {
                if(elem !== null)
                {
                    object = elem.GetObject();
                    if (typeof object !== 'undefined' && object !== null && object.IsType('TVisibleFigure'))
                    {
                        if (object.IsType(type_))
                            object.SetSelection(selectYN);
                    }
                }
            }
        }
    };

    TListFigure.prototype.FindObjectGraphElement = function(code){
        var elem,object;
        if (typeof code !== 'undefined' && code !== null)
        {
            for (elem = this.First();elem !== null;elem = this.Next())
            {
                if(elem !== null)
                {
                    object = elem.GetObject();
                    if (typeof object !== 'undefined' && object !== null && object.IsType('TGraphElement'))
                    {
                        if (object.GetCode() === code)
                            return object;
                    }
                }
            }
        }
        return null;
    };

    TListFigure.prototype.FindObjectGraphConnector = function(code){
        var elem,object;
        if (typeof code !== 'undefined' && code !== null)
        {
            for (elem = this.First();elem !== null;elem = this.Next())
            {
                if(elem !== null)
                {
                    object = elem.GetObject();
                    if (typeof object !== 'undefined' && object !== null && object.IsType('TGraphConnector'))
                    {
                        if (object.GetCode() === code)
                            return object;
                    }
                }
            }
        }
        return null;
    };

}

TListFigure.prototype = new TList();


function TGraphElement(){
    var type = 'TGraphElement';
    TGraphElement.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.code = '';
        this.connectors = [];
        this.SetType(type);
            
    };
    this.InitConstructor();

    TGraphElement.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TGraphElement') && objM !== null)
        {
//            if (typeof _object.textFigure !== 'undefined' && _object.textFigure !== null)
//                this.textFigure = objM.copy(_object.textFigure);
            if (typeof _object.code !== 'undefined' && _object.code !== null)
            {
                if (_object.code !== null)
                {
                    this.code = new String(_object.code);
                    if (this.code !== null)
                        this.code = this.code.toString();
                }
/*                if (typeof _object.connectors !== 'undefined' && _object.connectors !== null && _object.connectors.length > 0)
                {
                    var i,n = _object.connectors.length;
                    this.connectors = [];
                    for (i = 0;i < n;i++)
                        this.connectors[i] = _object.connectors[i];                    
                }*/
            }
        }
    };


    TGraphElement.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TGraphElement.prototype.SetFigure = function(type,width,height){
        //TODO: Implement Me 
        if (typeof width !== 'undefined' && width !== null && IsNumeric(width) && typeof width !== 'undefined' && height !== null && IsNumeric(height))
        {
            if (typeof type !== 'undefined' && type !== null)
            {
                var objM = this.GetObjectManager();
                if (typeof objM !== 'undefined' && objM !== null)
                {
                    var figure;
                    switch(type)
                    {
                        case 'Rectangle':
                            figure = objM.newObject('TTextRectangle');
                            if (figure !== null)
                            {
                                figure.SetWidth(width);
                                figure.SetHeight(height);
                                figure.SetAlignmentX('center');
                                figure.SetAlignmentY('center');
                                figure.SetInteractive(true);
                                figure.TypeSelection('Move');
                                figure.SetParent(this);
                                this.AddChild(figure,0);
                            }
                            break;
                    }
                }
            }
        }


    };

    TGraphElement.prototype.SetBackgroundColour = function(colour){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour'))
            {
                figure.SetBackgroundColour(colour);
            }else
                figure.SetBackgroundColour(null);
        }
        TVisibleFigure.prototype.SetBackgroundColour.call(this,colour);
    };

    TGraphElement.prototype.SetLineColour = function(colour){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour'))
            {
                figure.SetLineColour(colour);
            }else
                figure.SetLineColour(null);
        }
        TVisibleFigure.prototype.SetLineColour.call(this,colour);
    };

    TGraphElement.prototype.SetLineWidth = function(width){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof width !== 'undefined' && width !== null && IsNumeric(width))
            {
                figure.SetLineWidth(width);
            }
        }
        TVisibleFigure.prototype.SetLineWidth.call(this,width);
    };

    TGraphElement.prototype.SetData = function(coordinates,text,code){
        //TODO: Implement Me 
        if (typeof text !== 'undefined' && text !== null && typeof code !== 'undefined' && code !== null)
        {
            this.code = code;
            var objM = this.GetObjectManager();
            if (typeof objM !== 'undefined' && objM !== null)
            {
                var figure = this.GetChild(0);
                if (figure !== null)
                    figure.SetText(coordinates,text);
            }
        }
    };

    TGraphElement.prototype.SetMarginX = function(margin){
        //TODO: Implement Me 
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
            if (typeof margin !== 'undefined' && margin !== null && IsNumeric(margin))
            {
                figure.SetMarginX(margin);
            }
    };

    TGraphElement.prototype.SetFontSize = function(size){
        //TODO: Implement Me 
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
            if (typeof size !== 'undefined' && size !== null && IsNumeric(size))
            {
                figure.SetFontSize(size);
            }
    };

//    TGraphElement.prototype.DrawFigure = function(ctx){
//        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
//        {
//            if (this.textFigure !== null)
//                this.textFigure.Draw(ctx);
//        }
//        
//    };

    TGraphElement.prototype.InArea = function(coordinates){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            var tmp = figure.InArea(coordinates);
            if (tmp !== null && tmp.IsType('THitObject'))
                tmp.objectParent = this;
            return tmp;
        }
        return null;
    };

    TGraphElement.prototype.MouseEvent = function(coordinates,type_,servedYN){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            return figure.MouseEvent(coordinates,type_,servedYN);
        }
        return servedYN;
    };

    TGraphElement.prototype.TypeOfInteraction = function(type_){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            figure.TypeOfInteraction(type_);
        }
    };

    TGraphElement.prototype.GetCoordinates = function(){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TFigure'))
        {
            return figure.GetCoordinates();
        }
        return null;
    };

    TGraphElement.prototype.SetConnector = function(connector){
        if (typeof connector !== 'undefined' && connector !== null && connector.IsType('TGraphConnector'))
        {
            this.connectors[this.connectors.length] = connector;
        }
    };

    TGraphElement.prototype.MoveChild = function(){
        var i;
        for (i = 0;i < this.connectors.length;i++)
        {
            if (this.connectors[i] !== null)
            {
                this.connectors[i].CalculateVertex();
            }
        }    
            
    };

    TGraphElement.prototype.GetCode = function(){
        var tmp = new String(this.code);
        if (typeof tmp !== 'undefined' && tmp !== null)
            return tmp.toString();
        else
            return null;
    };

    TGraphElement.prototype.GetText = function(){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            return figure.GetText();
        }
        return null;
    };
    
    TGraphElement.prototype.GetWidth = function(){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            return figure.GetWidth();
        }
        return null;
    };

    TGraphElement.prototype.GetHeight = function(){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            return figure.GetHeight();
        }
        return null;
    };

    TGraphElement.prototype.SetText = function(text){
        if (typeof text !== 'undefined' && text !== null)
        {
            var objM = this.GetObjectManager();
            if (typeof objM !== 'undefined' && objM !== null)
            {
                var figure = this.GetChild(0);
                if (figure !== null)
                {
                    var coordinates = figure.GetCoordinates();
                    figure.SetText(coordinates,text);
                }
            }
        }
    };

    TGraphElement.prototype.SetScaleTextYN = function(yn){
        var figure = this.GetChild(0);
        if (figure !== null && figure.IsType('TTextFigure'))
        {
            figure.SetScaleTextYN(yn);
        }
    };

    TGraphElement.prototype.SetLineType = function(type){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            figure.SetLineType(type);
        }
        TVisibleFigure.prototype.SetLineType.call(this,type);
    };

    TGraphElement.prototype.SetBackgroundType = function(type){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            figure.SetBackgroundType(type);
        }
        TVisibleFigure.prototype.SetBackgroundType.call(this,type);
    };

    TGraphElement.prototype.SetTextStyle = function(style){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            figure.SetTextStyle(style);
        }
    };

    TGraphElement.prototype.SetFontRelativeSize = function(size){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            figure.SetFontRelativeSize(size);
        }
    };

    TGraphElement.prototype.SetTextColour = function(colour){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour'))
            {
                figure.SetTextColour(colour);
            }else
                figure.SetTextColour(null);
        }
    };

    TGraphElement.prototype.SetFont = function(font_){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof font_ !== 'undefined' && font_ !== null)
            {
                figure.SetFont(font_);
            }
        }
    };

}

TGraphElement.prototype = new TVisibleFigure();


function TGraphConnector(){
    var type = 'TGraphConnector';
    TGraphConnector.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.invTransformation = null;
        this.coordinatesStart = null;
        this.shift = 0;
        this.begin = null;
        this.end = null;
        this.code = '';
        this.styleScaleTextYN = true;
        this.SetType(type);
        this.beginLength = 1;
        this.endLength = 1;
        this.coordText = null;
    };
    this.InitConstructor();

    TGraphConnector.prototype.Init = function(_object){
        //TODO: Implement Me 
        TVisibleFigure.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TGraphConnector') && objM !== null)
        {
            if (typeof _object.shift !== 'undefined' && _object.shift !== null && IsNumeric(_object.shift))
                this.shift = _object.shift;
            if (typeof _object.coordinatesStart !== 'undefined' && _object.coordinatesStart !== null)
                this.coordinatesStart = objM.copy(_object.coordinatesStart);
            if (typeof _object.invTransformation !== 'undefined' && _object.invTransformation !== null)
                this.invTransformation = objM.copy(_object.invTransformation);
            if (typeof _object.code !== 'undefined' && _object.code !== null)
            {
                this.code = new String(_object.code);
                if (this.code !== null)
                    this.code = this.code.toString();
            }
            if (typeof _object.styleScaleTextYN !== 'undefined' && _object.styleScaleTextYN !== null)
                this.styleScaleTextYN = _object.styleScaleTextYN;
//            if (typeof _object.begin !== 'undefined' && _object.begin !== null && _object.begin.IsType('TGraphElement'))
//                this.begin = _object.begin;
//            if (typeof _object.end !== 'undefined' && _object.end !== null && _object.end.IsType('TGraphElement'))
//                this.end = _object.end;
            if (typeof _object.beginLength !== 'undefined' && _object.beginLength !== null && IsNumeric(_object.beginLength))
                this.beginLength = _object.beginLength;
            if (typeof _object.endLength !== 'undefined' && _object.endLength !== null && IsNumeric(_object.endLength))
                this.endLength = _object.endLength;
            if (typeof _object.coordText !== 'undefined' && _object.coordText !== null && _object.coordText.IsType('TVector'))
                this.coordText = objM.copy(_object.coordText);
        }
    };

    TGraphConnector.prototype.InitConstructor2 = function(){
        TVisibleFigure.prototype.InitConstructor2.call(this);
        var objM = this.GetObjectManager();
        if (objM !== null)
        {
            var line = objM.newObject('TRationalBezierCurve');
            if (line !== null)
            {
                var tmp = objM.newObject('TColourRGBA');
                tmp.SetColourRGBA(0,0,0,1);
                line.SetLineColour(tmp);
                line.SetLineWidth(2);
                this.AddChild(line,0);
            }
        }
    };


    TGraphConnector.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };
    
    TGraphConnector.prototype.CalculateVertex = function(){        
        var line = this.GetChild(0);
        var objM = this.GetObjectManager();
        if (line !== null && objM !== null)
        {
            var P0 = null,P2 = null,dif;
            if (typeof this.begin !== 'undefined' && this.begin !== null && this.begin.IsType('TGraphElement'))
            {
                P0 = this.begin.GetCoordinates();
                if (P0 !== null)
                {
                    line.SetVerticle(0,P0);
                }
            }
            if (typeof this.end !== 'undefined' && this.end !== null && this.end.IsType('TGraphElement'))
            {
                P2 = this.end.GetCoordinates();
                if (P2 !== null)
                {
                    line.SetVerticle(2,P2);
                }
            }
            if (P0 !== null && P2 !== null)
            {
                dif = this.CalculateP1(this.shift);
                if (dif !== null)
                {
                    var text = this.GetChild(1);
                    if (text !== null && text.IsType('TTextFigure'))
                    {
                        var P = line.GetVerticle(1);
                        var dif_ = objM.copy(dif);
                        dif_.Subtraction(P);
                        var coord = text.GetCoordinates();
                        coord.Addition(dif_);
                        text.SetCoordinates(coord);
                    }
                    line.SetVerticle(1,dif);
                    var tmp = objM.newObject('TPointSelected');
                    tmp.SetCoordinates(dif);
                    tmp.SetTypeSelected('Square');
                    tmp.SetParent(this);
                    this.AddChild(tmp,2);
                }
                this.CalculateP0P2();
                line.SetBeginLength(this.beginLength);
                line.SetEndLength(this.endLength);
//                line.SetArrow('TArrowTriangle',false);
            }
        }
    };
    
    TGraphConnector.prototype.CalculateP1 = function(shift_){
        if(typeof shift_ !== 'undefined' && shift_ !== null && IsNumeric(shift_))
        {
            var line = this.GetChild(0);
            var objM = this.GetObjectManager();
            if (line !== null && objM !== null)
            {
                var P0 = null,P1a,P1b,P1c,P2 = null,dif;
                var x0 = null,y0 = null;
                if (typeof this.begin !== 'undefined' && this.begin !== null && this.begin.IsType('TGraphElement'))
                {
                    P0 = this.begin.GetCoordinates();
                }
                if (typeof this.end !== 'undefined' && this.end !== null && this.end.IsType('TGraphElement'))
                {
                    P2 = this.end.GetCoordinates();
                }
                if (P0 !== null && P2 !== null)
                {
                    P1a = objM.copy(P2);
                    P1a.Subtraction(P0);
                    P1a.MultiplicationScalar(0.5);
                    x0 = P1a.GetCoordinate(0);
                    y0 = P1a.GetCoordinate(1);
                    if (x0 !== 0 || y0 !== 0)
                    {
                        P1b = objM.newObject(P1a.GetType());
                        if (x0 > 0 && y0 > 0)
                        {
                            P1b.SetCoordinate(0,x0);
                            P1b.SetCoordinate(1,-y0);
                        }
                        if (x0 === 0 && y0 > 0)
                        {
                            P1b.SetCoordinate(0,y0);
                            P1b.SetCoordinate(1,0);
                        }
                        if (x0 > 0 && y0 < 0)
                        {
                            P1b.SetCoordinate(0,-x0);
                            P1b.SetCoordinate(1,y0);
                        }
                        if (x0 > 0 && y0 === 0)
                        {
                            P1b.SetCoordinate(0,0);
                            P1b.SetCoordinate(1,-x0);
                        }
                        if (x0 < 0 && y0 < 0)
                        {
                            P1b.SetCoordinate(0,x0);
                            P1b.SetCoordinate(1,-y0);
                        }
                        if (x0 === 0 && y0 < 0)
                        {
                            P1b.SetCoordinate(0,y0);
                            P1b.SetCoordinate(1,0);
                        }
                        if (x0 < 0 && y0 > 0)
                        {
                            P1b.SetCoordinate(0,-x0);
                            P1b.SetCoordinate(1,y0);
                        }
                        if (x0 < 0 && y0 === 0)
                        {
                            P1b.SetCoordinate(0,0);
                            P1b.SetCoordinate(1,-x0);
                        }
                        if (P1a.ScalarProduct(P1b) === 0)
                        {
                            dif = objM.copy(P1b);
                        }else
                        {
                            var c = P1a.VectorComponent(P1b);
                            P1c = objM.copy(P1a);
                            P1c.MultiplicationScalar(c);
                            dif = objM.copy(P1b);
                            dif.Subtraction(P1c);
                        }
                        var norm = dif.Norm();
    //                    dif.MultiplicationScalar(25/norm);
                        dif.MultiplicationScalar(shift_/norm);
                        dif.Addition(P0);                    
                        dif.Addition(P1a);
                        return dif;
                    }
                }
            }
        }
        return null;
    };
    
    TGraphConnector.prototype.Move = function(coordinates){        
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            var figure = this.GetChild(2);
            if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TPointSelected'))
            {
                var area_ = figure.GetArea();
                var line = this.GetChild(0);
                if (line !== null && area_  !== null)
                {
//                    var P1 = line.GetVerticle(1);
                    var P1_ = this.CalculateP1(10),P0,P2,P1a;
                    var objM = this.GetObjectManager();
                    if (P1_ !== null && objM !== null)
                    {
                        if (typeof this.begin !== 'undefined' && this.begin !== null && this.begin.IsType('TGraphElement'))
                            P0 = this.begin.GetCoordinates();
                        if (typeof this.end !== 'undefined' && this.end !== null && this.end.IsType('TGraphElement'))
                            P2 = this.end.GetCoordinates();
                        if (P0 !== null && P2 !== null)
                        {
                            P1a = objM.copy(P2);
                            P1a.Addition(P0);
                            P1a.MultiplicationScalar(0.5);
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!
                            var coordP1a = this.CalculateCoordinates(coordinates);
                            if (coordP1a === null)
                                return;
                            coordP1a.Subtraction(P1a);
                            var P1_P1a = objM.copy(P1_);
                            P1_P1a.Subtraction(P1a);
                            var norm = P1_P1a.Norm();
                            P1_P1a.MultiplicationScalar(1/norm);
                            this.shift = P1_P1a.VectorComponent(coordP1a);
                            this.CalculateVertex();
                            this.SetSelection(true);
//                            P1_P1a.MultiplicationScalar(c);
//                            var P1 = objM.copy(P1a);
//                            P1.Addition(P1_P1a);
//                            line.SetVerticle(1,P1);
//                            figure.SetCoordinates(P1);
                        }
                        
                        
//                        P1.Addition(coordinates);
//                        line.SetVerticle(1,P1);
//                        figure.SetCoordinates(P1);
                    }
                }
            }            
        }
    };    
    
    TGraphConnector.prototype.LineCalculate_a = function(P0,P1){
        //TODO: Implement Me 
        if (typeof P0 !== 'undefined' && P0 !== null && (P0.IsType('TVector2DT') || P0.IsType('TVector3DT')))
        {
            if (typeof P1 !== 'undefined' && P1 !== null && (P1.IsType('TVector2DT') || P0.IsType('TVector3DT')))
            {
                var x0 = P0.GetCoordinate(0);
                var y0 = P0.GetCoordinate(1);
                var x1 = P1.GetCoordinate(0);
                var y1 = P1.GetCoordinate(1);
                var a = (y1-y0)/(x1-x0);
                return a;
            }
        }
    };

    TGraphConnector.prototype.LineCalculate_b = function(P,a){
        //TODO: Implement Me 
        if (typeof P !== 'undefined' && P !== null && (P.IsType('TVector2DT') || P.IsType('TVector3DT')))
        {
            if (typeof a !== 'undefined' && a !== null && IsNumeric(a))
            {
                var x = P.GetCoordinate(0);
                var y = P.GetCoordinate(1);
                var b = y-a*x;
                return b;
            }
        }
    };

    TGraphConnector.prototype.CalculateP0OrP2Rectangle = function(beginYN){
        //TODO: Implement Me 
        var objM = this.GetObjectManager();
        if (objM !== null && typeof beginYN !== 'undefined' && beginYN !== null)
        {
            var P0 = null,P2 = null;
            if (typeof this.begin !== 'undefined' && this.begin !== null && this.begin.IsType('TGraphElement'))
            {
                if (beginYN)
                    P0 = this.begin.GetCoordinates();
            }
            if (typeof this.end !== 'undefined' && this.end !== null && this.end.IsType('TGraphElement'))
            {
                if (!beginYN)
                    P0 = this.end.GetCoordinates();
            }
            var line = this.GetChild(0);
            if (line !== null)
            {
                P2 = line.GetVerticle(1);
            }
            if (P0 !== null && P2 !== null)
            {
                var figure;
                if (beginYN)
                    figure = this.begin.GetChild(0);
                else
                    figure = this.end.GetChild(0);
                if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextRectangle'))
                {
                    var w = figure.GetWidth();
                    var h = figure.GetHeight();
                    var rP = objM.newObject(P0.GetType());
                    if (w !== null && h !== null && rP !== null)
                    {
                        var x0 = P0.GetCoordinate(0);
                        var y0 = P0.GetCoordinate(1);
                        var x2 = P2.GetCoordinate(0);
                        var y2 = P2.GetCoordinate(1);
                        var xv0,yv0,xv1,yv1,xv2,yv2,xv3,yv3;
                        xv0 = x0-w/2,yv0 = y0-h/2;
                        xv1 = x0+w/2,yv1 = y0-h/2;
                        xv2 = x0+w/2,yv2 = y0+h/2;
                        xv3 = x0-w/2,yv3 = y0+h/2;
                        if (x0 === x2 && y0 === y2)
                            return null;
                        if (x0 === x2)
                        {
                            rP.SetCoordinate(0,x0);
                            if (Math.abs(yv0-y2) < Math.abs(yv2-y2))
                                rP.SetCoordinate(1,yv0);
                            else
                                rP.SetCoordinate(1,yv2);
                            return rP;
                        }
                        if (y0 === y2)
                        {
                            rP.SetCoordinate(1,y0);
                            if (Math.abs(xv0-x2) < Math.abs(xv2-x2))
                                rP.SetCoordinate(0,xv0);
                            else
                                rP.SetCoordinate(0,xv2);
                            return rP;
                        }
                        if (x0 !== x2 && y0 !== y2)
                        {
                            var a = this.LineCalculate_a(P0,P2);
                            var b = this.LineCalculate_b(P0,a);
                            var rP0 = objM.newObject(rP.GetType());
                            var rP1 = objM.newObject(rP.GetType());
                            var rP2 = objM.newObject(rP.GetType());
                            var rP3 = objM.newObject(rP.GetType());
                            if (a !== null && b !== null && rP0 !== null && rP1 !== null&& rP2 !== null && rP3 !== null)
                            {
                                var tmp = (yv0 - b)/a;
                                
                                if (tmp >= xv0 && tmp <= xv1)
                                {
                                    rP0.SetCoordinate(0,tmp);
                                    rP0.SetCoordinate(1,yv0);
                                    var d0 = P2.Distance(rP0);
                                    
                                    rP2.SetCoordinate(0,(yv2 - b)/a);
                                    rP2.SetCoordinate(1,yv2);
                                    var d2 = P2.Distance(rP2);
                                    if (d0 < d2)
                                        return rP0;
                                    else
                                        return rP2;
                                }
                                
                                tmp = a*xv1 + b;
                                
                                if (tmp >= yv1 && tmp <= yv2)
                                {
                                    rP1.SetCoordinate(0,xv1);
                                    rP1.SetCoordinate(1,tmp);
                                    var d1 = P2.Distance(rP1);

                                    rP3.SetCoordinate(0,xv3);
                                    rP3.SetCoordinate(1,a*xv3 + b);
                                    var d3 = P2.Distance(rP3);
                                    if (d1 < d3)
                                        return rP1;
                                    else
                                        return rP3;
                                }
                                
                            }                            
                        }
                    }
                }
            }
        }
        return null;
    };

    TGraphConnector.prototype.CalculateP0P2Rectangle = function(){
        var line = this.GetChild(0);
        if (line !== null)
        {
            var P0 = this.CalculateP0OrP2Rectangle(true);
            if (P0 !== null)
                line.SetVerticle(0,P0);
            var P2 = this.CalculateP0OrP2Rectangle(false);
            if (P2 !== null)
                line.SetVerticle(2,P2);
        }
    };
    
    TGraphConnector.prototype.CalculateP0P2 = function(){
        this.CalculateP0P2Rectangle();
    };
    
    TGraphConnector.prototype.SetBegin = function(begin_){
        //TODO: Implement Me 
        if (typeof begin_ !== 'undefined' && begin_ !== null && begin_.IsType('TGraphElement'))
        {
            this.begin = begin_;
            this.CalculateVertex();
            begin_.SetConnector(this);
        }
    };

    TGraphConnector.prototype.SetEnd = function(end_){
        //TODO: Implement Me 
        if (typeof end_ !== 'undefined' && end_ !== null && end_.IsType('TGraphElement'))
        {
            this.end = end_;
            this.CalculateVertex();
            end_.SetConnector(this);
        }
    };

    TGraphConnector.prototype.MouseEvent = function(coordinates,type_,servedYN){
        var figure = this.GetChild(2);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TPointSelected'))
        {
            if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector2DT'))
            {
                var objM = this.GetObjectManager();
                if (objM !== null && typeof type_ !== 'undefined' && type_ !== null)
                {
                    switch (type_)
                    {
                        case 'LeftButtonDownConnectors':
                            if (!servedYN)
                            {
                                var hit = figure.InArea(coordinates);
                                if (hit !== null && hit.hit)
                                {
                                    this.coordinatesStart = objM.copy(coordinates);
                                    return true;
                                }
                            }
                            this.coordinatesStart = null;
                            break;
                        case 'LeftButtonUpConnectors':
                            this.coordinatesStart = null;
                            break;
                        case 'MouseMoveConnectors':
                            if (this.coordinatesStart !== null)
                            {
                                var coord = objM.copy(coordinates);
//                                coord.Subtraction(this.coordinatesStart);
                                this.Move(coord);
                                this.coordinatesStart = objM.copy(coordinates);
                            }
                            break;
                    }
                }
            }
//            return figure.MouseEvent(coordinates,type_,servedYN);
        }
        if (!servedYN)
        {
            var figure = this.GetChild(1);
            if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
            {
                return figure.MouseEvent(coordinates,type_,servedYN);
            }            
        }
        return servedYN;
    };


    TGraphConnector.prototype.SetSelection = function(selectYN){
        var figure = this.GetChild(2);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TPointSelected'))
        {
            figure.SetSelection(selectYN);
        }
    };

    TGraphConnector.prototype.SetTransformation = function(matrix){
        var objM = this.GetObjectManager();
        if (typeof matrix !== 'undefined' && matrix !== null && matrix.IsType('TMatrixTransformation') && objM !== null)
        {
//            this.transformation = objM.copy(matrix);
            this.invTransformation = objM.copy(matrix);
            this.invTransformation.Inv();
        }
    };
    TGraphConnector.prototype.DrawFigure = function(ctx){
        if (typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            this.SetTransformation(ctx.GetTransformation());
            TVisibleFigure.prototype.DrawFigure.call(this,ctx);
        }
    };

    TGraphConnector.prototype.CalculateCoordinates = function(coordinates){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (typeof this.invTransformation !== 'undefined' && this.invTransformation !== null && this.invTransformation.IsType('TMatrixTransformation'))
            {
                return this.invTransformation.MatrixVectorMultiplication(coordinates);
            }
            
        }
        return null;
    };

    TGraphConnector.prototype.SetText = function(text){
        var objM = this.GetObjectManager();
        if (typeof text !== 'undefined' && text !== null && objM !== null)
        {
            var figure = objM.newObject('TTextRectangle');
            if (figure !== null)
            {
                figure.SetScaleTextYN(this.styleScaleTextYN);
                figure.SetWidth(75);
                figure.SetHeight(50);
                figure.SetAlignmentX('center');
                figure.SetAlignmentY('center');
                figure.SetInteractive(true);
                figure.TypeSelection('Move');
                figure.SetParent(this);
                var line = this.GetChild(0);
                if (line !== null && line.IsType('TLine'))
                {
                    var P = line.GetVerticle(1);
                    if (P !== null && P.IsType('TVector'))
                        figure.SetText(P,text);
                }
                this.AddChild(figure,1);
            }
        }
    };

    TGraphConnector.prototype.InArea = function(coordinates){
        var hit = TVisibleFigure.prototype.InArea.call(this,coordinates);
        if (hit !== null && !hit.hit)
        {
            var figure = this.GetChild(1);
            if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
            {
                var tmp = figure.InArea(coordinates);
                if (tmp !== null && tmp.IsType('THitObject'))
                    tmp.objectParent = this;
                return tmp;
            }
        }
        return hit;
    };

    TGraphConnector.prototype.TypeOfInteraction = function(type_){
        TVisibleFigure.prototype.TypeOfInteraction.call(this,type_);
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            figure.TypeOfInteraction(type_);
        }
    };

    TGraphConnector.prototype.GetShift = function(){
        return this.shift;
    };

    TGraphConnector.prototype.SetShift = function(_shift){
        if (typeof _shift !== 'undefined' && _shift !== null)
        {
            this.shift = _shift;
            this.CalculateVertex();
        }
    };

    TGraphConnector.prototype.SetCode = function(_code){
        if (typeof _code !== 'undefined' && _code !== null)
        {
            var tmp = new String(_code);
            if (typeof tmp !== 'undefined' && tmp !== null)
                this.code = tmp.toString();
        }
    };

    TGraphConnector.prototype.GetCode = function(){
        var tmp = new String(this.code);
        if (typeof tmp !== 'undefined' && tmp !== null)
            return tmp.toString();
        else
            return null;
    };
    
    TGraphConnector.prototype.GetTextCoordinates = function(){
        var figure = this.GetChild(1);
        if (figure !== null)
        {
            return figure.GetCoordinates();
        }
        return null;
    };

    TGraphConnector.prototype.SetTextCoordinates = function(coord){
        var figure = this.GetChild(1);
        var objM = this.GetObjectManager();
        if (figure !== null && objM !== null)
        {
            var tmp = objM.copy(figure.GetCoordinates());
            if (tmp !== null)
            {
//                if (this.coordText !== null)
//                    this.coordText.Addition(coord);
//                else
//                    this.coordText = objM.copy(coord);
//                tmp.Addition(this.coordText);
                tmp.Addition(coord);
                this.coordText = objM.copy(coord);
                return figure.SetCoordinates(tmp);
            }
        }
        return null;
    };

    TGraphConnector.prototype.SetLineWidth = function(_width){
        var figure = this.GetChild(0);
        if (figure !== null)
        {
            return figure.SetLineWidth(_width);
        }
    };

    TGraphConnector.prototype.SetScaleTextYN = function(yn){
        var figure = this.GetChild(1);
        if (figure !== null && figure.IsType('TTextFigure'))
        {
            figure.SetScaleTextYN(yn);
            this.styleScaleTextYN = yn;
        }
    };

    TGraphConnector.prototype.SetBeginLength = function(l)
    {
        if (typeof l !== 'undefined' && l !== null && IsNumeric(l))
        {
            if (l > 1)
                l = 1;
            if (l < 0)
                l = 0;
            
            this.beginLength = l;
        }
    };

    TGraphConnector.prototype.SetEndLength = function(l)
    {
        if (typeof l !== 'undefined' && l !== null && IsNumeric(l))
        {
            if (l > 1)
                l = 1;
            if (l < 0)
                l = 0;

            this.endLength = l;
        }
    };

    
    TGraphConnector.prototype.SetNVerticles = function(n){
        var lineBezier = this.GetChild(0);
        if (typeof lineBezier !== 'undefined' && lineBezier !== null && lineBezier.IsType('TRationalBezierCurve'))
        {
            lineBezier.SetNVerticles(n);
        }
    };

    TGraphConnector.prototype.SetArrow = function(arrow_,beginYN){
        var lineBezier = this.GetChild(0);
        if (typeof lineBezier !== 'undefined' && lineBezier !== null && lineBezier.IsType('TLine'))
        {
            switch(arrow_)
            {   
                case 'ArrowTriangle':
                    lineBezier.SetArrow('TArrowTriangle',beginYN);
                    break;
            }
        }
    };

    TGraphConnector.prototype.SetLineColour = function(colour){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TLine'))
        {
            if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour'))
            {
                figure.SetLineColour(colour);
            }else
                figure.SetLineColour(null);
        }
        TVisibleFigure.prototype.SetLineColour.call(this,colour);
    };

    TGraphConnector.prototype.SetTextColour = function(colour){
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof colour !== 'undefined' && colour !== null && colour.IsType('TColour'))
            {
                figure.SetTextColour(colour);
            }else
                figure.SetTextColour(null);
        }
    };

    TGraphConnector.prototype.SetTextStyle = function(style){
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof style !== 'undefined' && style !== null)
            {
                figure.SetTextStyle(style);
            }
        }
    };

    TGraphConnector.prototype.SetFontRelativeSize = function(size){
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof size !== 'undefined' && size !== null)
            {
                figure.SetFontRelativeSize(size);
            }
        }
    };

    TGraphConnector.prototype.SetAlignmentX = function(alignment){
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof alignment !== 'undefined' && alignment !== null)
            {
                figure.SetAlignmentX(alignment);
            }
        }
    };

    TGraphConnector.prototype.SetAlignmentY = function(alignment){
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof alignment !== 'undefined' && alignment !== null)
            {
                figure.SetAlignmentY(alignment);
            }
        }
    };

    TGraphConnector.prototype.SetLineType = function(type){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TLine'))
        {
            figure.SetLineType(type);
        }
        TVisibleFigure.prototype.SetLineType.call(this,type);
    };

    TGraphConnector.prototype.SetBeginArrowWidth = function(value){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TLine'))
        {
            if (typeof value !== 'undefined' && value !== null && IsNumeric(value))
            {
                figure.SetBeginArrowWidth(value);
            }
        }
    };

    TGraphConnector.prototype.SetBeginArrowHeight = function(value){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TLine'))
        {
            if (typeof value !== 'undefined' && value !== null && IsNumeric(value))
            {
                figure.SetBeginArrowHeight(value);
            }
        }
    };

    TGraphConnector.prototype.SetEndArrowWidth = function(value){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TLine'))
        {
            if (typeof value !== 'undefined' && value !== null && IsNumeric(value))
            {
                figure.SetEndArrowWidth(value);
            }
        }
    };

    TGraphConnector.prototype.SetEndArrowHeight = function(value){
        var figure = this.GetChild(0);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TLine'))
        {
            if (typeof value !== 'undefined' && value !== null && IsNumeric(value))
            {
                figure.SetEndArrowHeight(value);
            }
        }
    };

    TGraphConnector.prototype.SetFont = function(font_){
        var figure = this.GetChild(1);
        if (typeof figure !== 'undefined' && figure !== null && figure.IsType('TTextFigure'))
        {
            if (typeof font_ !== 'undefined' && font_ !== null)
            {
                figure.SetFont(font_);
            }
        }
    };

    TGraphConnector.prototype.ReloadCoordinateText = function(){
        var figure = this.GetChild(1);
        var objM = this.GetObjectManager();
        if (figure !== null && objM !== null)
        {
            var tmp = objM.copy(figure.GetCoordinates());
            if (tmp !== null)
            {
//                if (this.coordText !== null)
//                    this.coordText.Addition(coord);
//                else
//                    this.coordText = objM.copy(coord);
//                tmp.Addition(this.coordText);
                tmp.Addition(this.coordText);
                return figure.SetCoordinates(tmp);
            }
        }
        return null;
    };


}



TGraphConnector.prototype = new TVisibleFigure();


function TGraph(){
    var type = 'TGraph';
    TGraph.prototype.InitConstructor = function(){
        TObject.prototype.InitConstructor.call(this);
        
        var objM = this.GetObjectManager();
        if (typeof objM !== 'undefined' && objM !== null)
            this.figures = objM.newObject('TListFigure');
        else
            this.figures = null;
        this.x = 0;
        this.y = 0;
        this.z = 0;
        this.width = 100;
        this.height = 100;
        this.scale = 1;
        this.typeInteraction = 'Move';
        this.coordinatesStart = null;
        this.selectedConnector = null;
        this.invTransformation = null;
        this.SetType(type);
            
    };
    this.InitConstructor();

    TGraph.prototype.Init = function(_object){
        //TODO: Implement Me 
        TObject.prototype.Init.call(this,_object);
//        TObject.Init(_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TGraph') && objM !== null)
        {
            this.figures = objM.newObject('TListFigure');
            if (typeof _object.x !== 'undefined' && _object.x !== null && IsNumeric(_object.x))
                this.x = _object.x;
            if (typeof _object.y !== 'undefined' && _object.y !== null && IsNumeric(_object.y))
                this.y = _object.y;
            if (typeof _object.z !== 'undefined' && _object.z !== null && IsNumeric(_object.z))
                this.z = _object.z;
            if (typeof _object.width !== 'undefined' && _object.width !== null && IsNumeric(_object.width))
                this.width = _object.width;
            if (typeof _object.height !== 'undefined' && _object.height !== null && IsNumeric(_object.height))
                this.height = _object.height;
            if (typeof _object.scale !== 'undefined' && _object.scale !== null && IsNumeric(_object.scale))
                this.scale = _object.scale;
            if (typeof _object.coordinatesStart !== 'undefined' && _object.coordinatesStart !== null)
                this.coordinatesStart = objM.copy(_object.coordinatesStart);
            if (typeof _object.invTransformation !== 'undefined' && _object.invTransformation !== null)
                this.invTransformation = objM.copy(_object.invTransformation);
//            if (typeof _object.selectedConnector !== 'undefined' && _object.selectedConnector !== null && _object.selectedConnector.IsType('TGraphConnector'))
//                this.selectedConnector = _object.selectedConnector;
            if (typeof _object.typeInteraction !== 'undefined' && _object.typeInteraction !== null)
            {
                this.typeInteraction = new String(_object.typeInteraction);
                if (this.typeInteraction !== null)
                    this.typeInteraction = this.typeInteraction.toString();
            }
        }
    };


    TGraph.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TObject.prototype.IsType.call(this,_type);
    };

    TGraph.prototype.SetTransformation = function(matrix){
        var objM = this.GetObjectManager();
        if (typeof matrix !== 'undefined' && matrix !== null && matrix.IsType('TMatrixTransformation') && objM !== null)
        {
//            this.transformation = objM.copy(matrix);
            this.invTransformation = objM.copy(matrix);
            this.invTransformation.Inv();
        }
    };

    TGraph.prototype.CalculateCoordinates = function(coordinates){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            if (typeof this.invTransformation !== 'undefined' && this.invTransformation !== null && this.invTransformation.IsType('TMatrixTransformation'))
            {
                return this.invTransformation.MatrixVectorMultiplication(coordinates);
            }
            
        }
        return null;
    };

    TGraph.prototype.AddElement= function(coordinates , text, code, width ,height){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector') && typeof text !== 'undefined' && text !== null && typeof code !== 'undefined' && code !== null)
        {
            var objM = this.GetObjectManager();
            if (typeof objM !== 'undefined' && objM !== null)
            {
                if (typeof width === 'undefined' || width === null)
                    width = 200;
                if (typeof height === 'undefined' || height === null)
                    height = 100;
                
                var graphElem = objM.newObject('TGraphElement');
                graphElem.SetFigure('Rectangle',width,height);
                
                graphElem.SetData(coordinates,text,code);
                graphElem.SetMarginX(10);
                graphElem.SetFontSize(20);
                var tmp = objM.newObject('TColourRGBA');
                tmp.SetColourRGBA(0.99,0.99,0.99,1);
                graphElem.SetBackgroundColour(tmp);
                tmp = objM.newObject('TColourRGBA');
                tmp.SetColourRGBA(0,0,0,1);
                graphElem.SetLineColour(tmp);
                graphElem.SetLineWidth(5);
                if (typeof this.figures === 'undefined' || this.figures === null)
                    this.figures = objM.newObject('TListFigure');
                if (typeof this.figures !== 'undefined' && this.figures !== null)
                {
                    this.figures.Add(graphElem);
                }
                
            }
        }        
    };

    TGraph.prototype.GetElementByCode= function(code){
        if (this.figures !== null)
            return this.figures.FindObjectGraphElement(code);
        return null;
    };
    
    TGraph.prototype.GetConnectorByCode= function(code){
        if (this.figures !== null)
            return this.figures.FindObjectGraphConnector(code);
        return null;
    };
    
    TGraph.prototype.SetCoordinates = function(x_,y_,z_){
        if (typeof x_ !== 'undefined' && x_ !== null && IsNumeric(x_) && typeof y_ !== 'undefined' && y_ !== null && IsNumeric(y_))
        {
            this.x = x_;
            this.y = y_;
            if (typeof z_ !== 'undefined' && z_ !== null && IsNumeric(z_))
                this.z = z_;
        }
    };

    TGraph.prototype.SetSize = function(width_,height_){
        if (typeof width_ !== 'undefined' && width_ !== null && IsNumeric(width_) && typeof height_ !== 'undefined' && height_ !== null && IsNumeric(height_))
        {
            this.width = width_;
            this.height = height_;
        }
    };

    TGraph.prototype.Draw2 = function(ctx){
        var objM = this.GetObjectManager();        
        if (objM !== null && typeof ctx !== 'undefined' && ctx !== null && ctx.IsType('TDrawContext'))
        {
            var matrix;
            ctx.PushMatrix();
            
            var matrix = objM.newObject('TMatrixTransformation3D');
            var matrix2 = objM.newObject('TMatrixTransformation3D');
            var matrix3 = objM.newObject('TMatrixTransformation3D');
            matrix.SetTranslationMatrix(this.width/2,this.height/2,0);
            matrix2.SetScaleMatrix(this.scale);
            matrix3.SetTranslationMatrix(this.x,this.y,0);
            matrix.MatrixMultiplication(matrix2);
            matrix.MatrixMultiplication(matrix3);

            ctx.MultiplicationMatrix(matrix);
            if (typeof this.figures !== 'undefined' && this.figures !== null && this.figures.IsType('TListFigure'))
            {
                this.figures.Draw(ctx);
            }
            
            ctx.PopMatrix();
        }        
    };


    TGraph.prototype.Draw = function(ctx){
        if (typeof ctx !== 'undefined' && ctx !== null)
        {
            ctx.clearRect(0, 0, this.width, this.height);
            var objM = this.GetObjectManager();
            if (typeof objM !== 'undefined' && objM !== null)
            {
                var ctx_ = objM.newObject('TDrawCanvasContext');
                if (typeof ctx_ !== 'undefined' && ctx_ !== null)
                {
                    ctx_.SetScale(this.scale);
                    ctx_.SetContext(ctx);
                    var matrix = objM.newObject('TMatrixTransformation2D');
                    var matrix2 = objM.newObject('TMatrixTransformation2D');
                    var matrix3 = objM.newObject('TMatrixTransformation2D');
//                    matrix.SetTranslationMatrix(this.x + this.width/2,this.y + this.height/2);
                    matrix.SetTranslationMatrix(this.width/2,this.height/2);
                    matrix2.SetScaleMatrix(this.scale);
                    matrix3.SetTranslationMatrix(this.x,this.y);
                    matrix.MatrixMultiplication(matrix2);
                    matrix.MatrixMultiplication(matrix3);
                    ctx_.SetTransformation(matrix);
                    
                    this.SetTransformation(matrix);

                    if (typeof this.figures !== 'undefined' && this.figures !== null && this.figures.IsType('TListFigure'))
                    {
                        this.figures.Draw(ctx_);
                    }
                }
            }
        }
        
    };

    TGraph.prototype.MouseEvent = function(x,y,type_){
        var objM = this.GetObjectManager();        
        if (typeof this.figures !== 'undefined' && this.figures !== null && this.figures.IsType('TListFigure'))
        {
            if (typeof type_ !== 'undefined' && type_ !== null && typeof objM !== 'undefined' && objM !== null)
            {
                if (typeof x !== 'undefined' && x !== null && IsNumeric(x) && typeof y !== 'undefined' && y !== null && IsNumeric(y))
                {
                    var coordinates = objM.newObject('TVector2DT');
                    if (coordinates !== null)
                    {
                        coordinates.SetCoordinates(x,y);
                        switch(this.typeInteraction)
                        {
                            case 'MoveDraving':
                                switch(type_)
                                {
                                    case 'LeftButtonDown':
                                        this.coordinatesStart = objM.copy(coordinates);
                                        break;
                                    case 'LeftButtonUp':
                                        if (this.coordinatesStart !== null)
                                        {
                                            var coord = objM.copy(coordinates);
                                            coord.Subtraction(this.coordinatesStart);
//                                            this.Move(coord);
                                            this.coordinatesStart = null;
                                        }
                                        break;
                                    case 'MouseMove':
                                        if (this.coordinatesStart !== null)
                                        {
                                            var coord = objM.copy(this.coordinatesStart);
                                            var coord2 = objM.newObject(coord.GetType());
                                            coord2 = this.CalculateCoordinates(coord2);
                                            coord.Subtraction(coordinates);
                                            coord = this.CalculateCoordinates(coord);
                                            coord2.Subtraction(coord);
                                            this.Move(coord2);
//                                            var coord = objM.copy(coordinates);
//                                            coord.Subtraction(this.coordinatesStart);
//                                            this.Move(coord);
                                            this.coordinatesStart = objM.copy(coordinates);
                                        }
                                        break;
                                }
                                break;
                            case 'Move':
                                switch(type_)
                                {
                                    case 'LeftButtonDown':
                                    case 'LeftButtonUp':
                                    case 'MouseMove':
                                        this.figures.MouseEvent(coordinates,type_,false);
            /*                                var hit = this.figures.InArea(coordinates);
                                            if (hit !== null && hit.hit)
                                            {

                                            }*/
                                        break;
                                }
                                break;
                            case 'MoveAndResize':
                                switch(type_)
                                {
                                    case 'LeftButtonDown':
                                    case 'LeftButtonUp':
                                    case 'MouseMove':
                                        this.figures.MouseEvent(coordinates,type_,false);
                                        break;
                                }
                                break;
                            case 'Connectors':
                                switch(type_)
                                {
                                    case 'LeftButtonDown':
                                        var YN = this.figures.MouseEvent(coordinates,'LeftButtonDownConnectors',false);
                                        if (!YN)
                                        {
                                            var hit = this.figures.InArea(coordinates);
                                            if (hit !== null && hit.hit && typeof hit.object !== 'undefined' && hit.object !== null && hit.object.IsType('TFigure'))
                                            {
                                                if (typeof hit.objectParent !== 'undefined' && hit.objectParent !== null && hit.objectParent.IsType('TGraphElement'))
                                                {
                                                    this.selectedConnector = objM.newObject('TGraphConnector');
                                                    if (this.selectedConnector !== null)
                                                    {
                                                        this.selectedConnector.SetBegin(hit.objectParent);
                                                        this.figures.Add(this.selectedConnector);
                                                    }
                                                    break;
                                                }
                                            }
                                        }
                                        this.selectedConnector = null;
                                        break;
                                    case 'LeftButtonUp':
                                        if (this.selectedConnector !== null)
                                        {
                                            var hit = this.figures.InArea(coordinates);
                                            if (hit !== null && hit.hit && typeof hit.object !== 'undefined' && hit.object !== null && hit.object.IsType('TFigure'))
                                            {
                                                if (typeof hit.objectParent !== 'undefined' && hit.objectParent !== null && hit.objectParent.IsType('TGraphElement'))
                                                {
                                                    this.selectedConnector.SetEnd(hit.objectParent);
                                                    this.selectedConnector.SetText('abcd');
                                                    this.selectedConnector.SetSelection(true);
                                                }
                                            }
                                        }
                                        this.selectedConnector = null;
                                        this.figures.MouseEvent(coordinates,'LeftButtonUpConnectors',false);
                                        break;
                                    case 'MouseMove':
                                        this.figures.MouseEvent(coordinates,'MouseMoveConnectors',false);
                                        break;
                                }
                                break;
                        }
                    }
                }        
            }
        }
        
    };

    TGraph.prototype.TypeOfInteraction = function(type_){
        if (typeof type_ !== 'undefined' && type_ !== null)
        {
            if (type_ !== this.typeInteraction)
                this.figures.SetSelection(false);
            this.typeInteraction = new String(type_);
            if (this.typeInteraction !== null)
                this.typeInteraction = this.typeInteraction.toString();
            if (this.figures !== null)
            {
                if (type_ === 'MoveDraving')
                    this.figures.TypeOfInteraction('None');
                else
                    this.figures.TypeOfInteraction(type_);
                
                if (type_ === 'Connectors')
                    this.figures.SetSelectionFigureType(true,'TGraphConnector');
                else
                    this.figures.SetSelectionFigureType(false,'TGraphConnector');
            }
        }
    };

    TGraph.prototype.Move = function(coordinates){
        if (typeof coordinates !== 'undefined' && coordinates !== null && coordinates.IsType('TVector'))
        {
            var x = coordinates.GetCoordinate(0),y = coordinates.GetCoordinate(1);
            this.x = this.x + x;
            this.y = this.y + y;
        }
    };

    TGraph.prototype.SetScale = function(scale_){
        if (typeof scale_ !== 'undefined' && scale_ !== null && IsNumeric(scale_))
        {
            this.scale = scale_;
        }
    };

    TGraph.prototype.FirstElement = function(){
        if (typeof this.figures !== 'undefined' && this.figures !== null)
        {
            this.figures.First();
        }
    };

    TGraph.prototype.NextElement = function(){
        if (typeof this.figures !== 'undefined' && this.figures !== null)
        {
            this.figures.Next();
        }
    };
    
    TGraph.prototype.GetElement = function(){
        if (typeof this.figures !== 'undefined' && this.figures !== null)
        {
            return this.figures.GetData();
        }
        return null;
    };
    
    TGraph.prototype.AddConnector = function(code1,code2,codeConnector){
        var objM = this.GetObjectManager();        
        if (objM !== null && typeof this.figures !== 'undefined' && this.figures !== null && typeof code1 !== 'undefined' && code1 !== null && typeof code2 !== 'undefined' && code2 !== null)
            if (typeof codeConnector !== 'undefined' && codeConnector !== null)
            {
                var object1 = this.figures.FindObjectGraphElement(code1);
                var object2 = this.figures.FindObjectGraphElement(code2);
                if (object1 !== null && object2 !== null)
                {
                    var connector = objM.newObject('TGraphConnector');
                    if (connector !== null)
                    {
                        connector.SetBegin(object1);
                        this.figures.Add(connector);
                        connector.SetEnd(object2);
                        connector.SetCode(codeConnector);
//                        connector.SetText('a');
                        return connector;
                    }

                }
            }
        return null;
    };

    TGraph.prototype.SaveSvg = function(){
        var txt = '<?xml version="1.0" standalone="no"?>\n';
        txt = txt + '<!DOCTYPE svg PUBLIC " -//W3C//DTD SVG 1.1//EN"\n';
        txt = txt + '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n';
        txt = txt + '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" fill-rule="evenodd">\n';
        
        var objM = this.GetObjectManager();
        if (typeof objM !== 'undefined' && objM !== null)
        {
            var ctx_ = objM.newObject('TDrawSvgContext');
            if (typeof ctx_ !== 'undefined' && ctx_ !== null)
            {
                ctx_.SetScale(1);
                ctx_.SetContext(txt);
                var matrix = objM.newObject('TMatrixTransformation2D');
                var matrix2 = objM.newObject('TMatrixTransformation2D');
                var matrix3 = objM.newObject('TMatrixTransformation2D');
//                    matrix.SetTranslationMatrix(this.x + this.width/2,this.y + this.height/2);
                matrix.SetTranslationMatrix(this.width/2,this.height/2);
                matrix2.SetScaleMatrix(this.scale);
                matrix3.SetTranslationMatrix(this.x,this.y);
                matrix.MatrixMultiplication(matrix2);
                matrix.MatrixMultiplication(matrix3);
                ctx_.SetTransformation(matrix);

                this.SetTransformation(matrix);

                if (typeof this.figures !== 'undefined' && this.figures !== null && this.figures.IsType('TListFigure'))
                {
                    this.figures.Draw(ctx_);
                }
                txt = ctx_.GetContext();
            }
        }
        
        txt = txt + '</svg>\n';
        return txt;
    };

}

TGraph.prototype = new TObject();


function TCharts(){
    var type = 'TCharts';
    TCharts.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.SetType(type);
        this.chartType = null;
        this.x = [];
        this.y = [];
        this.width = 10;
        this.height = 10;
        this.xMin = 0;
        this.xMax = 1;
        this.yMin = 0;
        this.yMax = 1;
        this.shiftX = 0;
        this.shiftY = 0;
        this.idChart = null;
        this.scaleAxisXYN = true;
        this.scaleAxisYYN = true;
	this.proportionalScaleAxisYN = false;
    };
    this.InitConstructor();

    TCharts.prototype.Init = function(_object){
        TVisibleFigure.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TCharts') && objM !== null)
        {
            var i;
            if (typeof _object.x !== 'undefined' && _object.x !== null)
            {
                this.x = [];
                for (i = 0;i < _object.x.length;i++)
                {
                    if (typeof _object.x[i] !== 'undefined' && _object.x[i] !== null)
                        this.x[i] = _object.x[i];
                }
            }
            if (typeof _object.y !== 'undefined' && _object.y !== null)
            {
                this.y = [];
                for (i = 0;i < _object.y.length;i++)
                {
                    if (typeof _object.y[i] !== 'undefined' && _object.y[i] !== null)
                        this.y[i] = _object.y[i];
                }
            }
            if (typeof _object.width !== 'undefined' && _object.width !== null && IsNumeric(_object.width))
                this.width = _object.width;
            if (typeof _object.height !== 'undefined' && _object.height !== null && IsNumeric(_object.height))
                this.height = _object.height;
            if (typeof _object.xMin !== 'undefined' && _object.xMin !== null && IsNumeric(_object.xMin))
                this.xMin = _object.xMin;
            if (typeof _object.xMax !== 'undefined' && _object.xMax !== null && IsNumeric(_object.xMax))
                this.xMax = _object.xMax;
            if (typeof _object.yMin !== 'undefined' && _object.yMin !== null && IsNumeric(_object.yMin))
                this.yMin = _object.yMin;
            if (typeof _object.yMax !== 'undefined' && _object.yMax !== null && IsNumeric(_object.yMax))
                this.yMax = _object.yMax;
            if (typeof _object.shiftX !== 'undefined' && _object.shiftX !== null && IsNumeric(_object.shiftX))
                this.shiftX = _object.shiftX;
            if (typeof _object.shiftY !== 'undefined' && _object.shiftY !== null && IsNumeric(_object.shiftY))
                this.shiftY = _object.shiftY;
            if (typeof _object.idChart !== 'undefined' && _object.idChart !== null)
            {
                this.idChart = new String(_object.idChart);
                if (this.idChart !== null)
                    this.idChart = this.idChart.toString();
            }
            if (typeof _object.scaleAxisXYN !== 'undefined' && _object.scaleAxisXYN !== null)
                this.scaleAxisXYN = _object.scaleAxisXYN;
            if (typeof _object.scaleAxisYYN !== 'undefined' && _object.scaleAxisYYN !== null)
                this.scaleAxisYYN = _object.scaleAxisYYN;
            if (typeof _object.proportionalScaleAxisYN !== 'undefined' && _object.proportionalScaleAxisYN !== null)
                this.proportionalScaleAxisYN = _object.proportionalScaleAxisYN;
        }
    };
    
    TCharts.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TCharts.prototype.DrawFigure = function(scene){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof scene !== 'undefined' && scene !== null  && this.lineClass !== null && this.textClass !== null)
// && scene.IsType('TCanvasScene')        
        {
        }
    };

    TCharts.prototype.DrawSign = function(scene,x,y,width){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof scene !== 'undefined' && scene !== null  && this.lineClass !== null && this.textClass !== null)
// && scene.IsType('TCanvasScene')        
        {
        }
    };

    TCharts.prototype.SetX = function(tab){
        if (typeof tab !== 'undefined' && tab !== null)
        {
            var i;
            this.x = [];
            for (i = 0;i < tab.length;i++)
            {
                if (typeof tab[i] !== 'undefined' && tab[i] !== null)
                    this.x[i] = tab[i];
            }
        }
    };    
    
    TCharts.prototype.SetY = function(tab){
        if (typeof tab !== 'undefined' && tab !== null)
        {
            var i;
            this.y = [];
            for (i = 0;i < tab.length;i++)
            {
                if (typeof tab[i] !== 'undefined' && tab[i] !== null)
                    this.y[i] = tab[i];
            }
        }
    };    

    TCharts.prototype.SetWidth = function(w){
        if (typeof w !== 'undefined' && w !== null && IsNumeric(w))
            this.width = w;
    };

    TCharts.prototype.SetHeight = function(h){
        if (typeof h !== 'undefined' && h !== null && IsNumeric(h))
            this.height = h;
    };
    
    TCharts.prototype.SetXMin = function(min_){
        if (typeof min_ !== 'undefined' && min_ !== null && IsNumeric(min_))
            this.xMin = min_;
    };    

    TCharts.prototype.SetXMax = function(max_){
        if (typeof max_ !== 'undefined' && max_ !== null && IsNumeric(max_))
            this.xMax = max_;
    };    

    TCharts.prototype.SetYMin = function(min_){
        if (typeof min_ !== 'undefined' && min_ !== null && IsNumeric(min_))
            this.yMin = min_;
    };    

    TCharts.prototype.SetYMax = function(max_){
        if (typeof max_ !== 'undefined' && max_ !== null && IsNumeric(max_))
            this.yMax = max_;
    };    

    TCharts.prototype.SetShiftX = function(shift){
        if (typeof shift !== 'undefined' && shift !== null && IsNumeric(shift))
            this.shiftX = shift;
    };    

    TCharts.prototype.SetShiftY = function(shift){
        if (typeof shift !== 'undefined' && shift !== null && IsNumeric(shift))
            this.shiftY = shift;
    };    

    TCharts.prototype.SetScaleAxisXYN = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.scaleAxisXYN = YN;
    };   
 
    TCharts.prototype.SetScaleAxisYYN = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.scaleAxisYYN = YN;
    };    

    TCharts.prototype.SetProportionalScaleAxisYN = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.proportionalScaleAxisYN = YN;
    };    

    TCharts.prototype.SetIdChart = function(id_){
        if (typeof id_ !== 'undefined' && id_ !== null)
        {
            this.idChart = new String(id_);
            if (this.idChart !== null)
                this.idChart = this.idChart.toString();
        }
    };

    TCharts.prototype.GetIdChart = function(){
        if (typeof this.idChart !== 'undefined' && this.idChart != null)
        {
            var res = new String(this.idChart);
            if (res !== null)
                return res.toString();
        }
        return null;
    };

    TCharts.prototype.GetMinDataX = function(){
        var res = null;
        if (typeof this.x !== 'undefined' && this.x !== null)
        {
            var i;
            for (i = 0;i < this.x.length;i++)
            {
                if (typeof this.x[i] !== 'undefined' && this.x[i] !== null)
                {
                    if (res === null)
                        res = this.x[i];
                    else
                    {
                        if (res > this.x[i])
                            res = this.x[i];
                    }
                }
            }
            
        }
        return res;
    };

    TCharts.prototype.GetMaxDataX = function(){
        var res = null;
        if (typeof this.x !== 'undefined' && this.x !== null)
        {
            var i;
            for (i = 0;i < this.x.length;i++)
            {
                if (typeof this.x[i] !== 'undefined' && this.x[i] !== null)
                {
                    if (res === null)
                        res = this.x[i];
                    else
                    {
                        if (res < this.x[i])
                            res = this.x[i];
                    }
                }
            }
            
        }
        return res;
    };

    TCharts.prototype.GetMinDataY = function(){
        var res = null;
        if (typeof this.y !== 'undefined' && this.y !== null)
        {
            var i;
            for (i = 0;i < this.y.length;i++)
            {
                if (typeof this.y[i] !== 'undefined' && this.y[i] !== null)
                {
                    if (res === null)
                        res = this.y[i];
                    else
                    {
                        if (res > this.y[i])
                            res = this.y[i];
                    }
                }
            }
            
        }
        return res;
    };

    TCharts.prototype.GetMaxDataY = function(){
        var res = null;
        if (typeof this.y !== 'undefined' && this.y !== null)
        {
            var i;
            for (i = 0;i < this.y.length;i++)
            {
                if (typeof this.y[i] !== 'undefined' && this.y[i] !== null)
                {
                    if (res === null)
                        res = this.y[i];
                    else
                    {
                        if (res < this.y[i])
                            res = this.y[i];
                    }
                }
            }
            
        }
        return res;
    };

}

TCharts.prototype = new TVisibleFigure();

function TLineChart(){
    var type = 'TLineChart';
    TLineChart.prototype.InitConstructor = function(){
        TCharts.prototype.InitConstructor.call(this);
        
        this.SetType(type);
    };
    this.InitConstructor();

    TLineChart.prototype.Init = function(_object){
        TCharts.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TLineChart') && objM !== null)
        {
        }
    };
    
    TLineChart.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TCharts.prototype.IsType.call(this,_type);
    };

    TLineChart.prototype.DrawFigure = function(scene){
        TCharts.prototype.DrawFigure.call(this,scene);
        var objM = this.GetObjectManager();
        if (objM !== null && typeof scene !== 'undefined' && scene !== null  && this.lineClass !== null && this.textClass !== null)
// && scene.IsType('TCanvasScene')        
        {
            var line,i,coord1,coord2,colour,YN;
	    var sx_,sy_;
	    if (this.scaleAxisXYN === true)
            	sx_ = this.width/(this.xMax - this.xMin);
	    else
		sx_ = 1;
	    if (this.scaleAxisXYN === true)
            	sy_ = this.height/(this.yMax - this.yMin);
	    else
		sy_ = 1;
	    if (this.proportionalScaleAxisYN === true)
		if (sx_ < sy_)
		    sy_ = sx_;
		else
		    sx_ = sy_;

            var test1,test2,a,b,x0,y0,x1,y1,xp,yp,d,d0,d1;
            for (i = 1;i < this.x.length;i++)
            {
                YN = false;
                if (this.x[i-1] >= this.xMin && this.x[i-1] <= this.xMax && this.y[i-1] >= this.yMin && this.y[i-1] <= this.yMax)
                {
                    if (this.x[i] >= this.xMin && this.x[i] <= this.xMax && this.y[i] >= this.yMin && this.y[i] <= this.yMax)
                    {
                        YN = true;
                        coord1 = objM.newObject('TVector3DT');
                        coord1.SetCoordinates(this.shiftX + sx_*(this.x[i-1] - this.xMin),this.shiftY + sy_*(this.y[i-1] - this.yMin),0);
                        coord2 = objM.newObject('TVector3DT');
                        coord2.SetCoordinates(this.shiftX + sx_*(this.x[i] - this.xMin),this.shiftY + sy_*(this.y[i] - this.yMin),0);
                    }
                }
                if (!YN)
                {
                    test1 = 0;
                    if(this.x[i-1] >= this.xMax)
                        test1 = test1 | 8;
                    if(this.x[i-1] <= this.xMin)
                        test1 = test1 | 4;
                    if(this.y[i-1] >= this.yMax)
                        test1 = test1 | 2;
                    if(this.y[i-1] <= this.yMin)
                        test1 = test1 | 1;
                    
                    test2 = 0;
                    if(this.x[i] >= this.xMax)
                        test2 = test2 | 8;
                    if(this.x[i] <= this.xMin)
                        test2 = test2 | 4;
                    if(this.y[i] >= this.yMax)
                        test2 = test2 | 2;
                    if(this.y[i] <= this.yMin)
                        test2 = test2 | 1;

                    if ((test1 === 0 || test2 === 0) || ((test1 & test2) === 0))
                    {
                        x0 = this.shiftX + sx_*(this.x[i-1] - this.xMin);
                        y0 = this.shiftY + sy_*(this.y[i-1] - this.yMin);
                        x1 = this.shiftX + sx_*(this.x[i] - this.xMin);
                        y1 = this.shiftY + sy_*(this.y[i] - this.yMin);
                        d = Math.sqrt((x0 - x1)*(x0 - x1) + (y0 - y1)*(y0 - y1));
                        if (test1 === 0)
                        {
                            coord1 = objM.newObject('TVector3DT');
                            coord1.SetCoordinates(x0,y0,0);                            
                        }else
                        {
                            if (x1 !== x0)
                            {
                                a = (y1-y0)/(x1-x0);
                                b = y0 - a*x0;
                                xp = this.shiftX;
                                yp = a*xp + b;
                                d0 = Math.sqrt((x0 - xp)*(x0 - xp) + (y0 - yp)*(y0 - yp));
                                d1 = Math.sqrt((xp - x1)*(xp - x1) + (yp - y1)*(yp - y1));
                                if (d < d1 + d0 - 0.000001)
                                {
                                    xp = this.shiftX + sx_*(this.xMax - this.xMin);
                                    yp = a*xp + b;
                                    d0 = Math.sqrt((x0 - xp)*(x0 - xp) + (y0 - yp)*(y0 - yp));
                                    d1 = Math.sqrt((xp - x1)*(xp - x1) + (yp - y1)*(yp - y1));
                                    if (d < d1 + d0 - 0.000001)
                                    {
                                        yp = this.shiftY;
                                        xp = (yp - b)/a;
                                        d0 = Math.sqrt((x0 - xp)*(x0 - xp) + (y0 - yp)*(y0 - yp));
                                        d1 = Math.sqrt((xp - x1)*(xp - x1) + (yp - y1)*(yp - y1));
                                        if (d < d1 + d0 - 0.000001)
                                        {
                                            yp = this.shiftY + sy_*(this.yMax - this.yMin);
                                            xp = (yp - b)/a;                                            
                                        }
                                    }                                    
                                }
                            }else
                            {
                                xp = x0;
                                yp = this.shiftY;
                                d0 = Math.sqrt((x0 - xp)*(x0 - xp) + (y0 - yp)*(y0 - yp));
                                d1 = Math.sqrt((xp - x1)*(xp - x1) + (yp - y1)*(yp - y1));
                                if (d < d1 + d0 - 0.000001)
                                {
                                    yp = this.shiftY + sy_*(this.yMax - this.yMin);
                                }
                            }
                            coord1 = objM.newObject('TVector3DT');
                            coord1.SetCoordinates(xp,yp,0);
//                            coord2 = objM.newObject('TVector3DT');
//                            coord2.SetCoordinates(x1,y1,0);                            
//                            YN = true;
                        }
                        if (test2 === 0)
                        {
                            coord2 = objM.newObject('TVector3DT');
                            coord2.SetCoordinates(x1,y1,0);                            
                        }else
                        {
                            if (x1 !== x0)
                            {
                                a = (y1-y0)/(x1-x0);
                                b = y0 - a*x0;
                                xp = this.shiftX;
                                yp = a*xp + b;
                                d0 = Math.sqrt((x0 - xp)*(x0 - xp) + (y0 - yp)*(y0 - yp));
                                d1 = Math.sqrt((xp - x1)*(xp - x1) + (yp - y1)*(yp - y1));
                                if ((xp === coord1.GetX() && yp === coord1.GetY()) || d < d1 + d0 - 0.000001)
                                {
                                    xp = this.shiftX + sx_*(this.xMax - this.xMin);
                                    yp = a*xp + b;
                                    d0 = Math.sqrt((x0 - xp)*(x0 - xp) + (y0 - yp)*(y0 - yp));
                                    d1 = Math.sqrt((xp - x1)*(xp - x1) + (yp - y1)*(yp - y1));
                                    if ((xp === coord1.GetX() && yp === coord1.GetY()) || d < d1 + d0 - 0.000001)
                                    {
                                        yp = this.shiftY;
                                        xp = (yp - b)/a;
                                        d0 = Math.sqrt((x0 - xp)*(x0 - xp) + (y0 - yp)*(y0 - yp));
                                        d1 = Math.sqrt((xp - x1)*(xp - x1) + (yp - y1)*(yp - y1));
                                        if ((xp === coord1.GetX() && yp === coord1.GetY()) || d < d1 + d0 - 0.000001)
                                        {
                                            yp = this.shiftY + sy_*(this.yMax - this.yMin);
                                            xp = (yp - b)/a;                                            
                                        }
                                    }                                    
                                }
                            }else
                            {
                                xp = x0;
                                yp = this.shiftY;
                                d0 = Math.sqrt((x0 - xp)*(x0 - xp) + (y0 - yp)*(y0 - yp));
                                d1 = Math.sqrt((xp - x1)*(xp - x1) + (yp - y1)*(yp - y1));
                                if ((xp === coord1.GetX() && yp === coord1.GetY()) || d < d1 + d0 - 0.000001)
                                {
                                    yp = this.shiftY + sy_*(this.yMax - this.yMin);
                                }
                            }
                            coord2 = objM.newObject('TVector3DT');
                            coord2.SetCoordinates(xp,yp,0);
                        }
                        YN = true;
                    }
                }
                if (YN)
                {
                    line = objM.newObject('T' + this.chartType + 'Line');
                    line.SetVerticle(0,coord1);
                    line.SetVerticle(1,coord2);
//                    colour = objM.newObject('TColourRGBA');
//                    colour.SetColourRGBA(0,0,0,0);
                    line.SetLineColour(this.GetLineColour());
                    line.SetLineWidth(this.GetLineWidth());
                    line.SetLineType(this.GetLineType());
                    line.Draw(scene);
                }
            }
        }
        
    };

    TLineChart.prototype.DrawSign = function(scene,x,y,width){
        TCharts.prototype.DrawSign.call(this,scene,x,y,width);
        var objM = this.GetObjectManager();
        if (objM !== null && typeof scene !== 'undefined' && scene !== null  && this.lineClass !== null)
        {

            var coord1 = objM.newObject('TVector3DT');
            var coord2 = objM.newObject('TVector3DT');
            coord1.SetCoordinates(x,y,0);
            coord2.SetCoordinates(x + width,y,0);            
            
            var line = objM.newObject('T' + this.chartType + 'Line');
            line.SetVerticle(0,coord1);
            line.SetVerticle(1,coord2);
//                    colour = objM.newObject('TColourRGBA');
//                    colour.SetColourRGBA(0,0,0,0);
            line.SetLineColour(this.GetLineColour());
            line.SetLineWidth(this.GetLineWidth());
            line.SetLineType(this.GetLineType());
            line.Draw(scene);
        }
    };
    
}

TLineChart.prototype = new TCharts();

function TPointChart(){
    var type = 'TPointChart';
    TPointChart.prototype.InitConstructor = function(){
        TCharts.prototype.InitConstructor.call(this);        
        this.SetType(type);
        
        this.size = 5;
        this.nPoints = 4;
        this.startAngle = 45;
    };
    this.InitConstructor();

    TPointChart.prototype.Init = function(_object){
        TCharts.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TPointChart') && objM !== null)
        {
            if (typeof _object.size !== 'undefined' && _object.size !== null && IsNumeric(_object.size))
                this.size = _object.size;
            if (typeof _object.nPoints !== 'undefined' && _object.nPoints !== null && IsInt(_object.nPoints))
                this.nPoints = _object.nPoints;
            if (typeof _object.startAngle !== 'undefined' && _object.startAngle !== null && IsNumeric(_object.startAngle))
                this.startAngle = _object.startAngle;
        }
    };
    
    TPointChart.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TCharts.prototype.IsType.call(this,_type);
    };

    TPointChart.prototype.DrawSign_ = function(scene,x,y){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof scene !== 'undefined' && scene !== null  && this.lineClass !== null && this.textClass !== null)
        {
            var bg = this.GetBackgroundColour();
            if (bg !== null && bg.GetN() >= 3)
            {
                var transformation = scene.GetTransformation();
                var trans = objM.copy(transformation);
                trans.Inv();
                var polygon = objM.newObject('T' + this.chartType + 'Polygon');
                var w = this.size;
                var coord = objM.newObject('TVector3DT');
                var coord2 = objM.newObject('TVector3DT');
                coord.SetCoordinates(0,0,0);
                coord2.SetCoordinates(0,w,0);
                var result1 = trans.MatrixVectorMultiplication(coord);
                var result2 = trans.MatrixVectorMultiplication(coord2);
                w = Math.abs(result2.GetCoordinate(1) - result1.GetCoordinate(1));
                var alpha = this.startAngle,j;
                var n = this.nPoints,step = 2*Math.PI/n,x0_,y0_,x1_,y1_,coord1,line;
                for (j = 0;j < n;j++)
                {
                    alpha = alpha + step;
                    x1_ = w*Math.cos(alpha);
                    y1_ = w*Math.sin(alpha);
                    coord2 = objM.newObject('TVector3DT');
                    coord2.SetCoordinates(x+x1_,y+y1_,0);
                    polygon.SetVerticle(j,coord2);
                }
                polygon.SetBackgroundColour(bg);
                polygon.Draw(scene);
                alpha = this.startAngle;
                for (j = 0;j < n;j++)
                {
                    x0_ = w*Math.cos(alpha - step);
                    y0_ = w*Math.sin(alpha - step);
                    x1_ = w*Math.cos(alpha);
                    y1_ = w*Math.sin(alpha);
                    coord1 = objM.newObject('TVector3DT');
                    coord1.SetCoordinates(x+x0_,y+y0_,0);                            
                    coord2 = objM.newObject('TVector3DT');
                    coord2.SetCoordinates(x+x1_,y+y1_,0);
                    line = objM.newObject('T' + this.chartType + 'Line');
                    line.SetVerticle(0,coord1);
                    line.SetVerticle(1,coord2);
                    line.SetLineColour(this.GetLineColour());
                    line.SetLineWidth(this.GetLineWidth());
                    line.SetLineType(this.GetLineType());
                    line.Draw(scene);
                    alpha = alpha + step;
                }
            }
        }
    };

    TPointChart.prototype.DrawFigure = function(scene){
        TCharts.prototype.DrawFigure.call(this,scene);
        var objM = this.GetObjectManager();
        if (objM !== null && typeof scene !== 'undefined' && scene !== null  && this.lineClass !== null && this.textClass !== null)
// && scene.IsType('TCanvasScene')        
        {
            var transformation = scene.GetTransformation();
            var trans = objM.copy(transformation);
            trans.Inv();
            var i,j,line,coord1,coord2,x,y,w = this.size,x0_,y0_,x1_,y1_;
//            var triangle,coord3;
            var polygon,bg;
            var n = this.nPoints,alpha,step = 2*Math.PI/n;
            var coord = objM.newObject('TVector3DT');
            coord2 = objM.newObject('TVector3DT');
            coord.SetCoordinates(0,0,0);
            coord2.SetCoordinates(0,w,0);
            var result1 = trans.MatrixVectorMultiplication(coord);
            var result2 = trans.MatrixVectorMultiplication(coord2);
            w = Math.abs(result2.GetCoordinate(1) - result1.GetCoordinate(1));
            
            var sx_ = this.width/(this.xMax - this.xMin);
            var sy_ = this.height/(this.yMax - this.yMin);
            for (i = 0;i < this.x.length;i++)
            {
                if (this.x[i] >= this.xMin && this.x[i] <= this.xMax && this.y[i] >= this.yMin && this.y[i] <= this.yMax)
                {
                    x = this.shiftX + sx_*(this.x[i] - this.xMin);
                    y = this.shiftY + sy_*(this.y[i] - this.yMin);
                    
                    bg = this.GetBackgroundColour();
                    if (bg !== null && bg.GetN() >= 3)
                    {
                        polygon = objM.newObject('T' + this.chartType + 'Polygon');
        //                coord3 = objM.newObject('TVector3DT');
        //                coord3.SetCoordinates(x,y,0);

                        alpha = this.startAngle;
                        for (j = 0;j < n;j++)
                        {
                            alpha = alpha + step;
                            x1_ = w*Math.cos(alpha);
                            y1_ = w*Math.sin(alpha);
                            coord2 = objM.newObject('TVector3DT');
                            coord2.SetCoordinates(x+x1_,y+y1_,0);
                            polygon.SetVerticle(j,coord2);
                        }
                        polygon.SetBackgroundColour(bg);
                        polygon.Draw(scene);
                    }
                    
                    alpha = this.startAngle;
                    for (j = 0;j < n;j++)
                    {
                        x0_ = w*Math.cos(alpha - step);
                        y0_ = w*Math.sin(alpha - step);
                        x1_ = w*Math.cos(alpha);
                        y1_ = w*Math.sin(alpha);
                        coord1 = objM.newObject('TVector3DT');
                        coord1.SetCoordinates(x+x0_,y+y0_,0);                            
                        coord2 = objM.newObject('TVector3DT');
                        coord2.SetCoordinates(x+x1_,y+y1_,0);
                        line = objM.newObject('T' + this.chartType + 'Line');
                        line.SetVerticle(0,coord1);
                        line.SetVerticle(1,coord2);
                        line.SetLineColour(this.GetLineColour());
                        line.SetLineWidth(this.GetLineWidth());
                        line.SetLineType(this.GetLineType());
                        line.Draw(scene);
    /*                    triangle = objM.newObject('T' + this.chartType + 'Triangle');
                        triangle.SetVerticle(0,coord1);
                        triangle.SetVerticle(1,coord2);
                        triangle.SetVerticle(2,coord3);
                        triangle.SetLineColour(this.GetLineColour());
                        triangle.SetBackgroundColour(this.GetLineColour());
                        triangle.SetLineWidth(0);
                        triangle.Draw(scene);*/
                        alpha = alpha + step;
                    }
                }                
            }
        }
        
    };

    TPointChart.prototype.DrawSign = function(scene,x,y,width){
        TCharts.prototype.DrawSign.call(this,scene,x,y,width);
        var objM = this.GetObjectManager();
        if (objM !== null && typeof scene !== 'undefined' && scene !== null)
        {
            this.DrawSign_(scene,x + width/2,y);
        }
    };

    TPointChart.prototype.SetSize = function(s){
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.size = s;
    };    

    TPointChart.prototype.SetNPoints = function(n){
        if (typeof n !== 'undefined' && n !== null && IsInt(n))
            this.nPoints = n;
    };    

    TPointChart.prototype.SetStartAngle = function(angle){
        if (typeof angle !== 'undefined' && angle !== null && IsNumeric(angle))
            this.startAngle = angle;
    };    
    
}

TPointChart.prototype = new TCharts();

function TBarChart(){
    var type = 'TBarChart';
    TBarChart.prototype.InitConstructor = function(){
        TCharts.prototype.InitConstructor.call(this);        
        this.SetType(type);
        
        this.interspace = 0;
    };
    this.InitConstructor();

    TBarChart.prototype.Init = function(_object){
        TCharts.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TPointChart') && objM !== null)
        {
            if (typeof _object.interspace !== 'undefined' && _object.interspace !== null && IsNumeric(_object.interspace))
                this.interspace = _object.interspace;
        }
    };
    
    TBarChart.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TCharts.prototype.IsType.call(this,_type);
    };

    TBarChart.prototype.DrawFigure = function(scene){
        TCharts.prototype.DrawFigure.call(this,scene);
        var objM = this.GetObjectManager();
        if (objM !== null && this.x.length > 1 && typeof scene !== 'undefined' && scene !== null  && this.lineClass !== null)
        {
            var transformation = scene.GetTransformation();
            var trans = objM.copy(transformation);
            trans.Inv();
            var coord = objM.newObject('TVector3DT');
            var coord2 = objM.newObject('TVector3DT');
            coord.SetCoordinates(0,0,0);
            coord2.SetCoordinates(this.interspace,0,0);
            var result1 = trans.MatrixVectorMultiplication(coord);
            var result2 = trans.MatrixVectorMultiplication(coord2);
            var tmpInterspace = Math.abs(result2.GetCoordinate(0) - result1.GetCoordinate(0));
            tmpInterspace = tmpInterspace/2;

            var sx_ = this.width/(this.xMax - this.xMin);
            var sy_ = this.height/(this.yMax - this.yMin);
            var bg,polygon,i,x0,y0,x1,y1,line;
            for (i = 0;i < this.x.length;i++)
            {
                if (this.x[i] >= this.xMin && this.x[i] <= this.xMax && this.y[i] >= this.yMin && this.y[i] <= this.yMax)
                {
                    x = this.shiftX + sx_*(this.x[i] - this.xMin);
                    y = this.shiftY + sy_*(this.y[i] - this.yMin);
                    if (i > 0)
                        x0 = this.shiftX + sx_*(this.x[i] - (this.x[i] - this.x[i-1])/2 - this.xMin);
                    if (i < this.x.length-1)
                        x1 = this.shiftX + sx_*(this.x[i] + (this.x[i + 1] - this.x[i])/2 - this.xMin);
                    if (i === 0)
                    {
                        x0 = x - (x1 - x);
                        if (x0 < this.shiftX)
                            x0 = this.shiftX;
                    }
                    if (i === this.x.length-1)
                    {
                        x1 = x + (x - x0);
                        if (x1 > this.shiftX + sx_*(this.xMax - this.xMin))
                            x1 = this.shiftX + sx_*(this.xMax - this.xMin);
                    }
                    y0 = this.shiftY;
                    y1 = this.shiftY + sy_*(this.y[i] - this.yMin);
                    x0 = x0 + tmpInterspace;
                    x1 = x1 - tmpInterspace;
                    
                    bg = this.GetBackgroundColour();
                    if (bg !== null && bg.GetN() >= 3)
                    {
                        polygon = objM.newObject('T' + this.chartType + 'Polygon');

                        coord2 = objM.newObject('TVector3DT');
                        coord2.SetCoordinates(x0,y0,0);
                        polygon.SetVerticle(0,coord2);

                        coord2 = objM.newObject('TVector3DT');
                        coord2.SetCoordinates(x1,y0,0);
                        polygon.SetVerticle(1,coord2);

                        coord2 = objM.newObject('TVector3DT');
                        coord2.SetCoordinates(x1,y1,0);
                        polygon.SetVerticle(2,coord2);

                        coord2 = objM.newObject('TVector3DT');
                        coord2.SetCoordinates(x0,y1,0);
                        polygon.SetVerticle(3,coord2);

                        polygon.SetBackgroundColour(bg);
                        polygon.Draw(scene);
                    }
                    coord = objM.newObject('TVector3DT');
                    coord.SetCoordinates(x0,y0,0);                            
                    coord2 = objM.newObject('TVector3DT');
                    coord2.SetCoordinates(x1,y0,0);
                    line = objM.newObject('T' + this.chartType + 'Line');
                    line.SetVerticle(0,coord);
                    line.SetVerticle(1,coord2);
                    line.SetLineColour(this.GetLineColour());
                    line.SetLineWidth(this.GetLineWidth());
                    line.SetLineType(this.GetLineType());
                    line.Draw(scene);

                    coord = objM.newObject('TVector3DT');
                    coord.SetCoordinates(x1,y0,0);                            
                    coord2 = objM.newObject('TVector3DT');
                    coord2.SetCoordinates(x1,y1,0);
                    line = objM.newObject('T' + this.chartType + 'Line');
                    line.SetVerticle(0,coord);
                    line.SetVerticle(1,coord2);
                    line.SetLineColour(this.GetLineColour());
                    line.SetLineWidth(this.GetLineWidth());
                    line.SetLineType(this.GetLineType());
                    line.Draw(scene);

                    coord = objM.newObject('TVector3DT');
                    coord.SetCoordinates(x1,y1,0);                            
                    coord2 = objM.newObject('TVector3DT');
                    coord2.SetCoordinates(x0,y1,0);
                    line = objM.newObject('T' + this.chartType + 'Line');
                    line.SetVerticle(0,coord);
                    line.SetVerticle(1,coord2);
                    line.SetLineColour(this.GetLineColour());
                    line.SetLineWidth(this.GetLineWidth());
                    line.SetLineType(this.GetLineType());
                    line.Draw(scene);

                    coord = objM.newObject('TVector3DT');
                    coord.SetCoordinates(x0,y1,0);                            
                    coord2 = objM.newObject('TVector3DT');
                    coord2.SetCoordinates(x0,y0,0);
                    line = objM.newObject('T' + this.chartType + 'Line');
                    line.SetVerticle(0,coord);
                    line.SetVerticle(1,coord2);
                    line.SetLineColour(this.GetLineColour());
                    line.SetLineWidth(this.GetLineWidth());
                    line.SetLineType(this.GetLineType());
                    line.Draw(scene);
                }
            }
        
        }
        
    };

    TBarChart.prototype.SetInterspace = function(i){
        if (typeof i !== 'undefined' && i !== null && IsNumeric(i))
            this.interspace = i;
    };    

}

TBarChart.prototype = new TCharts();

function TChartLegend(){
    var type = 'TChartLegend';
    TChartLegend.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        this.SetType(type);
        this.x = 0;
        this.y = 0;
        this.fontSize = '12';
        this.font = 'Arial';
        this.fontStyle = 'normal';
        this.lineSpacing = 30;
        this.interspace = 30;
        this.signWidth = 10;
        this.text = [];
        this.chart1 = [];
        this.chart2 = [];
        this.textClass = null;
    };
    this.InitConstructor();

    TChartLegend.prototype.Init = function(_object){
        TVisibleFigure.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (objM !== null && typeof _object !== 'undefined' && _object !== null && _object.IsType('TChartLegend_'))
        {
            var i;
            if (typeof _object.x !== 'undefined' && _object.x !== null && IsNumeric(_object.x))
                this.x = _object.x;
            if (typeof _object.y !== 'undefined' && _object.y !== null && IsNumeric(_object.y))
                this.y = _object.y;
            if (typeof _object.font !== 'undefined' && _object.font !== null)
            {
                this.font = new String(_object.font);
                if (this.font !== null)
                    this.font = this.font.toString();
            }
            if (typeof _object.fontSize !== 'undefined' && _object.fontSize !== null)
            {
                this.fontSize = new String(_object.fontSize);
                if (this.fontSize !== null)
                    this.fontSize = this.fontSize.toString();
            }
            if (typeof _object.fontStyle !== 'undefined' && _object.fontStyle !== null)
            {
                this.fontStyle = new String(_object.fontStyle);
                if (this.fontStyle !== null)
                    this.fontStyle = this.fontStyle.toString();
            }
            if (typeof _object.lineSpacing !== 'undefined' && _object.lineSpacing !== null && IsNumeric(_object.lineSpacing))
                this.lineSpacing = _object.lineSpacing;
            if (typeof _object.interspace !== 'undefined' && _object.interspace !== null && IsNumeric(_object.interspace))
                this.interspace = _object.interspace;
            if (typeof _object.signWidth !== 'undefined' && _object.signWidth !== null && IsNumeric(_object.interspace))
                this.signWidth = _object.signWidth;
            if (typeof _object.text !== 'undefined' && _object.text !== null)
            {
                this.text = new String(_object.text);
                if (this.text !== null)
                    this.text = this.text.toString();
            }
            if (typeof _object.chart1 !== 'undefined' && _object.chart1 !== null)
            {
                for (i = 0;i < _object.chart1.length;i++)
                {
                    if (typeof _object.chart1[i] !== 'undefined' && _object.chart1[i] !== null && _object.chart1[i].IsType('TCharts'))
                        this.chart1[i] = objM.copy(_object.chart1[i]);
                }
            }
            if (typeof _object.chart2 !== 'undefined' && _object.chart2 !== null)
            {
                for (i = 0;i < _object.chart2.length;i++)
                {
                    if (typeof _object.chart2[i] !== 'undefined' && _object.chart2[i] !== null && _object.chart2[i].IsType('TCharts'))
                        this.chart2[i] = objM.copy(_object.chart2[i]);
                }
            }
        }
    };

    TChartLegend.prototype.IsType = function(_type){
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TChartLegend.prototype.DrawFigure = function(scene){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof scene !== 'undefined' && scene !== null && this.textClass !== null)
        {
            var transformation = scene.GetTransformation();
            var trans = objM.copy(transformation);
            trans.Inv();
            var coord1 = objM.newObject('TVector3DT');
            var coord2 = objM.newObject('TVector3DT');
            coord1.SetCoordinates(0,0,0);
            coord2.SetCoordinates(this.signWidth,0,0);
            var result1 = trans.MatrixVectorMultiplication(coord1);
            var result2 = trans.MatrixVectorMultiplication(coord2);
            var tmpSignWidth = Math.abs(result2.GetCoordinate(0) - result1.GetCoordinate(0));

            coord2.SetCoordinates(this.interspace,0,0);
            result2 = trans.MatrixVectorMultiplication(coord2);
            var tmpInterspace = Math.abs(result2.GetCoordinate(0) - result1.GetCoordinate(0));

            coord2.SetCoordinates(this.lineSpacing,0,0);
            result2 = trans.MatrixVectorMultiplication(coord2);
            var tmpLineSpacing = Math.abs(result2.GetCoordinate(0) - result1.GetCoordinate(0));
            
            var i,coord,text,colour;
            for (i = 0;i < this.text.length;i++)
            {
                if (typeof this.chart1[i] !== 'undefined' && this.chart1[i] !== null && this.chart1[i].IsType('TCharts'))
                {
                    this.chart1[i].DrawSign(scene,this.x,this.y - i*tmpLineSpacing,tmpSignWidth);
                }
                if (typeof this.chart2[i] !== 'undefined' && this.chart2[i] !== null && this.chart2[i].IsType('TCharts'))
                {
                    this.chart2[i].DrawSign(scene,this.x,this.y - i*tmpLineSpacing,tmpSignWidth);
                }
                
                if (typeof this.text[i] !== 'undefined' && this.text[i] !== null)
                {
                    text = objM.newObject(this.textClass);
                    coord = objM.newObject('TVector3DT');
                    coord.SetCoordinates(this.x + tmpSignWidth + tmpInterspace,this.y - i*tmpLineSpacing,0);
                    text.SetVerticle(0,coord);
                    text.SetText(this.text[i]);
                    colour = objM.newObject('TColourRGBA');
                    colour.SetColourRGBA(0,0,0,0);
                    text.SetColourText(colour);
                    text.SetFont(this.font);
                    text.SetFontStyle(this.fontStyle);
                    text.SetFontSize(this.fontSize);
                    text.SetAlignX('left');
                    text.SetAlignY('center');
                    text.Draw(scene);
                }
            }
        }        
    };

    TChartLegend.prototype.SetX = function(x_){
        if (typeof x_ !== 'undefined' && x_ !== null && IsNumeric(x_))
            this.x = x_;
    };    

    TChartLegend.prototype.SetY = function(y_){
        if (typeof y_ !== 'undefined' && y_ !== null && IsNumeric(y_))
            this.y = y_;
    };    

    TChartLegend.prototype.SetFontSize = function(size){
        if (typeof size !== 'undefined' && size !== null)
        {
            this.fontSize = new String(size);
            if (this.fontSize !== null)
                this.fontSize = this.fontSize.toString();
        }
        if (size === null)
            this.fontSize = null;
    };

    TChartLegend.prototype.SetFont = function(font_){
        if (typeof font_ !== 'undefined' && font_ !== null)
        {
            this.font = new String(font_);
            if (this.font !== null)
                this.font = this.font.toString();
        }
        if (font_ === null)
            this.font = null;
    };

    TChartLegend.prototype.SetFontStyle = function(fontStyle_){
        if (typeof fontStyle_ !== 'undefined' && fontStyle_ !== null)
        {
            this.fontStyle = new String(fontStyle_);
            if (this.fontStyle !== null)
                this.fontStyle = this.fontStyle.toString();
        }
    };

    TChartLegend.prototype.SetLineSpacing = function(ls){
        if (typeof ls !== 'undefined' && ls !== null)
            this.lineSpacing = parseFloat(ls);
    };    

    TChartLegend.prototype.SetInterspace = function(i){
        if (typeof i !== 'undefined' && i !== null)
            this.interspace = parseFloat(i);
    };    

    TChartLegend.prototype.SetSignWidth = function(s){
        if (typeof s !== 'undefined' && s !== null)
            this.signWidth = parseFloat(s);
    };    

    TChartLegend.prototype.SetText = function(t){
        if (typeof t !== 'undefined' && t !== null)
        {
            var i;
            this.text = [];
            for (i = 0;i < t.length;i++)
            {
                if (typeof t[i] !== 'undefined' && t[i] !== null && t[i].IsType('TPageElement'))
                    this.text[i] = t[i].GetTXT();
            }
        }
    };    

    TChartLegend.prototype.SetChart1 = function(ch){
        if (typeof ch !== 'undefined' && ch !== null)
        {
            var i;
            this.chart1 = [];
            for (i = 0;i < ch.length;i++)
            {
                if (typeof ch[i] !== 'undefined' && ch[i] !== null && ch[i].IsType('TCharts'))
                    this.chart1[i] = ch[i];
            }
        }
    };    

    TChartLegend.prototype.SetChart2 = function(ch){
        if (typeof ch !== 'undefined' && ch !== null)
        {
            var i;
            this.chart2 = [];
            for (i = 0;i < ch.length;i++)
            {
                if (typeof ch[i] !== 'undefined' && ch[i] !== null && ch[i].IsType('TCharts'))
                    this.chart2[i] = ch[i];
            }
        }
    };    

};

TChartLegend.prototype = new TVisibleFigure();


function TChart(){
    var type = 'TChart';
    TChart.prototype.InitConstructor = function(){
        TVisibleFigure.prototype.InitConstructor.call(this);
        
        this.SetType(type);
        this.fontSize = '1';
        this.font = null;
        this.fontStyle = 'normal';
        this.width = 10;
        this.height = 10;
        this.axisLineWidth = 1;
        this.axisArrowWidth = 15;
        this.axisArrowHeight = 10;
        this.axisTypeArrow = 'TArrowTriangle';
        this.x = 0;
        this.y = 0;
        this.xMin = 0;
        this.xMax = 1;
        this.yMin = 0;
        this.yMax = 1;
        this.axisXZero = false;
        this.axisYZero = false;
        this.axisXYN = true;
        this.axisYYN = true;
        this.scaleAxisXYN = true;
        this.scaleAxisYYN = true;
	this.proportionalScaleAxisYN = false;
        this.descriptionLineWidth = 1;
        this.sizeDescriptionLine = 10;
        this.shiftDescriptionAxisX = -17;
        this.shiftDescriptionAxisY = -10;
        this.shiftDescriptionAxisZeroX = 0;
        this.shiftDescriptionAxisZeroY = 0;
        this.descriptionFontSize = '12';
        this.descriptionFont = 'Arial';
        this.descriptionFontStyle = 'normal';
        this.descriptionAxisX = [];
        this.descriptionAxisXText = [];
        this.descriptionXWidthAxisArrow = 15;
        this.descriptionXRangeIncludeZero = false;
        this.autoDescriptionX = true;
        this.descriptionSeparator = '.';
        this.descriptionYWidthAxisArrow = 15;
        this.descriptionYRangeIncludeZero = false;
        this.autoDescriptionY = true;
        this.axisYZero = false;
        this.descriptionAxisYText = [];
        this.xLabel = '';
        this.shiftXLabel = -35;
        this.yLabel = '';
        this.shiftYLabel = -35;
        this.lineClass = null;
        this.textClass = null;
        this.charts = [];
    };
    this.InitConstructor();

    TChart.prototype.Init = function(_object){
        TVisibleFigure.prototype.Init.call(this,_object);
        var objM = this.GetObjectManager();
        if (typeof _object !== 'undefined' && _object !== null && _object.IsType('TChart') && objM !== null)
        {
            var i;
            if (typeof _object.fontSize !== 'undefined' && _object.fontSize !== null)
            {
                this.fontSize = new String(_object.fontSize);
                if (this.fontSize !== null)
                    this.fontSize = this.fontSize.toString();
            }
            if (typeof _object.font !== 'undefined' && _object.font !== null)
            {
                this.font = new String(_object.font);
                if (this.font !== null)
                    this.font = this.font.toString();
            }
            if (typeof _object.fontStyle !== 'undefined' && _object.fontStyle !== null)
            {
                this.fontStyle = new String(_object.fontStyle);
                if (this.fontStyle !== null)
                    this.fontStyle = this.fontStyle.toString();
            }
/*            if (typeof _object.width !== 'undefined' && _object.width !== null)
            {
                this.width = new String(_object.width);
                if (this.width !== null)
                    this.width = this.width.toString();
            }
            if (typeof _object.height !== 'undefined' && _object.height !== null)
            {
                this.height = new String(_object.height);
                if (this.height !== null)
                    this.height = this.height.toString();
            }*/
            if (typeof _object.width !== 'undefined' && _object.width !== null && IsNumeric(_object.width))
                this.width = _object.width;
            if (typeof _object.height !== 'undefined' && _object.height !== null && IsNumeric(_object.height))
                this.height = _object.height;
            if (typeof _object.axisLineWidth !== 'undefined' && _object.axisLineWidth !== null && IsNumeric(_object.axisLineWidth))
                this.axisLineWidth = _object.axisLineWidth;
            if (typeof _object.axisArrowWidth !== 'undefined' && _object.axisArrowWidth !== null && IsNumeric(_object.axisArrowWidth))
                this.axisArrowWidth = _object.axisArrowWidth;
            if (typeof _object.axisArrowHeight !== 'undefined' && _object.axisArrowHeight !== null && IsNumeric(_object.axisArrowHeight))
                this.axisArrowHeight = _object.axisArrowHeight;
            if (typeof _object.axisTypeArrow !== 'undefined' && _object.axisTypeArrow !== null)
            {
                this.axisTypeArrow = new String(_object.axisTypeArrow);
                if (this.axisTypeArrow !== null)
                    this.axisTypeArrow = this.axisTypeArrow.toString();
            }
            if (typeof _object.x !== 'undefined' && _object.x !== null && IsNumeric(_object.x))
                this.x = _object.x;
            if (typeof _object.y !== 'undefined' && _object.y !== null && IsNumeric(_object.y))
                this.y = _object.y;
            if (typeof _object.xMin !== 'undefined' && _object.xMin !== null && IsNumeric(_object.xMin))
                this.xMin = _object.xMin;
            if (typeof _object.xMax !== 'undefined' && _object.xMax !== null && IsNumeric(_object.xMax))
                this.xMax = _object.xMax;
            if (typeof _object.yMin !== 'undefined' && _object.yMin !== null && IsNumeric(_object.yMin))
                this.yMin = _object.yMin;
            if (typeof _object.yMax !== 'undefined' && _object.yMax !== null && IsNumeric(_object.yMax))
                this.yMax = _object.yMax;
            if (typeof _object.axisXZero !== 'undefined' && _object.axisXZero !== null)
                this.axisXZero = _object.axisXZero;
            if (typeof _object.axisYZero !== 'undefined' && _object.axisYZero !== null)
                this.axisYZero = _object.axisYZero;
            if (typeof _object.descriptionLineWidth !== 'undefined' && _object.descriptionLineWidth !== null && IsNumeric(_object.descriptionLineWidth))
                this.descriptionLineWidth = _object.descriptionLineWidth;
            if (typeof _object.sizeDescriptionLine !== 'undefined' && _object.sizeDescriptionLine !== null && IsNumeric(_object.sizeDescriptionLine))
                this.sizeDescriptionLine = _object.sizeDescriptionLine;
            if (typeof _object.sizeDescriptionLine !== 'undefined' && _object.sizeDescriptionLine !== null && IsNumeric(_object.sizeDescriptionLine))
                this.sizeDescriptionLine = _object.sizeDescriptionLine;
            if (typeof _object.shiftDescriptionAxisX !== 'undefined' && _object.shiftDescriptionAxisX !== null && IsNumeric(_object.shiftDescriptionAxisX))
                this.shiftDescriptionAxisX = _object.shiftDescriptionAxisX;
            if (typeof _object.shiftDescriptionAxisY !== 'undefined' && _object.shiftDescriptionAxisY !== null && IsNumeric(_object.shiftDescriptionAxisY))
                this.shiftDescriptionAxisY = _object.shiftDescriptionAxisY;
            if (typeof _object.shiftDescriptionAxisZeroX !== 'undefined' && _object.shiftDescriptionAxisZeroX !== null && IsNumeric(_object.shiftDescriptionAxisZeroX))
                this.shiftDescriptionAxisZeroX = _object.shiftDescriptionAxisZeroX;
            if (typeof _object.shiftDescriptionAxisZeroY !== 'undefined' && _object.shiftDescriptionAxisZeroY !== null && IsNumeric(_object.shiftDescriptionAxisZeroY))
                this.shiftDescriptionAxisZeroY = _object.shiftDescriptionAxisZeroY;
            if (typeof _object.descriptionFontSize !== 'undefined' && _object.descriptionFontSize !== null)
            {
                this.descriptionFontSize = new String(_object.descriptionFontSize);
                if (this.descriptionFontSize !== null)
                    this.descriptionFontSize = this.descriptionFontSize.toString();
            }
            if (typeof _object.descriptionFont !== 'undefined' && _object.descriptionFont !== null)
            {
                this.descriptionFont = new String(_object.descriptionFont);
                if (this.descriptionFont !== null)
                    this.descriptionFont = this.descriptionFont.toString();
            }
            if (typeof _object.descriptionFontStyle !== 'undefined' && _object.descriptionFontStyle !== null)
            {
                this.descriptionFontStyle = new String(_object.descriptionFontStyle);
                if (this.descriptionFontStyle !== null)
                    this.descriptionFontStyle = this.descriptionFontStyle.toString();
            }
            if (typeof _object.descriptionAxisX !== 'undefined' && _object.descriptionAxisX !== null)
            {
                this.descriptionAxisX = [];
                for (i = 0;i < _object.descriptionAxisX.length;i++)
                {
                    if (typeof _object.descriptionAxisX[i] !== 'undefined' && _object.descriptionAxisX[i] !== null)
                        this.descriptionAxisX[i] = _object.descriptionAxisX[i];
                }
            }
            if (typeof _object.descriptionAxisXText !== 'undefined' && _object.descriptionAxisXText !== null)
            {
                this.descriptionAxisXText = [];
                for (i = 0;i < _object.descriptionAxisXText.length;i++)
                {
                    this.descriptionAxisXText[i] = new String(_object.descriptionAxisXText[i]);
                    if (this.descriptionAxisXText[i] !== null)
                        this.descriptionAxisXText[i] = this.descriptionAxisXText[i].toString();
                }
            }
            if (typeof _object.descriptionXWidthAxisArrow !== 'undefined' && _object.descriptionXWidthAxisArrow !== null && IsNumeric(_object.descriptionXWidthAxisArrow))
                this.descriptionXWidthAxisArrow = _object.descriptionXWidthAxisArrow;
            if (typeof _object.descriptionXRangeIncludeZero !== 'undefined' && _object.descriptionXRangeIncludeZero !== null)
                this.descriptionXRangeIncludeZero = _object.descriptionXRangeIncludeZero;
            if (typeof _object.autoDescriptionX !== 'undefined' && _object.autoDescriptionX !== null)
                this.autoDescriptionX = _object.autoDescriptionX;
            if (typeof _object.descriptionAxisY !== 'undefined' && _object.descriptionAxisY !== null)
            {
                this.descriptionAxisY = [];
                for (i = 0;i < _object.descriptionAxisY.length;i++)
                {
                    if (typeof _object.descriptionAxisY[i] !== 'undefined' && _object.descriptionAxisY[i] !== null)
                        this.descriptionAxisY[i] = _object.descriptionAxisY[i];
                }
            }
            if (typeof _object.descriptionAxisYText !== 'undefined' && _object.descriptionAxisYText !== null)
            {
                this.descriptionAxisYText = [];
                for (i = 0;i < _object.descriptionAxisYText.length;i++)
                {
                    this.descriptionAxisYText[i] = new String(_object.descriptionAxisYText[i]);
                    if (this.descriptionAxisYText[i] !== null)
                        this.descriptionAxisYText[i] = this.descriptionAxisYText[i].toString();
                }
            }
            if (typeof _object.descriptionYWidthAxisArrow !== 'undefined' && _object.descriptionYWidthAxisArrow !== null && IsNumeric(_object.descriptionYWidthAxisArrow))
                this.descriptionYWidthAxisArrow = _object.descriptionYWidthAxisArrow;
            if (typeof _object.descriptionYRangeIncludeZero !== 'undefined' && _object.descriptionYRangeIncludeZero !== null)
                this.descriptionYRangeIncludeZero = _object.descriptionYRangeIncludeZero;
            if (typeof _object.autoDescriptionY !== 'undefined' && _object.autoDescriptionY !== null)
                this.autoDescriptionY = _object.autoDescriptionY;
            if (typeof _object.descriptionSeparator !== 'undefined' && _object.descriptionSeparator !== null)
            {
                this.descriptionSeparator = new String(_object.descriptionSeparator);
                if (this.descriptionSeparator !== null)
                    this.descriptionSeparator = this.descriptionSeparator.toString();
            }
            if (typeof _object.xLabel !== 'undefined' && _object.xLabel !== null)
            {
                this.xLabel = new String(_object.xLabel);
                if (this.xLabel !== null)
                    this.xLabel = this.xLabel.toString();
            }
            if (typeof _object.shiftXLabel !== 'undefined' && _object.shiftXLabel !== null && IsNumeric(_object.shiftXLabel))
                this.shiftXLabel = _object.shiftXLabel;
            if (typeof _object.yLabel !== 'undefined' && _object.yLabel !== null)
            {
                this.yLabel = new String(_object.yLabel);
                if (this.yLabel !== null)
                    this.yLabel = this.yLabel.toString();
            }
            if (typeof _object.shiftYLabel !== 'undefined' && _object.shiftYLabel !== null && IsNumeric(_object.shiftYLabel))
                this.shiftYLabel = _object.shiftYLabel;
            if (typeof _object.charts !== 'undefined' && _object.charts !== null)
            {
                for (i = 0;i < _object.charts.length;i++)
                {
                    if (typeof _object.charts[i] !== 'undefined' && _object.charts[i] !== null && _object.charts[i].IsType('TCharts'))
                        this.charts[i] = objM.copy(charts.element[i]);
                }
            }
            if (typeof _object.axisXYN !== 'undefined' && _object.axisXYN !== null)
                this.axisXYN = _object.axisXYN;
            if (typeof _object.axisYYN !== 'undefined' && _object.axisYYN !== null)
                this.axisYYN = _object.axisYYN;
            if (typeof _object.scaleAxisXYN !== 'undefined' && _object.scaleAxisXYN !== null)
                this.scaleAxisXYN = _object.scaleAxisXYN;
            if (typeof _object.scaleAxisYYN !== 'undefined' && _object.scaleAxisYYN !== null)
                this.scaleAxisYYN = _object.scaleAxisYYN;
             if (typeof _object.proportionalScaleAxisYN !== 'undefined' && _object.proportionalScaleAxisYN !== null)
                this.proportionalScaleAxisYN = _object.proportionalScaleAxisYN;
       }
    };
    
    TChart.prototype.IsType = function(_type){
        //TODO: Implement Me 
        if (typeof _type !== 'undefined' && _type !== null)
        {
            if (_type === type)
                return true;
        }
        return TVisibleFigure.prototype.IsType.call(this,_type);
    };

    TChart.prototype.DrawFigure = function(scene){
        var objM = this.GetObjectManager();
        if (objM !== null && typeof scene !== 'undefined' && scene !== null && this.lineClass !== null && this.textClass !== null)
        {
            var i;
            var transformation = scene.GetTransformation();
            
            var n = this.GetNumberOfVerticles(),coord;
            var x_ = this.x;
            var y_ = this.y;
            var sx_,sy_;
	    if (this.scaleAxisXYN === true)
		sx_ = this.width/(this.xMax - this.xMin);
	    else
		sx_ = 1;
 	    if (this.scaleAxisYYN === true)
		sy_ = this.height/(this.yMax - this.yMin);
	    else
		sy_ = 1;
	    if (this.proportionalScaleAxisYN === true)
		if (sx_ < sy_)
		    sy_ = sx_;
		else
		    sx_ = sy_;

            var xAxis;
            if (this.axisYZero)
                xAxis = x_ - this.xMin*sx_;
            else
                xAxis = x_;
            var yAxis;
            if (this.axisXZero)
                yAxis = y_ - this.yMin*sy_;
            else
                yAxis = y_;
            
	    var line,coord,colour;
	    if (this.axisXYN == true)
	    {
		line = objM.newObject(this.lineClass);
		coord = objM.newObject('TVector3DT');
		coord.SetCoordinates(x_,yAxis,0);
		line.SetVerticle(0,coord);
		coord = objM.newObject('TVector3DT');
		coord.SetCoordinates(x_ + this.width,yAxis,0);
		line.SetVerticle(1,coord);
		colour = objM.newObject('TColourRGBA');
		colour.SetColourRGBA(0,0,0,0);
		line.SetLineColour(colour);
		line.SetLineWidth(this.axisLineWidth);
		line.SetArrow(this.axisTypeArrow,false);
		line.SetBeginArrowWidth(this.axisArrowWidth);
		line.SetBeginArrowHeight(this.axisArrowHeight);
		line.Draw(scene);
	    }

	    if (this.axisYYN == true)
	    {
		line = objM.newObject(this.lineClass);
		coord = objM.newObject('TVector3DT');
		coord.SetCoordinates(xAxis,y_,0);
		line.SetVerticle(0,coord);
		coord = objM.newObject('TVector3DT');
		coord.SetCoordinates(xAxis,y_ + this.height,0);
		line.SetVerticle(1,coord);
		colour = objM.newObject('TColourRGBA');
		colour.SetColourRGBA(0,0,0,0);
		line.SetLineColour(colour);
		line.SetLineWidth(this.axisLineWidth);
		line.SetArrow(this.axisTypeArrow,false);
		line.SetBeginArrowWidth(this.axisArrowWidth);
		line.SetBeginArrowHeight(this.axisArrowHeight);
		line.Draw(scene);
	    }
            
            var trans = objM.copy(transformation);
            trans.Inv();
            coord = objM.newObject('TVector3DT');
            coord2 = objM.newObject('TVector3DT');
            coord.SetCoordinates(0,0,0);
            coord2.SetCoordinates(0,this.sizeDescriptionLine,0);
            var result1 = trans.MatrixVectorMultiplication(coord);
            var result2 = trans.MatrixVectorMultiplication(coord2);
            var tmp = Math.abs(result2.GetCoordinate(1) - result1.GetCoordinate(1));
            var text;
            var shiftZero = 0;
            
            coord2 = objM.newObject('TVector3DT');
            coord2.SetCoordinates(this.descriptionXWidthAxisArrow,0,0);
            result2 = trans.MatrixVectorMultiplication(coord2);
            var tmpArrowXWidth = Math.abs(result2.GetCoordinate(0) - result1.GetCoordinate(0));

            coord2.SetCoordinates(0,this.shiftDescriptionAxisX,0);
            result2 = trans.MatrixVectorMultiplication(coord2);
            var tmp2 = result2.GetCoordinate(1) - result1.GetCoordinate(1);
            coord2.SetCoordinates(this.shiftDescriptionAxisZeroX,0,0);
            result2 = trans.MatrixVectorMultiplication(coord2);
            var tmp3 = result2.GetCoordinate(0) - result1.GetCoordinate(0);

	    if (this.axisXYN == true)
	    {
		for(i = 0;i < this.descriptionAxisX.length;i++)
		{
		    if (this.descriptionAxisX[i] >= this.xMin && this.descriptionAxisX[i] <= this.xMax)
		    {
//                    if (i === this.descriptionAxisX.length - 1)
			if (x_ + (this.descriptionAxisX[i] - this.xMin)*sx_ > x_ + this.width - tmpArrowXWidth)
			    break;
			line = objM.newObject(this.lineClass);
			coord = objM.newObject('TVector3DT');
			coord.SetCoordinates(x_ + (this.descriptionAxisX[i] - this.xMin)*sx_,yAxis - tmp/2,0);
			line.SetVerticle(0,coord);
			coord = objM.newObject('TVector3DT');
			coord.SetCoordinates(x_ + (this.descriptionAxisX[i] - this.xMin)*sx_,yAxis + tmp/2,0);
			line.SetVerticle(1,coord);
			colour = objM.newObject('TColourRGBA');
			colour.SetColourRGBA(0,0,0,0);
			line.SetLineColour(colour);
			line.SetLineWidth(this.descriptionLineWidth);
			line.Draw(scene);

			if (typeof this.descriptionAxisXText[i] !== 'undefined' && this.descriptionAxisXText[i] !== null && this.descriptionAxisXText[i] !== '') 
			{

			    text = objM.newObject(this.textClass);
			    coord = objM.newObject('TVector3DT');
			    if (this.axisYZero)
			    {
				if (this.descriptionAxisX[i] === 0)
				    shiftZero = tmp3;
				else
				    shiftZero = 0;
			    }else
			    {
				if (i === 0)
				    shiftZero = tmp3;
				else
				    shiftZero = 0;                            
			    }
			    coord.SetCoordinates(x_ + (this.descriptionAxisX[i] - this.xMin)*sx_ + shiftZero,yAxis - tmp2,0);
			    text.SetVerticle(0,coord);
			    text.SetText(this.descriptionAxisXText[i]);
			    colour = objM.newObject('TColourRGBA');
			    colour.SetColourRGBA(0,0,0,0);
			    text.SetColourText(colour);
			    text.SetFont(this.descriptionFont);
			    text.SetFontStyle(this.descriptionFontStyle);
			    text.SetFontSize(this.descriptionFontSize);
			    text.SetAlignX('center');
			    text.SetAlignY('center');
			    text.Draw(scene);
			}   
		    }
		}
	    }

            coord2.SetCoordinates(0,this.shiftXLabel,0);
            result2 = trans.MatrixVectorMultiplication(coord2);
            tmp = result2.GetCoordinate(1) - result1.GetCoordinate(1);

            if (this.xLabel !== null)
            {
                text = objM.newObject(this.textClass);
                coord = objM.newObject('TVector3DT');
                if (this.axisXZero)
                    coord.SetCoordinates(x_ + this.width,yAxis - tmp,0);
                else
                    coord.SetCoordinates(x_ + this.width/2,yAxis - tmp,0);
                text.SetVerticle(0,coord);
                text.SetFont(this.font);
                text.SetFontStyle(this.fontStyle);
                text.SetFontSize(this.fontSize);
                text.SetAlignX('center');
                text.SetAlignY('center');
                text.SetText(this.xLabel);

                colour = objM.newObject('TColourRGBA');
                colour.SetColourRGBA(0,0,0,0);
                text.SetColourText(colour);
                text.Draw(scene);
            }
            
            coord = objM.newObject('TVector3DT');
            coord2 = objM.newObject('TVector3DT');
            coord.SetCoordinates(0,0,0);
            coord2.SetCoordinates(this.sizeDescriptionLine,0,0);
            result1 = trans.MatrixVectorMultiplication(coord);
            result2 = trans.MatrixVectorMultiplication(coord2);
            tmp = Math.abs(result2.GetCoordinate(0) - result1.GetCoordinate(0));

            coord2.SetCoordinates(0,this.shiftDescriptionAxisY,0);
            result2 = trans.MatrixVectorMultiplication(coord2);
            tmp2 = result2.GetCoordinate(1) - result1.GetCoordinate(1);
            coord2.SetCoordinates(this.shiftDescriptionAxisZeroY,0,0);
            result2 = trans.MatrixVectorMultiplication(coord2);
            tmp3 = result2.GetCoordinate(0) - result1.GetCoordinate(0);

            coord2 = objM.newObject('TVector3DT');
            coord2.SetCoordinates(0,this.descriptionYWidthAxisArrow,0);
            result2 = trans.MatrixVectorMultiplication(coord2);
            var tmpArrowYWidth = Math.abs(result2.GetCoordinate(1) - result1.GetCoordinate(1));


            if (!this.axisYZero)
                tmp2 = -tmp2;

	    if (this.axisYYN == true)
	    {
		for(i = 0;i < this.descriptionAxisY.length;i++)
		{
		    if (this.descriptionAxisY[i] >= this.yMin && this.descriptionAxisY[i] <= this.yMax)
		    {
			if (y_ + (this.descriptionAxisY[i] - this.yMin)*sy_ > y_ + this.height - tmpArrowYWidth)
			    break;
			line = objM.newObject(this.lineClass);
			coord = objM.newObject('TVector3DT');
			coord.SetCoordinates(xAxis - tmp/2,y_ + (this.descriptionAxisY[i] - this.yMin)*sy_,0);
			line.SetVerticle(0,coord);
			coord = objM.newObject('TVector3DT');
			coord.SetCoordinates(xAxis + tmp/2,y_ + (this.descriptionAxisY[i] - this.yMin)*sy_,0);
			line.SetVerticle(1,coord);
			colour = objM.newObject('TColourRGBA');
			colour.SetColourRGBA(0,0,0,0);
			line.SetLineColour(colour);
			line.SetLineWidth(this.descriptionLineWidth);
			line.Draw(scene);                

			if (typeof this.descriptionAxisYText[i] !== 'undefined' && this.descriptionAxisYText[i] !== null && this.descriptionAxisYText[i] !== '') 
			{

			    text = objM.newObject(this.textClass);
			    coord = objM.newObject('TVector3DT');
			    if (this.axisXZero)
			    {
				if (this.descriptionAxisY[i] === 0)
				    shiftZero = tmp3;
				else
				    shiftZero = 0;
			    }else
			    {
				if (i === 0)
				    shiftZero = tmp3;
				else
				    shiftZero = 0;                            
			    }
			    coord.SetCoordinates(xAxis + tmp2, y_ + (this.descriptionAxisY[i] - this.yMin)*sy_ + shiftZero,0);
			    text.SetVerticle(0,coord);
			    text.SetText(this.descriptionAxisYText[i]);
			    colour = objM.newObject('TColourRGBA');
			    colour.SetColourRGBA(0,0,0,0);
			    text.SetColourText(colour);
			    text.SetFont(this.descriptionFont);
			    text.SetFontStyle(this.descriptionFontStyle);
			    text.SetFontSize(this.descriptionFontSize);
			    text.SetAlignX('right');
			    text.SetAlignY('center');
			    text.Draw(scene);
			}   
		    }            
            
		}
	    }

            coord2.SetCoordinates(0,this.shiftYLabel,0);
            result2 = trans.MatrixVectorMultiplication(coord2);
            tmp = result2.GetCoordinate(1) - result1.GetCoordinate(1);

            if (this.yLabel !== null)
            {
                text = objM.newObject(this.textClass);
                coord = objM.newObject('TVector3DT');
                if (this.axisYZero)
                    coord.SetCoordinates(xAxis + tmp,y_ + this.height,0);
                else
                {
                    coord.SetCoordinates(xAxis - tmp,y_ + this.height/2,0);
                    text.SetRotate(-Math.PI / 2);
                }
                text.SetVerticle(0,coord);
                text.SetFont(this.font);
                text.SetFontStyle(this.fontStyle);
                text.SetFontSize(this.fontSize);
                text.SetAlignX('center');
                text.SetAlignY('center');
                text.SetText(this.yLabel);
                colour = objM.newObject('TColourRGBA');
                colour.SetColourRGBA(0,0,0,0);
                text.SetColourText(colour);
                text.Draw(scene);
            }
            
            for (i = 0;i < this.charts.length;i++)
            {
                if (typeof this.charts[i] !== 'undefined' && this.charts[i] !== null && this.charts[i].IsType('TCharts'))
                {
                    this.charts[i].DrawFigure(scene);
                }
            }
            if (typeof this.legend !== 'undefined' && this.legend !== null && this.legend.IsType('TChartLegend'))
            {
                this.legend.DrawFigure(scene);
            }
            
        }
        
    };
    
    TChart.prototype.SetFontSize = function(size){
        if (typeof size !== 'undefined' && size !== null)
        {
            this.fontSize = new String(size);
            if (this.fontSize !== null)
                this.fontSize = this.fontSize.toString();
        }
        if (size === null)
            this.fontSize = null;
    };

    TChart.prototype.SetFont = function(font_){
        if (typeof font_ !== 'undefined' && font_ !== null)
        {
            this.font = new String(font_);
            if (this.font !== null)
                this.font = this.font.toString();
        }
        if (font_ === null)
            this.font = null;
    };

    TChart.prototype.SetFontStyle = function(fontStyle_){
        if (typeof fontStyle_ !== 'undefined' && fontStyle_ !== null)
        {
            this.fontStyle = new String(fontStyle_);
            if (this.fontStyle !== null)
                this.fontStyle = this.fontStyle.toString();
        }
    };

    TChart.prototype.SetWidth = function(w){
        if (typeof w !== 'undefined' && w !== null && IsNumeric(w))
            this.width = w;
    };

    TChart.prototype.SetHeight = function(h){
        if (typeof h !== 'undefined' && h !== null && IsNumeric(h))
            this.height = h;
    };
    
    TChart.prototype.SetAxisLineWidth = function(w){
        if (typeof w !== 'undefined' && w !== null && IsNumeric(w))
            this.axisLineWidth = w;
    };    

    TChart.prototype.SetAxisArrowWidth = function(w){
        if (typeof w !== 'undefined' && w !== null && IsNumeric(w))
            this.axisArrowWidth = w;
    };    

    TChart.prototype.SetAxisArrowHeight = function(h){
        if (typeof h !== 'undefined' && h !== null && IsNumeric(h))
            this.axisArrowHeight = h;
    };    

    TChart.prototype.SetAxisTypeArrow = function(t){
        if (typeof t !== 'undefined' && t !== null)
        {
            this.axisTypeArrow = new String(t);
            if (this.axisTypeArrow !== null)
                this.axisTypeArrow = this.axisTypeArrow.toString();
        }
        if (t === null)
            this.axisTypeArrow = null;
    };    

    TChart.prototype.SetX = function(x_){
        if (typeof x_ !== 'undefined' && x_ !== null && IsNumeric(x_))
            this.x = x_;
    };    

    TChart.prototype.SetY = function(y_){
        if (typeof y_ !== 'undefined' && y_ !== null && IsNumeric(y_))
            this.y = y_;
    };    

    TChart.prototype.SetXMin = function(min_){
        if (typeof min_ !== 'undefined' && min_ !== null && IsNumeric(min_))
            this.xMin = min_;
    };    

    TChart.prototype.SetXMax = function(max_){
        if (typeof max_ !== 'undefined' && max_ !== null && IsNumeric(max_))
            this.xMax = max_;
    };    

    TChart.prototype.SetYMin = function(min_){
        if (typeof min_ !== 'undefined' && min_ !== null && IsNumeric(min_))
            this.yMin = min_;
    };    

    TChart.prototype.SetYMax = function(max_){
        if (typeof max_ !== 'undefined' && max_ !== null && IsNumeric(max_))
            this.yMax = max_;
    };    

    TChart.prototype.SetAxisXZero = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.axisXZero = YN;
    };    

    TChart.prototype.SetAxisYZero = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.axisYZero = YN;
    };  
  
    TChart.prototype.GetAxisXYN = function(){
        return this.axisXYN;
    };
    TChart.prototype.GetAxisYYN = function(){
        return this.axisYYN;
    };
    TChart.prototype.SetAxisXYN = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.axisXYN = YN;
    };    
    TChart.prototype.SetAxisYYN = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.axisYYN = YN;
    };    

    TChart.prototype.GetScaleAxisXYN = function(){
        return this.scaleAxisXYN;
    };
    TChart.prototype.GetScaleAxisYYN = function(){
        return this.scaleAxisYYN;
    };
    TChart.prototype.SetScaleAxisXYN = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.scaleAxisXYN = YN;
    };    
    TChart.prototype.SetScaleAxisYYN = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.scaleAxisYYN = YN;
    };    

    TChart.prototype.SetProportionalScaleAxisYN = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.proportionalScaleAxisYN = YN;
    };    
    TChart.prototype.SetProportionalScaleAxisYN = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
            this.proportionalScaleAxisYN = YN;
    };    

    TChart.prototype.SetDescriptionLineWidth = function(d){
        if (typeof d !== 'undefined' && d !== null)
            this.descriptionLineWidth = d;
    };    

    TChart.prototype.SetSizeDescriptionLine = function(s){
        if (typeof s !== 'undefined' && s !== null)
            this.sizeDescriptionLine = s;
    };    

    TChart.prototype.SetShiftDescriptionAxisX = function(s){
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.shiftDescriptionAxisX = s;
    };    

    TChart.prototype.SetShiftDescriptionAxisY = function(s){
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.shiftDescriptionAxisY = s;
    };    

    TChart.prototype.SetShiftDescriptionAxisZeroX = function(s){
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.shiftDescriptionAxisZeroX = s;
    };    

    TChart.prototype.SetShiftDescriptionAxisZeroY = function(s){
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.shiftDescriptionAxisZeroY = s;
    };    

    TChart.prototype.SetDescriptionFontSize = function(s){
        if (typeof s !== 'undefined' && s !== null)
        {
            this.descriptionFontSize = new String(s);
            if (this.descriptionFontSize !== null)
                this.descriptionFontSize = this.descriptionFontSize.toString();
        }
        if (s === null)
            this.descriptionFontSize = null;
    };    

    TChart.prototype.SetDescriptionFont = function(f){
        if (typeof f !== 'undefined' && f !== null)
        {
            this.descriptionFont = new String(f);
            if (this.descriptionFont !== null)
                this.descriptionFont = this.descriptionFont.toString();
        }
        if (f === null)
            this.descriptionFont = null;
    };    

    TChart.prototype.SetDescriptionFontStyle = function(s){
        if (typeof s !== 'undefined' && s !== null)
        {
            this.descriptionFontStyle = new String(s);
            if (this.descriptionFontStyle !== null)
                this.descriptionFontStyle = this.descriptionFontStyle.toString();
        }
        if (s === null)
            this.descriptionFontStyle = null;
    };    

    TChart.prototype.SetDescriptionAxisX = function(d){
        if (typeof d !== 'undefined' && d !== null)
        {
            var i;
            this.descriptionAxisX = [];
            for (i = 0;i < d.length;i++)
            {
                if (typeof d[i] !== 'undefined' && d[i] !== null && IsNumeric(d[i]))
                    this.descriptionAxisX[i] = parseFloat(d[i]);
            }
        }
    };    

    TChart.prototype.SetDescriptionAxisXTextTXT = function(d){
        if (typeof d !== 'undefined' && d !== null)
        {
            var i;
            this.descriptionAxisXText = [];
            for (i = 0;i < d.length;i++)
            {
                if (typeof d[i] !== 'undefined' && d[i] !== null && d[i].IsType('TPageElement'))
                    this.descriptionAxisXText[i] = d[i].GetTXT();
            }
//            this.descriptionAxisXText = eval(d);
        }
    };    

    TChart.prototype.SetDescriptionXWidthAxisArrow = function(s){
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.descriptionXWidthAxisArrow = s;
    };    
    
    TChart.prototype.SetDescriptionXRangeIncludeZero = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
        {
            this.descriptionXRangeIncludeZero = YN;
        }
    };

    TChart.prototype.SetAutoDescriptionX = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
        {
            this.autoDescriptionX = YN;
            this.AutoX();
        }
    };    

    TChart.prototype.SetDescriptionAxisY = function(d){
        if (typeof d !== 'undefined' && d !== null)
        {
            var i;
            this.descriptionAxisY = [];
            for (i = 0;i < d.length;i++)
            {
                if (typeof d[i] !== 'undefined' && d[i] !== null && IsNumeric(d[i]))
                    this.descriptionAxisY[i] = parseFloat(d[i]);
            }
        }
    };    

    TChart.prototype.SetDescriptionAxisYTextTXT = function(d){
        if (typeof d !== 'undefined' && d !== null)
        {
            var i;
            this.descriptionAxisYText = [];
            for (i = 0;i < d.length;i++)
            {
                if (typeof d[i] !== 'undefined' && d[i] !== null && d[i].IsType('TPageElement'))
                    this.descriptionAxisYText[i] = d[i].GetTXT();
            }
        }
    };    

    TChart.prototype.SetDescriptionYWidthAxisArrow = function(s){
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.descriptionYWidthAxisArrow = s;
    };    
    
    TChart.prototype.SetDescriptionYRangeIncludeZero = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
        {
            this.descriptionYRangeIncludeZero = YN;
        }
    };

    TChart.prototype.SetAutoDescriptionY = function(YN){
        if (typeof YN !== 'undefined' && YN !== null)
        {
            this.autoDescriptionY = YN;
            this.AutoY();
        }
    };    

    TChart.prototype.SetDescriptionSeparator = function(s){
        if (typeof s !== 'undefined' && s !== null && s.IsType('TPageElement'))
            this.descriptionSeparator = s.GetTXT();
        else
            this.descriptionSeparator = '.';
    };    
    
    TChart.prototype.SetXLabel = function(l){
        if (typeof l !== 'undefined' && l !== null && l.IsType('TPageElement'))
            this.xLabel = l.GetTXT();
        else
            this.xLabel = null;
    };    

    TChart.prototype.SetShiftXLabel = function(s){
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.shiftXLabel = s;
    };    

    TChart.prototype.SetYLabel = function(l){
        if (typeof l !== 'undefined' && l !== null && l.IsType('TPageElement'))
            this.yLabel = l.GetTXT();
        else
            this.yLabel = null;
    };    

    TChart.prototype.SetShiftYLabel = function(s){
        if (typeof s !== 'undefined' && s !== null && IsNumeric(s))
            this.shiftYLabel = s;
    };    

    TChart.prototype.AddChart = function(chart){
        if (typeof chart !== 'undefined' && chart !== null && chart.IsType('TCharts'))
        {
            this.charts[this.charts.length] = chart;
            this.AutoX();
            this.AutoY();
        }
    };    

    TChart.prototype.GetCharts = function(chart){
        return this.charts;
    };    

    TChart.prototype.SetLegend = function(l){
        if (typeof l !== 'undefined' && l !== null && l.IsType('TChartLegend'))
            this.legend = l;
    };    

    TChart.prototype.ChangeSeparator = function(txt,sep){
        var res = null;
        if (typeof txt !== 'undefined' && txt !== null)
        {
            if (typeof sep !== 'undefined' && sep !== null)
            {
                res = '';
                var i;
                for (i = 0;i<txt.length;i++)
                {
                    if (txt[i] === '.')
                        res = res + sep;
                    else
                        res = res + txt[i];
                }
//                res = res.toString();
            }else
                return txt;
        }        
        
        return res;
    };

    TChart.prototype.AutoDescription = function(min_,max_){
        var res = [];
        res[0] = [];
        res[1] = [];
        if (typeof min_ !== 'undefined' && min_ !== null && IsNumeric(min_) && typeof max_ !== 'undefined' && max_ !== null && IsNumeric(max_))
        {
            var multi = 1,type = 1,multi2 = 1;
            var range = max_-min_;
            var tmpMin,tmpMax,step,i,j;
            for (;;multi = multi/10)
            {
                if (range >= 10*multi)
                {
                    type = 1;
                    break;
                }
            }
            for (;;multi = multi*10)
            {
                if (range <= 10*multi)
                {
                    type = 1;
                    break;
                }
            }
            if (type === 1)
            {
                tmpMax = max_; 
                step = multi;
                if (range/step < 5)
                {
                    step = step/2;
                    multi2 = 2;
                    if (range/step < 5)
                    {
                        step = step*2/5;
                        multi2 = 5;
                    }
                }
                if (step >= 1)
                {
                    tmpMin = Math.round(min_/multi)*multi;
                    for (i = tmpMin,j = 0;i <= tmpMax;i += step,j++)
                    {
                        res[0][j] = i;
                        res[1][j] = i.toString();
                    }
                }else
                {
                    multi = Math.round(1/multi);
                    tmpMin = Math.round(min_*multi*multi2)/(multi*multi2);
                    for (i = tmpMin,j = 0;i <= tmpMax;i += step,j++)
                    {
                        i = Math.round(i*multi*multi2)/(multi*multi2);
                        res[0][j] = i;
                        res[1][j] = this.ChangeSeparator(i.toString(),this.descriptionSeparator);
                    }
                    
                }
            }
        }        
        
        
        return res;
    };
    
    TChart.prototype.AutoX = function(){
        if (this.autoDescriptionX)
        {
            var max_ = null,min_ = null,i,tmp,tmp2,res;
            if (typeof this.charts !== 'undefined' && this.charts !== null)
            {
                for (i = 0;i < this.charts.length;i++)
                {
                    if (typeof this.charts[i] !== 'undefined' && this.charts[i] !== null && this.charts[i].IsType('TCharts'))
                    {
                        tmp = this.charts[i].GetMinDataX();
                        if (tmp !== null)
                        {
                            if (min_ === null)
                                min_ = tmp;
                            else
                                if (min_ > tmp)
                                    min_ = tmp;
                        }
                        tmp2 = this.charts[i].GetMaxDataX();
                        if (tmp !== null)
                        {
                            if (max_ === null)
                                max_ = tmp2;
                            else
                                if (max_ < tmp2)
                                    max_ = tmp;
                        }
                    }
                }
                if (this.descriptionXRangeIncludeZero)
                {
                    if (min_ > 0)
                        min_ = 0;
                    if (max_ < 0)
                        max_ = 0;
                }
                if (min_ !== null)
                    this.xMin = min_;
                if (max_ !== null)
                    this.xMax = max_;
                for (i = 0;i < this.charts.length;i++)
                {
                    if (typeof this.charts[i] !== 'undefined' && this.charts[i] !== null && this.charts[i].IsType('TCharts'))
                    {
                        this.charts[i].SetXMin(this.xMin);
                        this.charts[i].SetXMax(this.xMax);
                    }
                }
                res = this.AutoDescription(min_,max_);
                if (res[0].length > 0)
                {
                    this.descriptionAxisX = res[0];
                    this.descriptionAxisXText = res[1];
                }
            }
        }
    };    


    TChart.prototype.AutoY = function(){
        if (this.autoDescriptionY)
        {
            var max_ = null,min_ = null,i,tmp,tmp2,res;
            if (typeof this.charts !== 'undefined' && this.charts !== null)
            {
                for (i = 0;i < this.charts.length;i++)
                {
                    if (typeof this.charts[i] !== 'undefined' && this.charts[i] !== null && this.charts[i].IsType('TCharts'))
                    {
                        tmp = this.charts[i].GetMinDataY();
                        if (tmp !== null)
                        {
                            if (min_ === null)
                                min_ = tmp;
                            else
                                if (min_ > tmp)
                                    min_ = tmp;
                        }
                        tmp2 = this.charts[i].GetMaxDataY();
                        if (tmp2 !== null)
                        {
                            if (max_ === null)
                                max_ = tmp2;
                            else
                                if (max_ < tmp2)
                                    max_ = tmp2;
                        }
                    }
                }
                if (this.descriptionYRangeIncludeZero)
                {
                    if (min_ > 0)
                        min_ = 0;
                    if (max_ < 0)
                        max_ = 0;
                }
                if (min_ !== null)
                    this.yMin = min_;
                if (max_ !== null)
                    this.yMax = max_;
                for (i = 0;i < this.charts.length;i++)
                {
                    if (typeof this.charts[i] !== 'undefined' && this.charts[i] !== null && this.charts[i].IsType('TCharts'))
                    {
                        this.charts[i].SetYMin(this.yMin);
                        this.charts[i].SetYMax(this.yMax);
                    }
                }
                res = this.AutoDescription(min_,max_);
                if (res[0].length > 0)
                {
                    this.descriptionAxisY = res[0];
                    this.descriptionAxisYText = res[1];
                }
            }
        }
    };    

}

TChart.prototype = new TVisibleFigure();
