/* 
 * Graphics Framework
 * copyright Dimitrios Al. Aggelis
 */
/* global THREE, Detector, ParticleSystem */
"use strict";


//////////////////////////////////////////////////////////////GF ///////////////////////////###################################################////////
                var GF = function () {
                    "use strict";
                    var debug = !true;
                    var debugs = [];

                    var hidelist = [];// opened forms for hide ncdown
                    var edeltay = 0;
                    var interval = 1 / 1111; ///  1/fps
                    var frames = 0;
                    var fps = 0;
                    var fpst = 0;
                    var fpst0 = 0;
                    var logw = 1280;
                    var logh = 720;
                    var mobile = false; // if touch screen mobile=true
                    //var wheeldelta=0;
                    var colorbutton = "#F0F0F1";
                    var colorwin = "cyan";//#00FEFA";
                    var colorbody = "#000000";
                    var colorcheck = "#FCFFE6";
                    var colortext = "#18005C";
                    var colortitle = "#FF9900";
                    var colortitle0 = "#fff0db";
                    var image1;
                    var check1;
                    var check2;
                    var radio1;
                    var radio2;
                    var iconhome;
                    var icontrig;
                    var iconinfo;
                    var iconwave;
                    var clock1;
                    var clock2;
                    var clock3, clock4, clock5, clock6, clock7;
                    var iconrgb;
                    var iconhelp, iconabout, iconclose;
                    var icondropdown;
                    var gsc = 1; //// global scale 
                    var gok = false; /// if all ready then start scene manager 
                    var vectorth = Math.PI * 0.85;
                    var vectorlen = 10;
                    var clicks = []; // list of clicked objects in a scene;
                    var MOUSEDOWN = -1;
                    var MOUSEUP = "MU";//-2;
                    var MOUSEMOVE = -3;
                    var TOUCHSTART = -4;
                    var TOUCHMOVE = -5;
                    var TOUCHEND = -6;
                    var KEYDOWN = -7;
                    var KEYUP = -8;
                    var MOUSEWHEEL = -9;
                    // Find the right method, call on correct element
                    var MULTISTATE = -16; //// 
                    var BUTTONCOMMAND = -17; /// command button with parameter list []
                    var PUSHBUTTON = -18;
                    var SCROLLBAR = -19;
                    var WINDOW = -20,
                            LABEL = -21,
                            BUTTON = -22,
                            VSCROLLBAR = -23,
                            HSCROLLBAR = -24;
                    var LIST = -25,
                            MLIST = -26,
                            CHECK = -27,
                            RADIO = -28,
                            LISTITEM = -29;
                    var SCNEXT = -30, ///// commands 
                            SCPREVIOUS = -31,
                            SCLAST = -32,
                            SCFIRST = -33,
                            SCANY = -34; //// COMMANDS need parameter a scene num
                    var FSON = -38; //fullscreen on
                    var FSOFF = -39; //off
                    var DRAGMOVE = -40;
                    var DRAGCLONE = -41;
                    var APP = -42;
                    var SHAPE = -43;
                    var degtorad = Math.PI / 180.0;
                    var pi = Math.PI;
                    var twopi = 2 * Math.PI;
                    var mousex = 0;
                    var mousey = 0;
                    var pmousex = 0;
                    var pmousey = 0;
                    var mousedx = 0;
                    var mousedy = 0;
                    var key1 = false; //key 1 pressed
                    var mousest = 122; // mousest=  mouse down =1 drag 2 up with drag=2 mst=3(drop)
                    //// mst=4 just up 
                    var mousemove = false;
                    var mousex0 = 0;
                    var mousey0 = 0; /// when drag start
                    var dragx = 0;
                    var dragy = 0; /// x,y of window dragged;
                    var overover = undefined;
                    var pressedobject = undefined;
                    var overobject = undefined; // which instance button downed
                    var inobject = undefined;
                    var overobject2 = undefined;// id dragged previous over
                    var draggedobject = undefined;
                    var clickedobject = undefined;
                    //var pressedpush=undefined; /// which pushbutton pressed
                    var drop = 1;
                    ////////////////////////////////
                    var time0 = 0; // initial millis 
                    var time1 = 0; // current 
                    var time = 0; /// since program startd
                    ///var timescale = 1;
                    var timedelta = 0;
                    ///// canvas, windoww ,winh 
                    //// canvas2 and canvas3d logw logh
                    var keysDown = {
                        mx: 0,
                        my: 0
                    }; // holds keycode if pressed
                    var keycode = -1; ///holds last key cod for test
                    var canvas = document.getElementById("canvas");
                    var canvas2 = document.getElementById("canvas2");
                    var ctx2 = canvas2.getContext("2d");
                    var imageresourcecount = 0;
                    canvas.width = logw; //window.innerWidth; 
                    canvas.height = logh; //window.innerHeight;
                    var ctx = canvas.getContext("2d");
                    var viewtr = new Transform();
                    viewtr.scale(2.0, 2.0);
                    var gtr1 = new Transform(); // global tranforms for debug use;
                    var gtr2 = new Transform();
                    /// --------------  3d globals app start ------------------------
                    var pressedelement = 0; /// will receive window mouse up
                    var raycaster, renderer, stats;
                    var control3d = true; //// no controls cause a form no 3d pressed
                    var focused;
                    //var ratio; /// put by form3d 
                    var container;
                    var INTERSECTED = null;
                    var can3d = false;
                    var canvas3d;
                    //------------------------------------------------- 
                    function getlastchild() {
                        if (clicks.length > 0)
                            return clicks[clicks.length - 1];
                        return undefined;
                    } /// 
                    //
                    // 
                    function getpreviouschild() {
                        if (clicks.length > 1)
                            return clicks[clicks.length - 2];
                        return undefined;
                    } /// 
                    function unpress(aw) {
                        if (aw)
                            aw.pressed = 0;
                    } /// 
                    //
                    function obtitle(ob) {
                        if (ob === undefined)
                            return "none";
                        return ob.id + " " + ob.kind;
                    }
                    ;

                    function objectcompare(ob1, ob2) {
                        if (!ob1)
                            return false;
                        if (!ob2)
                            return false;
                        return (ob1 === ob2);
                    }
                    ;
                    // Handle keyboard controls
                    function setmouse(e, type) {
                        var rect = canvas.getBoundingClientRect();
                        mousex = e.clientX - rect.left;
                        mousey = e.clientY - rect.top;
                        var inv = new Transform(viewtr);
                        inv.invert();
                        //*************    mousex mouse y transformed by view 
                        var poi = inv.transformPoint(mousex, mousey);
                        mousex = poi[0];
                        mousey = poi[1];
                        ///***********
                        mousemove = false;
                        if (type === MOUSEWHEEL) {
                            // wheeldelta+=e.deltaY;
                            sm.onevent(e, type);
                        }
                        if (type === MOUSEDOWN) {
                            mousest = 1;
                            mousex0 = mousex;
                            mousey0 = mousey; // for drag  
                            sm.onevent(e, MOUSEDOWN);
                        }
                        if (type === MOUSEUP) {
                            if (mousest === 2) {
                                mousest = 3;
                            } else {
                                mousest = 4;
                            }
                            sm.onevent(e, MOUSEUP);
                        }
                        if (type === MOUSEMOVE) {
                            if (mousest === 1) {
                                mousest = 2;
                            }
                            ;
                            if (mousest === 2)
                                mousemove = true;
                            sm.onevent(e, MOUSEMOVE);
                        }
                    }
                    ; /// set mouse 
                    // 
                    function setkeys(e, type) {
                        if (type === KEYDOWN) {
                            sm.onevent(e, "KEYDOWN");
                        }
                        if (type === KEYUP) {
                            sm.onevent(e, "KEYUP");
                        }
                        keycode = e.keyCode;
                    }
                    ;

                    function initialize() { //// ------------E v e n t   f r o m  O S    -----------------------------
                        /// class        
                        // Register an event listener to call the resizeCanvas() function 
                        // each time the window is resized.
                        addEventListener('resize', onresize, false);
                        addEventListener("wheel", function (e) {
                            setmouse(e, MOUSEWHEEL);
                        }, false);
                        //window.addEventListener('orientationchange', resizeCanvas,false);
                        addEventListener("keydown", function (e) {
                            keysDown[e.keyCode] = true;
                            setkeys(e, KEYDOWN);
                            e.preventDefault();
                        }, false);
                        addEventListener("keyup", function (e) {
                            delete keysDown[e.keyCode];
                            setkeys(e, KEYUP);
                            e.preventDefault();
                            if (keycode === 33) {
                                keycode = -1;
                                fullscreenon();
                            }
                            if (keycode === 34) {
                                keycode = -1;
                                fullscreenoff();
                            }
                        }, false);
                        addEventListener("mousedown", function (e) {
                            setmouse(e, MOUSEDOWN);
                            e.preventDefault();
                        }, true);
                        addEventListener("mousemove", function (e) {
                            setmouse(e, MOUSEMOVE);
                            e.preventDefault();
                        }, !false);
                        addEventListener("mouseup", function (e) {
                            setmouse(e, MOUSEUP);
                            e.preventDefault();
                        }, !false);
                        addEventListener("touchstart", function (e) {
                            mobile = true; /// touch down no mouse  
                            var touchobj = e.changedTouches[0];
                            e.preventDefault();
                            setmouse(touchobj, MOUSEDOWN);
                        }, false);
                        addEventListener("touchmove", function (e) {
                            var touchobj = e.changedTouches[0];
                            e.preventDefault();
                            setmouse(touchobj, MOUSEMOVE);
                        }, false);
                        addEventListener("touchend", function (e) {
                            var touchobj = e.changedTouches[0];
                            e.preventDefault();
                            setmouse(touchobj, MOUSEUP);
                        }, false);
                        onresize();
                    }

                    function resizecanvas() {

                        canvas.width = window.innerWidth;
                        canvas.height = canvas.width * logh / logw;
                        var px = 0;
                        var py = (window.innerHeight - canvas.height) / 2;
                        if (canvas.height > window.innerHeight) {
                            canvas.height = window.innerHeight;
                            canvas.width = canvas.height * logw / logh;
                            py = 0;
                            px = (window.innerWidth - canvas.width) / 2;
                        }
                        setelementpos(canvas, px, py);
                        if (can3d && canvas3d)
                            setelementpos(canvas3d, px, py);
                        //canvas3d.width = canvas.width;
                        // canvas3d.height = canvas.height;
                        // var wsc=canvas.width/logw;
                        //var ifr=getelement("iframehelp");
                        //var icw=ifr.contentWindow.document.body;
                        /// ifr.width  =icw.scrollWidth/4;
                        //ifr.height =icw.scrollHeight/4;
                        // alert  (ifr.width)
                        //scaleelement(getelement("help"),gsc,gsc);
                    }

                    function onresize() {
                        //canvas.width =   window.innerWidth;
                        //canvas.height =  window.innerHeight;
                        resizecanvas();
                        sm.onresize();
                    }
                    //------------------   definition classes
                    //
                    //
                    //
                    //
                    function Key(t, value) {
                        this.t = t;
                        this.value = value; /// eg 

                    }
                    Key.prototype.setkey = function (t, value) {
                        this.t = t;
                        this.value = value;
                    }

                    function Animation(kind) {
                        this.kind = kind; /// "xy", "rot" "a" "col1" "col2"
                        this.keys = [];
                        this.kind = "";

                    }
                    Animation.prototype.addkey = function (t, value) {
                        this.keys.push(new Key(t, value));
                    }
                    Animation.prototype.addkeys = function (kind, array) {
                        /// eg ("rot" ,[0,[4],7,[66] ...]) 
                        this.kind = kind;
                        var i;
                        for (i = 0; i < array.length / 2; i++) {
                            this.addkey(array[i * 2], array[2 * i + 1]);

                        }
                    }
                    Animation.prototype.setkey = function (akey, pos) {
                        if (pos >= this.keys.length)
                            return;
                        this.keys[pos].t = akey.t;
                        this.keys[pos].value = akey.value;
                    }
                    Animation.prototype.insertkey = function (t, value) {
                        var keys = this.keys;
                        var nk = new Key(t, value);
                        if (t < keys[0].t) {

                            keys.splice(0, 0, nk);
                            return 0;
                        }
                        var j;
                        for (j = 0; j < keys.length - 1; j++) {
                            if (keys[j].t <= t && keys[j + 1].t > t) {
                                keys.splice(j + 1, 0, nk);
                                return j + 1;

                            }

                        }

                        keys.push(nk);
                        return (keys.length - 1);
                    }
                    Animation.prototype.setperiod = function (at) {
                        var i;
                        var totl = 0;
                        var le = [];

                        var keys = this.keys;
                        var t2 = keys[0].t;
                        if (this.kind === "xy") {
                            le.push(t2);
                            for (i = 0; i < this.keys.length - 1; i++) {
                                var cl = length(keys[i].value[0], keys[i].value[1], keys[i + 1].value[0], keys[i + 1].value[1]);
                                totl += cl;
                                le.push(totl);
                            }

                            for (i = 1; i < this.keys.length; i++) {
                                keys[i].t = t2 + le[i] / totl * at;

                            }

                        }
                    }


                    Animation.prototype.getvalue = function (t) {
                        var i, j;
                        var keys = this.keys;


                        var array = [];
                        for (j = 0; j < keys[0].value.length; j++) {

                            array[j] = keys[0].value[j]

                        }

                        for (i = 0; i < keys.length - 1; i++) {
                            //
                            if (t <= keys[i + 1].t && t >= keys[i].t) {
                                for (j = 0; j < keys[i].value.length; j++) {

                                    array[j] = keys[i].value[j] + (keys[i + 1].value[j] - keys[i].value[j]) * (t - keys[i].t) / (keys[i + 1].t - keys[i].t)

                                }

                            }
                        }
                        return array;
                    }
                    function Animator(man) {
                        this.manager = man; /// get dt listener etc
                        this.animation = 0;/// no 
                        this.playing = false;
                        this.t = 0;
                        this.t0 = 0;  ///// when start?
                        this.tofset = 0;   //// t ofset
                        this.form = 0;
                        this.value = [];// 
                        this.loop = false;


                    }
                    //Animator.prototype.addanimation = function (aanim) {
                    //    this.animations.push(aanim);
                    //}
                    Animator.prototype.update = function (dt) {
                        //this.t += this.manager.dt;///dt * !this.manager.stopped;///this.playing;
                         this.t=this.manager.t;
                        if (this.t < 0)
                            this.t = 0;
                        var t1 = this.t - this.t0;
                        var mt = this.maxt();
                        if (t1 > mt)
                            t1 = mt;
                        if (this.loop)
                            t1 = this.t % this.maxt();

                        this.getvalue(t1);
                        this.updateform();

                    }
                    Animator.prototype.getvalue = function (t) {

                        this.value = this.animation.getvalue(t)



                    }
                    Animator.prototype.updateform = function () {

                        /// apply to form  

                        if (this.animation.kind === "rot") {


                            this.form.rot = this.value[0];
                        }

                        if (this.animation.kind === "xy") {

                            this.form.x = this.value[0];
                            this.form.y = this.value[1];
                        }
                    }
                    Animator.prototype.addkeys = function (kind, array) {
                        if (!this.animation)
                            this.animation = new Animation(kind)
                        this.animation.addkeys(kind, array);
                        this.manager.anims.push(this);

                    }
                    Animator.prototype.reset = function (stop) {

                        this.t = 0;
                        if (stop)
                            this.stop();
                    }
                    Animator.prototype.restart = function (stop) {
                        this.reset(stop);
                        this.start();
                    }
                    Animator.prototype.start = function () {
                        this.form.stopped = false;
                        this.playing = true;

                    }
                    Animator.prototype.stop = function () {
                        this.form.stopped = true;
                        this.playing = false;
                    }
                    Animator.prototype.maxt = function () {
                        var n = this.animation.keys.length;
                        // if(n>1){
                        return this.animation.keys[n - 1].t
                        //}
                        //  return this.animation.keys[0].t
                    }


                    /// class         ---------------------------- ImageResource     -----------------------------
                    function ImageResource(filename) {
                        this.filename = filename;
                        this.image = new Image();
                        this.isready = false;
                        this.imw;
                        this.imh;
                        //this.ratio;
                        var other = this;
                        this.image.onload = function () {
                            other.onloadcall();
                        };
                        this.image.src = filename;
                        imageresourcecount++;
                        this.onloadcall = function () {
                            this.imw = this.image.naturalWidth;
                            this.imh = this.image.naturalHeight;
                            //this.ratio=this.imw/this.imh;
                            this.isready = true;
                            imageresourcecount--;

                        };
                        this.draw = function (ctx, x, y) {
                            if (this.isready) {
                                ctx.drawImage(this.image, x, y);
                            }
                        };
                    } //// end ImageResource definition
                    /// class         ---------------------------- Actor    -----------------------------
                    function BBox() {
                        this.init();
                    }
                    BBox.prototype.init = function () {
                        this.xmin = Number.MAX_VALUE;
                        this.ymin = Number.MAX_VALUE;
                        this.zmin = Number.MAX_VALUE;
                        this.xmax = Number.MIN_VALUE;
                        this.ymax = Number.MIN_VALUE;
                        this.zmax = Number.MIN_VALUE;
                    };
                    BBox.prototype.addpoint = function (x, y, z) {
                        this.xmin = Math.min(x, this.xmin);
                        this.xmax = Math.max(x, this.xmax);
                        this.ymin = Math.min(y, this.ymin);
                        this.ymax = Math.max(y, this.ymax);
                        this.zmin = Math.min(z, this.zmin);
                        this.zmax = Math.max(z, this.zmax);
                    };



                    function Actor(imres, x, y, rot, scx, scy) {
                        this.imres = imres;
                        this.pivotx = 128;
                        this.pivoty = 16;
                        this.x = x;
                        this.y = y;
                        this.rot = rot;
                        this.scx = scx;
                        this.scy = scy;
                        this.v = 0;
                        this.v0 = 0;
                    }
                    Actor.prototype.draw = function (ctx) {
                        if (this.imres.isready) {
                            ctx.save();
                            ctx.translate(this.x, this.y);
                            ctx.rotate(this.rot * degtorad);
                            ctx.scale(this.scx, this.scy);
                            ctx.translate(-this.pivotx, -this.pivoty);
                            ctx.drawImage(this.imres.image, 0, 0);
                            ctx.restore();
                        }
                    };

                    function Actor2(imres, x, y, rot, scx, scy) {
                        Actor.call(this, imres, x, y, rot, scx, scy);
                    }
                    Actor2.prototype = Object.create(Actor.prototype);
                    Actor2.prototype.constructor = Actor2;
                    Actor2.prototype.draw = function (ctx) {
                        Actor.prototype.draw.call(this, ctx);
                    };

                    /// close opened forms eg menus drop downs 

                    function Hitarea(x, y, w, h) {
                        this.x = x;
                        this.y = y;
                        this.w = w;
                        this.h = h;
                        this.type = "rect"; /// oval ngon line 
                        this.p = [];

                    }
                    ;


                    /// class         ---------------------------- F o r m    -----------------------------////////////////////////////////////////////////
                    function Form(id, title, x, y, width, height, imageres) {
                        "use strict"
                        /// this.messages=[];////// message box for messages

                        this.transformable = false;

                        this.tr = new Transform();
                        this.wtr = new Transform(); // view * tr
                        this.tx = x;
                        this.ty = y;
                        this.scx = 1;
                        this.scy = 1;
                        this.rot = 0;
                        this.pivx = 0;
                        this.pivy = 0;
                        this.animators = [];
                        this.anims=[];
                        this.stretch = !true;
                        this.astep = 0;
                        this.wrap = false;
                        this.shadow = false;
                        this.shadowdx = 3;
                        this.shadowdy = 3;
                        this.shadowcolor = "lightgrey";
                        this.tasks = [];
                        this.lastx = 0;
                        this.lasty = 0;
                        this.lastx1 = 0;
                        this.lasty1 = 0;
                        this.lastx2 = 0;
                        this.lasty2 = 0;
                        this.lastlen = 0;
                        this.lastt = 0;
                        this.lastth = 0;

                        this.tooltip = undefined;// 
                        this.hitareas = [];
                        this.ctx = ctx;
                        this.cursor = "default";
                        this.picktype = 1; /// 1 rect 2  ellipse contains overrid e else i     //

                        this.wheeldelta = 0;
                        //// if want clip ellipse clip(1);
                        this.cliptype = 0; /// 0 no clip 1 cliprect 2 clip circle; else override clip
                        this.composition = "source-over";
                        this.visible = true; /// use it in custom draw
                        this.drawbackground = true;
                        this.drawoutline = false;
                        this.corner = 0; //if corner>0 draws roundrect outline
                        this.clipped = false; // if clipped  then clips children too;
                        this.commandlist = []; //   at any not defined go menu // 
                        this.command = 0; ///no command 
                        this.t = 0; ///time
                        this.dt = 0;
                        this.timescale = 1;
                        this.stopped = true;
                        this.pickable = true;
                        ////// update in draw;
                        this.id = id; /// no command  = 0 

                        ///------------------------values--------------------
                        this.min = 0;
                        this.max = 100;
                        this.value = 33; /// case scroll bar;

                        this.valuename = "";
                        this.valueunit = "";
                        this.valuedigits = 2; // accuracy;
                        this.valuedraw = false;
                        this.valuex = 0;
                        this.valuey = 0;
                        this.kind = WINDOW;
                        this.subkind = 0; /// or radio ///
                        ///// if subkind =check then multi and appropriate images
                        ////-----------------------
                        //// if list ,mlist, check box, radio button
                        this.checked = false; //// usefull as child
                        this.selecteditem; /// last  checked each time usefull for list and radios
                        this.selindex = -1;
                        this.state = 0;
                        //this.numstates = 0; //// for multistate count childs 
                        this.multiselect = false; //false;
                        this.rows = 1; /// update columns; rows auto;
                        this.cols = 1;
                        this.backcolor = colorwin;
                        this.textcolor = colortext;
                        this.linecolor = "grey";
                        this.lw = 1.33;
                        this.draggable = false;
                        this.dropable = false;
                        this.dragtype = 0; /////  DRAGMOVE ,DRAFCLONE ;
                        this.droptypes = [];
                        ////////////////this.sm=0; //////no  scene manager no notify  //// 
                        this.pressed = 0;
                        this.depressed = 1;
                        this.texth = 20; //text height 
                        this.textcentered = true; //center left
                        this.texthor = "";
                        this.texver = "";
                        this.parent = 0;
                        if (imageres !== undefined)
                            this.imageres = imageres;
                        this.title = title;
                        this.x = x; /// local
                        this.y = y;
                        this.xg = x; /// global by getparentpos;
                        this.yg = y; /// 
                        this.x0 = x;
                        this.y0 = y;
                        this.width = width;
                        this.height = height;
                        this.texts = []; /// 
                        this.childs = []; ///
                        this.xorig = 0; /// functions xo;yorigin
                        this.yorig = 0;
                        this.clickx = 0;
                        this.clicky = 0; /// for click pos in win (local coords)
                        this.setorigin(0, 0);
                        this.limited = false;
                        this.limit1x = 0;
                        this.limit1y = 0;
                        this.limit2x = 0;
                        this.limit2y = 0;
                        //this.setpickarea(0, 0, width, height);
                        this.setpickarea(0, 0, 0, 0);
                    } // end window definition 
                    Form.prototype.getanimforms = function (ar, anlist) {


                        if (this.animators.length > 0)
                            ar.push(this)
                        var j;

                        for (j = 0; j < this.animators.length; j++) {

                            anlist.push(this.animators[j]);
                        }
                        var i;
                        for (i = 0; i < this.childs.length; i++) {
                            this.childs[i].getanimforms(ar, anlist);
                        }

                    }
                    Form.prototype.pivot = function (fx, fy) {
                        this.pivx = fx * this.width;
                        this.pivy = fy * this.height;
                    }

                    Form.prototype.gettimedelta = function ( ) {
                        return timedelta;
                    }

                    Form.prototype.addanimator = function (man) {
                        var na = new Animator(man);
                        na.form = this;
                        this.animators.push(na);
                        return na;
                    }
                    Form.prototype.transform = function ( ) {
                        this.tr.copy(viewtr);
                        //this.tr.translate(this.tx  - this.parent.xg +this.xg, this.ty -this.parent.yg +this.yg);
                        this.tr.translate(this.tx, this.ty);

                        this.tr.rotate(this.rot);
                        this.tr.scale(this.scx, this.scy);
                        this.tr.translate(-this.pivx, -this.pivy);
                        settransform(ctx, this.tr);
                    }

                    Form.prototype.addtask = function (atype, aperiod, alife) {
                        var nt = new Task(atype, aperiod, alife);
                        nt.form = this;
                        this.tasks.push(nt);
                        return nt;
                    }
                    Form.prototype.debug = function (varname, value) {

                        debugs.push(varname + ":" + value);
                    }
                    Form.prototype.move = function (ax, ay) {

                        this.x = ax;
                        this.y = ay;
                    }
                    Form.prototype.vectorlength = function (len) {

                        vectorlen = len;
                    }
                    Form.prototype.vectortheta = function (th) {

                        vectorth = th;
                    }
                    Form.prototype.addhitarea = function (x, y, w, h, type) {
                        var nha = new Hitarea(x, y, w, h);
                        var ntype = type || "rect";
                        nha.type = ntype;
                        this.hitareas.push(nha);
                    }
                    Form.prototype.setpickarea = function (dx, dy, w, h, picktype) {
                        this.hitdx = dx;
                        this.hitdy = dy;
                        this.hitdw = w;
                        this.hitdh = h;
                        var ntype = picktype || 1;
                        this.picktype = ntype;
                    }
                    Form.prototype.drawhitareas = function (ctx) {
                        var i;
                        this.styles("green", "black");
                        //ctx.beginPath();
                        this.drawrect(0, 0, this.width, this.height, 0);
                        ctx.stroke();
                        for (i = 0; i < this.hitareas.length; i++) {
                            this.styles("green", "black");
                            //ctx.beginPath();
                            ctx.rect(this.hitareas[i].x + this.xg, this.hitareas[i].y + this.yg, this.hitareas[i].w, this.hitareas[i].h);
                            ctx.stroke();
                        }
                    }

                    Form.prototype.getpressed = function () {
                        return pressedobject;
                    }
                    Form.prototype.limit = function (aminx, aminy, amaxx, amaxy) {

                        this.limited = true;
                        this.limit1x = aminx;
                        this.limit1y = aminy;
                        this.limit2x = amaxx;
                        this.limit2y = amaxy;
                        this.dolimit();

                    }
                    Form.prototype.unlimit = function (aminx, aminy, amaxx, amaxy) {

                        this.limited = false;

                    }
                    Form.prototype.dolimit = function ( ) {
                        if (this.x < this.limit1x)
                            this.x = this.limit1x;
                        if (this.y < this.limit1y)
                            this.y = this.limit1y;
                        if (this.x > this.limit2x)
                            this.x = this.limit2x;
                        if (this.y > this.limit2y)
                            this.y = this.limit2y;
                    }
                    Form.prototype.sendmessage = function (msg) {
                        sm.messages.push(msg);
                    }

                    Form.prototype.getmousepos = function () {
                        return {x: mousex - this.xg, y: mousey - this.yg};
                    }
                    Form.prototype.getmouseposglobal = function () {
                        return {x: mousex, y: mousey};
                    }
                    Form.prototype.getmousest = function () {
                        return mousest;
                    }
                    Form.prototype.tofront = function (ch) {
                        for (var i = 0; i < this.childs.length; i++) {

                            if (ch === this.childs[i]) {
                                var tmp = this.childs[i];
                                var j;
                                for (j = i; j < this.childs.length - 1; j++) {
                                    this.childs[j] = this.childs[j + 1];
                                }
                                this.childs[this.childs.length - 1] = tmp;
                                return;

                            }

                        }

                    }
                    Form.prototype.getcanvas2 = function () {
                        return canvas2;
                    }
                    Form.prototype.getdragged = function () {
                        return draggedobject;
                    }
                    Form.prototype.getover = function () {
                        return overobject;
                    }
                    Form.prototype.getover2 = function () {
                        return overobject2;
                    }
                    Form.prototype.center = function () {
                        this.centerhor();
                        this.centerver();

                    }
                    Form.prototype.centerforms = function (s, d) {

                        d.x = s.x + s.width / 2 - (d.width / 2);
                        d.y = s.y + s.height / 2 - (d.height / 2);

                    }
                    Form.prototype.centerhor = function () {
                        var nx = 0;
                        if (this.parent)
                            nx = (this.parent.width - this.width) / 2;
                        else
                            nx = (logw - this.width) / 2;
                        this.x = nx;

                    }
                    Form.prototype.centerver = function () {
                        var nv = 0;
                        if (this.parent)
                            nv = (this.parent.height - this.height) / 2;
                        else
                            nv = (logh - this.height) / 2;
                        this.y = nv;
                    }
                    Form.prototype.bottom = function (d) {
                        var nv = 0;
                        if (this.parent)
                            nv = this.parent.height - this.height - d;
                        else
                            nv = logh - this.height - d;
                        this.y = nv;
                    }
                    Form.prototype.right = function (d) {
                        var nv = 0;
                        if (this.parent)
                            nv = this.parent.width - this.width - d;
                        else
                            nv = logw - this.width - d;
                        this.x = nv;
                    }

                    Form.prototype.backout = function (drawbackground, drawoutline) {
                        this.drawbackground = drawbackground;
                        this.drawoutline = drawoutline || false;
                    }
                    Form.prototype.setvaluepos = function (ax, ay) {
                        this.valuex = ax;
                        this.valuey = ay;
                    }
                    Form.prototype.setvaluedescr = function (aname, aunit, adigits) {
                        this.valuename = aname;
                        this.valueunit = aunit;
                        this.valuedigits = adigits;
                    }
                    Form.prototype.create = function () {}
                    Form.prototype.init = function () {}
                    Form.prototype.update = function () {


                    }
                    Form.prototype.render = function () {}
                    Form.prototype.setbackcolor = function (r, g, b, a) {
                        this.backcolor = rgba(r, g, b, 1 || a);
                    }

                    Form.prototype.drawimagetr = function (imageres, tx, ty, rot, sx, sy, pivx, pivy) {
                        if (imageres.isready) {
                            ctx.save();
                            rot = rot || 0;
                            sx = sx || 1;
                            sy = sy || 1;
                            pivx = pivx || 0;
                            pivy = pivy || 0;
                            //var tr2 = new Transform(viewtr);
                            this.tr.copy(viewtr);
                            this.tr.translate(tx + this.xg, ty + this.yg);
                            this.tr.rotate(rot);
                            this.tr.scale(sx, sy);
                            this.tr.translate(-pivx, -pivy);
                            // ***tr2.translate(pivx, pivy);
                            settransform(ctx, this.tr);


                            ctx.drawImage(imageres.image, 0, 0);


                            ctx.restore();
                        }

                    }
                    Form.prototype.fillimage = function () {
                        if (!this.imageres)
                            return;
                        if (!this.imageres.image)
                            return;
                        this.ctx.drawImage(this.imageres.image, 0 + this.xg, 0 + this.yg, this.width, this.height);
                    }
                    Form.prototype.drawimage = function (imageres, tw, th, centered) {
                        if (!imageres)
                            return;
                        if (!imageres.image)
                            return;
                        var imw = imageres.imw;
                        if (!imw)
                            imw = logw;
                        var imh = imageres.imh;
                        if (!imh)
                            imh = logh;
                        var nw, nh;
                        nw = tw;
                        nh = tw * imh / imw;
                        var px = 0;
                        var py = (th - nh) / 2;
                        if (nh > th) {
                            nh = th;
                            nw = th * imw / imh;
                            py = 0;
                            px = (tw - nw) / 2;
                        }
                        if (!centered) {
                            px = 0;
                            py = 0
                        }

                        ctx.drawImage(imageres.image, this.xg + px, this.yg + py, nw, nh);
                    }
                    Form.prototype.drawimageto = function (imageres, x, y) {
                        if (!imageres)
                            return;
                        if (!imageres.image)
                            return;

                        ctx.drawImage(imageres.image, this.xg + x, this.yg + y);
                    }
                    Form.prototype.drawimagefill = function (imageres) {
                        if (!imageres)
                            return;
                        if (!imageres.image)
                            return;

                        ctx.drawImage(imageres.image, this.xg + 0, this.yg + 0, this.width, this.height);
                    }
                    Form.prototype.drawpolar = function (x, y, r, thrad) {
                        drawpolar(ctx, x + this.xg, this.yg + y, r, thrad);
                    }
                    Form.prototype.clip = function () {
                        ctx.save();
                        var v = this.getparentpos();
                        ctx.beginPath();
                        ctx.lineWidth = "3";
                        if (this.cliptype === 1)
                            ctx.rect(v.x, +v.y, this.width, this.height);
                        if (this.cliptype === 2)
                            ctx.arc(v.x + this.width / 2, v.y + this.width / 2, this.width / 2, 0, twopi, false);
                        ctx.clip();
                    }
                    Form.prototype.drawvector = function (x1, y1, x2, y2) {
                        var thrad = Math.atan2(y2 - y1, x2 - x1);
                        var r = Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
                        if (r < 1)
                            return;
                        var vl = vectorlen;
                        if (vectorlen > r / 2)
                            vl = r / 2;
                        this.drawpolar(x1, y1, r, thrad);
                        this.drawpolar(x2, y2, vl, thrad + vectorth);
                        this.drawpolar(x2, y2, vl, thrad - vectorth);
                    }
                    Form.prototype.drawvectorrev = function (x1, y1, x2, y2) {

                        this.drawvector(x2, y2, x1, y1)
                    }
                    Form.prototype.drawpolarvector = function (x, y, r, thrad) {
                        this.drawvector(x, y, x + r * Math.cos(thrad), y + r * Math.sin(thrad));
                    }
                    Form.prototype.dptolp = function (ax, ay) {
                        /// tr -1 *  viewtr -1
                        var inv = new Transform(this.tr);
                        inv.invert();
                        var sec = new Transform(viewtr);
                        sec.invert();
                        inv.multiply(sec);
                        return inv.transformPoint(ax, ay)
                    };
                    Form.prototype.lptodp = function (ax, ay) {
                        var inv = new Transform(this.wtr);
                        inv.invert();
                        //inv.multiply(this.tr);
                        return inv.transformPoint(ax, ay)
                    };
                    Form.prototype.setorigin = function (xo, yo) {
                        var v = this.getparentpos();
                        this.xorig = v.x + xo;
                        this.yorig = v.y + yo;
                    }

                    Form.prototype.drawarcfilled = function (xo, yo, r, st, en, anticlock, linestyle) {
                        if (linestyle)
                            ctx.fillStyle = linestyle;
                        ctx.beginPath();

                        st = twopi - st;
                        en = twopi - en;
                        if (st > en) {
                            var tmp = st;
                            st = en;
                            en = tmp;
                        }
                        ctx.moveTo(xo + this.xorig, this.yorig - yo);
                        ctx.arc(xo + this.xorig, this.yorig - yo, r, st, en, anticlock);
                        ctx.fill();
                    }
                    Form.prototype.drawfilltext = function (str, x, y, linestyle) {
                        if (linestyle)
                            ctx.fillStyle = linestyle;
                        ctx.fillText(str, x + this.xorig, -y + this.yorig);
                    }

                    Form.prototype.drawcirclefilled = function (xo, yo, r, linestyle) {
                        this.drawarcfilled(xo, yo, r, 0, twopi, false, linestyle);
                    }
/// to parabola
//
//
                    Form.prototype.drawparabola = function (a, xo, yo, x1, x2, n, closed, filled) {
                        var i;
                        ctx.beginPath();
                        var x, y;
                        var dx, dy;
                        for (i = 0; i <= n; i++) {
                            x = x1 + i * (x2 - x1) / n;
                            y = a * x * x;
                            dx = x + xo + this.xg;
                            dy = y + yo + this.yg;
                            if (i === 0)
                                ctx.moveTo(dx, dy);
                            else
                                ctx.lineTo(dx, dy);

                        }
                        ctx.stroke();

                    }
                    ///no origin //////////////
                    Form.prototype.drawarc = function (xo, yo, r, st, en, anticlock, closed, filled) {
                        drawarc(ctx, xo + this.xg, yo + this.yg, r, st, en, anticlock, closed, filled)
                    }

                    ///  ok
                    Form.prototype.drawcircle = function (xo, yo, r, filled) {
                        drawarc(ctx, xo + this.xg, yo + this.yg, r, 0, twopi, true, true, filled)
                    }
                    /// no origin 
                    Form.prototype.drawbezier = function (x0, y0, x1, y1, x2, y2, x, y, filled, closed) {
                        var filled = filled || 0;
                        var closed = closed || false;
                        ctx.beginPath();
                        ctx.moveTo(x0 + this.xg, y0 + this.yg);
                        ctx.bezierCurveTo(x1 + this.xg, y1 + this.yg, x2 + this.xg, y2 + this.yg, x + this.xg, y + this.yg);
                        if (closed)
                            ctx.endPath();
                        if (filled === 0 || filled === 2)
                            ctx.stroke();
                        if (filled === 1 || filled === 2)
                            ctx.fill();

                    }
                    Form.prototype.drawrectform = function (f, filled) {

                        drawrect(ctx, f.xg, f.yg, f.width, f.height, filled);
                    }

                    /// no origin 
                    Form.prototype.drawtextform = function (f, text, size, centerleft) {

                        drawtext(ctx, text, f.width / 2 + f.xg, f.height / 2 + f.yg, size, centerleft);
                    }
                    /// no origin 
                    Form.prototype.lineargrad = function (x1, y1, x2, y2) {

                        return this.ctx.createLinearGradient(this.xg + x1, this.yg + y1, this.xg + x2, this.yg + y2);
                    }
                    Form.prototype.radialgrad = function (x1, y1, r1, x2, y2, r2) {

                        return this.ctx.createRadialGradient(this.xg + x1, this.yg + y1, r1, this.xg + x2, this.yg + y2, r2);
                    }
                    Form.prototype.drawrect = function (x1, y1, w, h, filled) {

                        drawrect(ctx, x1 + this.xg, y1 + this.yg, w, h, filled);
                    }
                    Form.prototype.styles = function (ls, fs) {
                        styles(ctx, ls, fs);
                    }

                    Form.prototype.lineargradient = function (x1, y1, x2, y2) {
                        var grd = ctx.createLinearGradient(x1 + this.xg, y1 + this.yg, x2 + this.xg, y2 + this.yg);
                        return grd;
                    }

                    Form.prototype.drawcylinder = function (x1, y1, w, h, filled) {
                        ctx.beginPath();
                        var dx = w / 3;
                        var dy = w / 6;
                        var xi = x1 + this.xg;
                        var yi = y1 + this.yg
                        ctx.moveTo(xi, yi);
                        ctx.bezierCurveTo(xi, yi - dy, xi + w, yi - dy, xi + w, yi);
                        ctx.lineTo(xi + w, yi + h);
                        ctx.bezierCurveTo(xi + w, yi + h + dy, xi, yi + h + dy, xi, yi + h);
                        ctx.closePath();
                        if (filled)
                            ctx.fill();
                        ctx.stroke();
                    }
                    Form.prototype.drawcylinderfront = function (x1, y1, w, h, filled) {
                        ctx.beginPath();
                        var dx = w / 3;
                        var dy = w / 6;
                        var xi = x1 + this.xg;
                        var yi = y1 + this.yg
                        ctx.moveTo(xi, yi);
                        ctx.bezierCurveTo(xi, yi + dy, xi + w, yi + dy, xi + w, yi);
                        ctx.lineTo(xi + w, yi + h);
                        ctx.bezierCurveTo(xi + w, yi + h + dy, xi, yi + h + dy, xi, yi + h);
                        ctx.closePath();
                        if (filled)
                            ctx.fill();
                        ctx.stroke();
                    }
                    Form.prototype.drawcylindertop = function (x1, y1, w, h, filled) {
                        ctx.beginPath();
                        var dx = w / 3;
                        var dy = w / 6;
                        var xi = x1 + this.xg;
                        var yi = y1 + this.yg
                        ctx.moveTo(xi, yi);
                        ctx.bezierCurveTo(xi, yi - dy, xi + w, yi - dy, xi + w, yi);
                        //ctx.lineTo(xi+w,yi+h);
                        ctx.bezierCurveTo(xi + w, yi + dy, xi, yi + dy, xi, yi);
                        ctx.closePath();
                        if (filled)
                            ctx.fill();
                        ctx.stroke();
                    }

                    Form.prototype.drawcylinderbottom = function (x1, y1, w, h, filled) {

                        ctx.beginPath();
                        var dx = w / 3;
                        var dy = w / 6;
                        var xi = x1 + this.xg;
                        var yi = y1 + this.yg
                        ctx.moveTo(xi + w, yi + h);
                        ctx.bezierCurveTo(xi + w, yi + h - dy, xi, yi + h - dy, xi, yi + h);
                        if (filled)
                            ctx.fill();
                        ctx.stroke();

                    }
                    /// no origin 
                    Form.prototype.drawtext = function (text, x, y, size, centerleft) {

                        drawtext(ctx, text, x + this.xg, y + this.yg, size, centerleft);
                    }
                    // no origin 

                    Form.prototype.drawpolygon = function (p, filled, closed, percent, st, len) {
                        var i;
                        var np = []
                        for (i = 0; i < p.length / 2; i++) {
                            np.push(p[2 * i] + this.xg);
                            np.push(p[2 * i + 1] + this.yg);
                        }
                        drawpolygon(ctx, np, filled, closed, percent, st, len)
                    }
                    Form.prototype.drawgraph = function (p, x0, y0, scx, scy) {
                        var i;
                        var x0 = x0 || 0;
                        var y0 = y0 || 0;
                        var scx = scx || 1;
                        var scy = scy || 1;
                        for (i = 0; i < p.length; i++) {
                            this.drawline(i * scx + x0, y0 - p[i] * scy + 2, i * scx + x0, y0 - p[i] * scy)
                        }

                    }
                    Form.prototype.drawcurve = function (x, y, filled, closed, percent) {
                        var i;
                        percent = percent || 1
                        ctx.beginPath();
                        for (i = 0; i < x.length * percent; i++) {
                            if (i === 0)
                                ctx.moveTo(x[i] + this.xg, y[i] + this.yg);
                            if (i > 0)
                                ctx.lineTo(x[i] + this.xg, y[i] + this.yg);
                        }
                        if (closed)
                            ctx.closePath();
                        if (filled > 0)
                            ctx.fill();
                        if (filled === 0 || filled === 2)
                            ctx.stroke();


                    }
                    // no origin //   because form can be moved so xg yg 

                    Form.prototype.dash = function (ar) {
                        this.ctx.setLineDash(ar);
                    }
                    Form.prototype.drawline = function (x1, y1, x2, y2, t) {
                        this.lastt = t || 1
                        ctx.beginPath();
                        var xa = x1 + this.xg;
                        var ya = this.yg + y1;
                        var xb = x2 + this.xg;
                        var yb = this.yg + y2;
                        ctx.moveTo(xa, ya);
                        this.lastx = xa + (xb - xa) * this.lastt;
                        this.lasty = ya + (yb - ya) * this.lastt;
                        ctx.lineTo(this.lastx, this.lasty);
                        ctx.stroke();

                    }
                    Form.prototype.drawlinecv = function (x1, y1, x2, y2, vel, t) {
                        var sol = Math.sqrt(x1 * x1 + y1 * y1);

                        if (sol < 0.01) {
                            t = 1;
                        } else
                            t = vel * t / sol;
                        if (t > 1)
                            t = 1;
                        this.drawline(x1, y1, x2, y2, t);

                    }
                    /// no origin 
                    Form.prototype.drawball = function (xo, yo, r, linestyle) {

                        var cx = xo + this.xg;
                        var cy = yo + this.yg;
                        var grd = ctx.createRadialGradient(cx, cy, r / 10, cx, cy, r * 1.5);
                        if (!linestyle)
                            grd.addColorStop(0, "white");
                        else
                            grd.addColorStop(0, linestyle);
                        grd.addColorStop(1, "black");

                        ctx.fillStyle = grd;

                        drawcirclefilled(ctx, cx, cy, r, 0, twopi, false);

                    }

                    /// draw arrow no origin 
                    Form.prototype.drawarrow = function (x, y, len, th, arh, d, filled) {
                        if (len < 0) {
                            len = abs(len);
                            th += Math.PI;
                        }
                        drawarrow(ctx, x + this.xg, y + this.yg, len, th, arh, d, filled)
                    }
                    Form.prototype.drawarrowc = function (x1, y1, x2, y2, arh, d, filled) {
                        drawarrow(ctx, x1 + this.xg, y1 + this.yg, Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)), Math.atan2((y2 - y1), x2 - x1), arh, d, filled)
                    }

                    // x,y center len half len
                    Form.prototype.drawdistance = function (x, y, len, th, arh, d, filled) {
                        drawdistance(ctx, x + this.xg, y + this.yg, len, th, arh, d, filled)
                    }

                    Form.prototype.pause = function (b) {
                        this.stopped = false;
                        if (b)
                            this.stopped = true;
                    };
                    //  Form.prototype.settime = function (atime) {
                    //      this.t = atime;
                    //  };
                    Form.prototype.setvalues = function (amin, amax, avalue) {
                        this.min = amin;
                        this.max = amax;
                        this.value = avalue;
                        this.setscrollpos(amin, amax, avalue);
                    };
                    Form.prototype.setscrollpos = function (amin, amax, avalue) {
                        this.min = amin;
                        this.max = amax;
                        this.value = avalue;
                        if (this.kind !== SCROLLBAR)
                            return;
                        var ishor = false;
                        var but = this.childs[1];
                        var dis = 100;
                        //this.y=(this.value-this.min)*dis/(this.max-this.min);
                        if (this.width > this.height)
                            ishor = true;
                        if (ishor) {
                            //alert (this.de)
                            but.y = this.height - this.de - this.de / 2;
                            dis = this.width - but.width;
                            but.x = (this.value - this.min) * dis / (this.max - this.min);
                            //but.width = (this.value - this.min) * dis / (this.max - this.min);
                            //but.x =0; 
                        } else {
                            but.x = this.width - this.de - this.de / 2;
                            dis = this.height - but.height;
                            but.y = (this.value - this.min) * dis / (this.max - this.min);
                            //but.height = (this.value - this.min) * dis / (this.max - this.min);
                            //but.y = 0; 
                        }
                    };
                    Form.prototype.fixscrollbar = function (sb) {
                        if (sb.kind !== SCROLLBAR)
                            return;
                        var ishor = false; //is vertical
                        var dis = 0;
                        var d1 = 0;
                        var d2 = 0;

                        if (sb.width > sb.height)
                            ishor = true;

                        if (ishor) {

                            dis = (sb.clickx - sb.de / 2) / (sb.width - sb.de);

                        } else {
                            dis = (sb.clicky - sb.de / 2) / (sb.height - sb.de);
                        }

                        if (dis < 0)
                            dis = 0;
                        if (dis > 1)
                            dis = 1;
                        sb.value = sb.min + dis * (sb.max - sb.min);
                        ///if (sb.astep===0) sb.value=toround(sb.value);
                        if (sb.astep)
                            sb.value = step(sb.value, sb.astep)
                        sb.setvalues(sb.min, sb.max, sb.value);
                        sb.onvaluechange();
                        sm.onvaluechange(sb);

                    };
                    Form.prototype.addsprite = function (id, title, x, y, w, h, imageres) {
                        var nw = new Sprite(id, title, x, y, w, h, imageres);



                        this.addchild(nw);
                        return nw;
                    };
                    Form.prototype.addapp = function (id, title) {
                        var sb = new App(id, title);
                        sb.kind = APP;
                        this.addchild(sb);
                        return sb;
                    };
                    Form.prototype.addclockwin = function (id, title, x, y) {
                        var sb = new Clockwin(0, "clockwin", x, y);
                        sb.kind = APP;
                        this.addchild(sb);
                        return sb;
                    };
                    Form.prototype.addform3d = function (id, title, x, y, w, h) {
                        var nf = new Form3d(id, title, x, y, w, h);
                        nf.kind = "3d";
                        this.addchild(nf);
                        return nf;
                    };
                    Form.prototype.addscrollbar = function (id, title, x, y, width, height, imageres) {
                        var sb = new Form(id, title, x, y, width, height, imageres);
                        sb.de = sb.height / 2; // new attr 
                        sb.rede = sb.height / 8;
                        sb.kind = SCROLLBAR;
                        sb.valuedraw = true;
                        sb.setvaluepos(12, -32);
                        sb.cursor = "pointer";
                        sb.drawbackground = false;
                        sb.drawoutline = false;
                        /// hor
                        var sbrect = sb.addform(0, "", sb.de / 2, (height - sb.rede) / 2, width - sb.de, sb.rede, imageres);
                        //var sbrect = sb.addform(0, "", 0, 0  , width, height  , imageres);
                        sbrect.pickable = false;
                        sbrect.drawoutline = true;
                        sbrect.backcolor = rgb(133, 133, 133);
                        this.addchild(sb);
                        /////add a test win
                        var ishor = false;
                        if (sb.width > sb.height)
                            ishor = true; ///
                        //var sbwi = sb.width/3;
                        // var sbhi = sb.width/3;
                        if (ishor) {
                            sb.de = sb.height / 2;
                            //   sbwi = sb.height/3;
                            //   sbhi = sb.height/3;// * 0.33;
                        }
                        if (!ishor) {
                            sb.de = sb.width / 2;
                            sb.rede = sb.width / 8;
                            sbrect.x = (width - sb.rede) / 2;
                            sbrect.y = sb.de / 2;
                            sbrect.width = sb.rede;
                            sbrect.height = height - sb.de;
                        }
                        var but = new Form(id, title, 0, 0, sb.de, sb.de, imageres);
                        sb.addchild(but);
                        but.corner = sb.de / 6;

                        but.pickable = false;
                        but.draggable = true;
                        but.backcolor = colorbutton; //rgb(128, 128, 178);
                        sb.backcolor = colorwin; //rgb(200, 200, 200);
                        sb.setscrollpos(sb.min, sb.max, sb.value);
                        but.drawoutline = true;
                        // but.drawbackground = false;
                        return sb;
                    };

                    Form.prototype.adddrag = function (id, title, x, y, width, height, imageres) {
                        var nw = new Drag(id, title, x, y, width, height, imageres);
                        this.addchild(nw);
                        return nw;
                    };
                    Form.prototype.addmultistate = function (id, title, x, y, width, height, imageres) {
                        var nw = new Multistate(id, title, x, y, width, height, imageres);
                        this.addchild(nw);
                        nw.backcolor = rgb(255, 255, 255);
                        nw.drawbackground = false;
                        nw.drawoutline = false;
                        nw.cursor = "pointer";
                        return nw;
                    };
                   
                   

                    Form.prototype.addlabel = function (id, title, x, y, width, height, imageres) {
                        var nw = new Form(id, title, x, y, width, height, imageres);
                        nw.kind = LABEL;
                        nw.pickable = false;
                        this.addchild(nw);
                        nw.backcolor = "white";////
                        return nw;
                    };
                    Form.prototype.getimageres = function (type) {
                        if (type === "about")
                            return iconabout;
                        if (type === "help")
                            return iconhelp;
                        if (type === "close")
                            return iconclose;
                        if (type === "clock1")
                            return clock1;
                        if (type === "clock2")
                            return clock2;
                        return undefined;
                    };
                    Form.prototype.addform = function (id, title, x, y, width, height, imageres) {
                        var nw = new Form(id, title, x, y, width, height, imageres);
                        this.addchild(nw);
                        nw.backcolor = colorwin;
                        return nw;
                    };
                    Form.prototype.addclosebutton = function (imageres) {
                        var nw = this.addbutton(0, "x", this.width - 32, 0, 32, 32, imageres);
                        var scope = this;
                        nw.onclick = function () {
                            scope.visible = false;
                        }
                        return nw;
                    };
                    Form.prototype.addbutton = function (id, title, x, y, width, height, imageres) {
                        var nw = new Form(id, title, x, y, width, height, imageres);
                        nw.kind = BUTTON;
                        nw.cursor = "pointer";
                        nw.backcolor = colorbutton; // rgb(155, 155, 155);
                        nw.drawbackground = true;
                        nw.drawoutline = true;
                        this.addchild(nw);
                        //this.textcentered=true;
                        return nw;
                    };
                    Form.prototype.addbuttoncommand = function (command, plist, id, title, x, y, width, height, imageres) {
                        var nw = this.addbutton(id, title, x, y, width, height, imageres);
                        nw.kind = BUTTON;
                        nw.backcolor = colorbutton; //rgb(155, 155, 155);
                        nw.drawbackground = false;
                        nw.command = command;
                        nw.commandlist = [];
                        for (var i = 0; i < plist.length; i++) {
                            nw.commandlist.push(plist[i]);
                        }
                        //this.addchild(nw);
                        return nw;
                    };
                    Form.prototype.addpushbutton = function (id, title, x, y, width, height, imageres) {

                        var nw = this.addbutton(id, title, x, y, width, height, imageres);
                        nw.kind = PUSHBUTTON;
                        //this.addchild(nw);
                        return nw;
                    };

                    function hidedown() {
                        var i;
                        ///alert (hidelist.length);
                        for (i = 0; i < hidelist.length; i++) {
                            var frm = hidelist[i];
                            var cnd = (!hidelist[i].contains(mousex, mousey));
                            //cnd=frm!==pressedobject;
                            if (cnd) {
                                hidelist[i].visible = false;

                            }

                        }
                        hidelist = [];
                    }
                    Form.prototype.has = function (ob) {
                        var i;
                        if (this === ob)
                            return true;
                        for (i = 0; i < this.childs.length; i++) {
                            return  has(childs[i]);
                        }
                        return false;
                    }
                    /// drop down
                    Form.prototype.adddropdown = function (id, title, x, y, width, height, imageres) {

                        var nw = new Dropdown(id, title, x, y, width, height);
                        this.addchild(nw);
                        nw.kind = 'dropdown';
                        return nw;


                    };
                    function Dropdown(id, title, x, y, width, height) {


                        Form.call(this, id, title, x, y, width, height);

                        this.butn = this.addbutton(id, title, 0, 0, width, height);
                        this.butn.textcentered = false;
                        var dd = this.butn.addlabel("ldd", "", this.butn.width - 48, 0, 48, 48, icondropdown);
                        dd.drawbackground = false;
                        this.list = this.addlist("lliisstt", "", 0, 0, width, 655.1);

                        this.list.visible = false;
                        var vlist = this.list;
                        vlist.drawbackground = true;
                        vlist.backcolor = "yellow";
                        vlist.drawoutline = true;
                        this.butn.onclick = function () {
                            vlist.visible = true;
                            hidelist.push(vlist);/// 

                        }





                    }

/// caution after constructor 
                    Dropdown.prototype = Object.create(Form.prototype);
                    Dropdown.prototype.constructor = Dropdown;

                    Dropdown.prototype.getselindex = function () {

                        return this.list.selindex;


                    }

                    Dropdown.prototype.setselindex = function (n) {

                        this.list.selectitem(n);
                        this.butn.title = this.list.childs[n].title;

                    }

                    Dropdown.prototype.additems = function (ar) {
                        var i;

                        for (i = 0; i < ar.length; i++) {
                            var li = this.list.addlistitem("li", ar[i], 0, i * this.height, this.width, this.height, undefined);
                            li.onclick = function () {
                                li.parent.visible = false;

                            }
                        }
                        this.list.height = ar.length * this.height;

                        this.list.selectitem(0);

                    }


                    ////////   addchild with proper image list mlist check combo
                    Form.prototype.addlist = function (id, title, x, y, width, height, imageres) {
                        var nw = new Form(id, title, x, y, width, height, imageres);
                        nw.kind = LIST;
                        nw.multiselect = false;
                        this.addchild(nw);
                        nw.backcolor = rgb(0, 250, 250);
                        return nw;
                    };
                    Form.prototype.addmlist = function (id, title, x, y, width, height, imageres) {
                        var nw = new Form(id, title, x, y, width, height, imageres);
                        nw.kind = LIST;
                        nw.multiselect = true;
                        this.addchild(nw);
                        nw.backcolor = rgb(0, 250, 250);
                        return nw;
                    };
                    Form.prototype.addcheck = function (id, title, x, y, width, height, imageres) {
                        var nw = new Form(id, title, x, y, width, height, imageres);
                        nw.kind = LIST;
                        nw.subkind = CHECK;
                        nw.multiselect = true;
                        this.addchild(nw);
                        nw.backcolor = colorcheck;
                        nw.drawoutline = true;
                        return nw;
                    };
                    Form.prototype.addradio = function (id, title, x, y, width, height, imageres) {
                        var nw = new Form(id, title, x, y, width, height, imageres);
                        nw.kind = LIST;
                        nw.subkind = RADIO;
                        nw.multiselect = false;
                        this.addchild(nw);
                        nw.backcolor = colorcheck;
                        nw.drawoutline = true;
                        return nw;
                    };
                    Form.prototype.addlistitem = function (id, title, x, y, width, height, imageres) {
                        var nw = new Form(id, title, x, y, width, height, imageres);
                        nw.kind = LISTITEM;
                        this.addchild(nw);
                        nw.cursor = "pointer";

                        //
                        return nw;
                    };

                    /// sets selindex if list ob is selecteditem
                    Form.prototype.setselindex = function (ob) {
                        this.selindex = -1;
                        if (this.kind !== LIST)
                            return;


                        for (var i = 0; i < this.childs.length; i++) {
                            if (ob === this.childs[i]) {
                                this.selindex = i;
                            }
                        }

                    };
                    Form.prototype.getselindex = function () {
                        return this.selindex;

                    };
                    ///// pressed list item object so only this check on list 
                    Form.prototype.listpressed = function (ob) {
                        if (!this.multiselect) {
                            for (var i = 0; i < this.childs.length; i++) {
                                this.childs[i].checked = (ob === this.childs[i]);
                            }
                        }
                    };
                    /// recalc position 
                    Form.prototype.setchilds = function (ax, ay, dx, dy, nw, nh) {
                        var si;
                        for (si = 0; si < this.childs.length; si++) {
                            this.childs[si].x = ax + si * dx;
                            this.childs[si].y = ay + si * dy;
                            if (nw)
                                this.childs[si].width = nw;
                            if (nh)
                                this.childs[si].height = nh;

                        }
                    };
                    Form.prototype.setchildsarray = function (rows, cols, dx, dy) {
                        var c, r;
                        var i;
                        for (r = 0; r < rows; r++) {

                            for (c = 0; c < cols; c++) {
                                i = cols * r + c;
                                if (i < this.childs.length) {
                                    this.childs[i].x = c * dx;
                                    this.childs[i].y = r * dy;
                                }

                            }

                        }
                    };

                    Form.prototype.selectitem = function (n) {
                        this.selecteditem = undefined;
                        if (n < 0 || n >= this.childs.length) {


                            return;
                        }
                        this.selecteditem = this.childs[n];
                        this.childs[n].checked = true;
                        this.setselindex(this.selecteditem);
                        if (this.multiselect)
                            return;/// 
                        var i;
                        for (i = 0; i < this.childs.length; i++) {
                            this.childs[i].checked = (n === i);

                        }

                    };
                    Form.prototype.unselectitem = function (n) {
                        this.selecteditem = undefined;

                        if (n < 0 || n > this.childs.length)
                            return;
                        this.childs[n].checked = false;
                    };
                    Form.prototype.checklist = function (n) {
                        if (n < 0 || n > this.childs.length)
                            return false;
                        if (this.kind !== LIST)
                            return false;
                        if (!this.multiselect)
                            return this.selecteditem === this.childs[n];
                        return this.childs[n].checked;
                    };
                    Form.prototype.checkeditem = function (n) {
                        if (n < 0 || n > this.childs.length)
                            return false;
                        if (this.kind !== LIST)
                            return false;
                        return this.childs[n].checked;
                    };
                    Form.prototype.setkind = function (kind) {
                        this.kind = kind;
                    };
                    Form.prototype.setsubkind = function (akind) {
                        this.subkind = akind;
                    };

                    Form.prototype.inside = function (x, y) {
                        var v = this.getparentpos();

                        if (x < v.x)
                            return false;
                        if (y < v.y)
                            return false;
                        if (x > v.x + this.width)
                            return false;
                        if (y > v.y + this.height)
                            return false;
                        return true;

                    }

                    Form.prototype.mouseoverforms = function (alist) {
                        var v = this.getmouseposglobal();
                        var i;
                        for (i = 0; i < alist.length; i++) {
                            if (alist[i].inside(v.x, v.y))
                                return alist[i];
                        }

                        return undefined;
                    }

                    Form.prototype.contains = function (ax, ay) {


                        /// hit areas;
                        if (!this.pickable)
                            return false;


                        var v = this.getparentpos();
                        if (ax < v.x + this.hitdx)
                            return false;
                        if (ay < v.y + this.hitdy)
                            return false;
                        if (ax > this.width + this.hitdw + v.x + this.hitdx)
                            return false;
                        if (ay > this.height + this.hitdh + v.y + this.hitdy)
                            return false;


                        /////
                        //// ok now we have hit win 
                        // 
                        this.clickx = ax - (v.x + this.hitdx);
                        this.clicky = ay - (v.y + this.hitdy);
                        ///********
                        if (this.picktype === 1)
                            return true;
                        if (this.picktype === 2) {
                            var cx = v.x + this.hitdx + (this.hitdw + this.width) / 2;
                            var cy = v.y + this.hitdy + (this.hitdh + this.height) / 2;
                            var rx = (this.hitdw + this.width) / 2;
                            var ry = (this.hitdh + this.height) / 2;

                             //return ((cx-ax)*(cx-ax)+(cy-ay)*(cy-ay)<this.width/2*this.width/2);
                           return Math.pow((cx - ax) / rx, 2) + Math.pow((cy - ay) / ry, 2) <= 1;
                        }




                        return false;
                    };
                    Form.prototype.addtext = function () {
                        var st = "";
                        for (var i = 0; i < arguments.length; i++) {
                            st += arguments[i] + " ";
                            //this.texts.push(arguments[i]);
                            ///// this.msg("hello from log"); works !!!!!!!!
                        }
                        this.texts.push(st);
                    };
                    Form.prototype.addchild = function () {
                        for (var i = 0; i < arguments.length; i++) {
                            this.childs.push(arguments[i]);
                            arguments[i].parent = this;
                        }
                    };
                    Form.prototype.getparentpos = function () {
                        var parx = this.x;
                        var pary = this.y;
                        var v = this.parent;
                        while (v) {
                            parx += v.x;
                            pary += v.y;
                            v = v.parent;
                        }
                        /// ok update 
                        this.xg = parx;
                        this.yg = pary;
                        return {
                            x: parx,
                            y: pary
                        };
                    };
                    Form.prototype.devtolog = function (ax, ay) {
                        //  -this.xorig+mousex,this.yorig-mousey	
                        return {
                            x: ax - this.xorig,
                            y: -ay + this.yorig
                        };
                    };
                    Form.prototype.logtodev = function (ax, ay) {
                        return {
                            x: ax + this.xorig,
                            y: -ay + this.yorig
                        };
                    };
                    Form.prototype.checkmouse = function (x, y) {
                        ////// fills clicks[] for win
                        // maybe for all forms not to overlap
                        if (!this.visible)
                            return;

                        if (this.contains(x, y)) {
                            clicks.push(this);

                        }
                        for (var i = 0; i < this.childs.length; i++) {
                            this.childs[i].checkmouse(x, y);
                        }
                    };
                    Form.prototype.home = function () {
                        this.x = this.x0;
                        this.y = this.y0;
                    };
                    Form.prototype.onvaluechange = function (ob) {
                        return (ob !== undefined);
                        /// do whatever on scroll bars
                    };
                    Form.prototype.onwheel = function (e) {
                        /// do whatever 
                    }; //// end onmdt
                    Form.prototype.onmousedown = function () {
                        /// do whatever 
                    }; //// end onmdt
                    Form.prototype.onmousemove = function () {
                        /// do whatever 
                    }; //// end onm mv
                    Form.prototype.onmouseup = function () {};
                    Form.prototype.onclick = function () {
                        /// do whatever 
                    };

                    Form.prototype.onchildclicked = function (ch) {
                        /// do whatever child ch clicked
                    };
                    Form.prototype.onenter = function () {

                    }; //// end onmdt
                    Form.prototype.onleave = function () {

                    }; //// end onmdt
                    Form.prototype.ondrop = function (dro, ovo) {
                        /// do whatever  droppedobject dropped over  oveobject2
                    };
                    Form.prototype.ondragstart = function (dro) {
                        /// do whatever  droppedobject dropped over  oveobject2
                    };
                    Form.prototype.onmessage = function (msg) {
                        // override this and read msg
                        /// do whatever  droppedobject dropped over  oveobject2
                    };
                    Form.prototype.onevent = function (e, type) {
                        /////  handle childs event first 
                        ///// useless until now 
                        if (type === MOUSEDOWN) {
                        }
                        var i = 0;
                        // for (i=this.childs.length-1;i>-1;i--){
                        //    this.childs[i].onevent(e,type);
                        //}   
                        for (i = 0; i < this.childs.length; i++) {
                            this.childs[i].onevent(e, type);
                        }
                        ///// now its time to handle which mousedown
                    }; //// end windo onevent
                    ////
                    Form.prototype.setpos = function () {

                        var v = this.getparentpos();
                        this.xg = v.x + this.pressed;
                        this.yg = v.y + this.pressed;

                    };
                    Form.prototype.setanimtime = function (t) {

                        var i;

                        for (i = 0; i < this.anims.length; i++) {

                            this.anims[i].t = t;
                            //this.anims[i].update(0);

                        }

                    };

                    Form.prototype.settime = function () {
                        this.dt = timedelta * this.timescale * (!this.stopped);
                        this.t += this.dt;
                        if (this.t < 0)
                            this.t = 0;

                    }


                    Form.prototype.setpost = function () {
                        this.setpos();
                        this.settime();
                        this.update();
                        var i;

                        for (i = 0; i < this.animators.length; i++) {

                            this.animators[i].update(this.dt);

                        }
                        for (i = 0; i < this.tasks.length; i++) {
                            this.tasks[i].update();
                        }
                    };
                    Form.prototype.setpicktype = function (apt) {
                        // 1 rect  2// ellipse   3 polygon 
                        this.picktype = apt;


                    }
                    Form.prototype.below = function (aform, d) {
                        aform.setpos();
                        this.x = aform.xg;
                        this.y = aform.yg + d + aform.height;

                    }
/////////////------------------------------------------------------------------------////////////////////////////////////////////////////////
                    Form.prototype.draw = function (ctx) {

                        if (this.transformable) {
                            ctx.save();
                            this.transform();
                        }

                       this.setpost(); /// position x y and time
                        if (!this.visible)
                            return;
                        
                        //
                        //
                        /// with drawchilds(ctx) no need all stuff 
                        ctx.globalCompositeOperation = this.composition;
                        if (this.cliptype > 0)
                            this.clip();
                        var selcolorink = this.textcolor;
                        ctx.lineWidth = this.lw;
                        ctx.linestyle = "black"
                        ctx.strokeStyle = "white";
                        if (this.kind === LABEL) {

                        }
                        ctx.fillStyle = this.backcolor;
                        ///var drawbackground = true;
                        /// if list dont draw background
                        if (this.kind === LISTITEM) {
                            this.drawbackground = false;
                            if (this.parent.subkind === CHECK) {
                                this.imageres = check1;
                            }
                            if (this.parent.subkind === RADIO) {
                                this.imageres = radio1;
                            }
                            ///// if non multistate 
                            if (this.parent.multiselect && this.checked) {
                                this.drawbackground = true;
                                selcolorink = "white";
                                ctx.fillStyle = "blue"; ///rgb(123,123,123);
                                if (this.parent.subkind === CHECK) {
                                    this.imageres = check2;
                                }
                                if (this.parent.subkind === RADIO) {
                                    this.imageres = radio2;
                                }
                            }
                            if (!this.parent.multiselect && this === this.parent.selecteditem) {
                                this.drawbackground = true;
                                selcolorink = "white";
                                ctx.fillStyle = "blue"; ///rgb(123,123,123);
                                if (this.parent.subkind === CHECK) {
                                    this.imageres = check2;
                                }
                                if (this.parent.subkind === RADIO) {
                                    this.imageres = radio2;
                                }
                            }
                            if (this.parent.subkind === CHECK || this.parent.subkind === RADIO) {
                                this.drawbackground = false;
                                selcolorink = this.textcolor;
                            }
                        } /// end is listitem 

                        if (this.shadow) {
                            ctx.fillStyle = this.shadowcolor;
                            ctx.fillRect(this.xg + this.shadowdx, this.yg + this.shadowdy, this.width, this.height);
                            ctx.fillStyle = this.backcolor;
                        }
                        if (this.drawbackground) {
                            if (this.corner <= 0) {
                                ctx.fillRect(this.xg, this.yg, this.width, this.height);
                            } else {
                                drawroundrect(ctx, this.xg, this.yg, this.width, this.height, this.corner, 1);
                            }


                        }
                        

                        ctx.fillStyle = selcolorink;

                        ctx.font = this.texth + "px Helvetica";
                        ctx.textAlign = "left";
                        if (this.textcentered && !this.wrap)
                            ctx.textAlign = "center";
                        ctx.textBaseline = "middle";
                        var ofsx = 10 * (!this.textcentered) + this.xg + this.width / 2 * this.textcentered;
                        var ofsy = this.yg + this.height / 2;
                        /// to scale image
                        var imx, imy;

                        if (this.kind === LISTITEM) {
                            //imx = this.xg + (this.width - this.imageres.imw) / 2;
                            //imy = this.yg + (this.height - this.imageres.imh) / 2;
                            ctx.textBaseline = "middle";
                            ofsx = 32 + this.xg;// + this.height;    ###
                            var ofsy = this.yg + this.height / 2;
                            ctx.textAlign = "start";

                        }
                        if (this.wrap) {
                            ctx.textBaseline = "top";
                            wraptext(ctx, this.title, this.xg + this.texth / 5, this.yg + this.texth * 0.5, this.width, this.texth + this.texth / 5)
                        } else
                            ctx.fillText(this.title, ofsx, ofsy);
                        ctx.textAlign = "start";
                        //ctx.textBaseline = "top";
                        //if (this.valuedraw) ctx.fillText(this.valuename + "=" + todecimal(this.value, this.valuedigits) + " " + this.valueunit, this.xg + this.valuex, this.height / 2 + this.yg + this.valuey)
                        this.drawtexts(ctx);
                        /// draw image
                        if (this.imageres) {
                            imx = this.xg + (this.width - this.imageres.imw) / 2;
                            imy = this.yg + (this.height - this.imageres.imh) / 2;
                            if (this.kind === LISTITEM) {
                                imx = this.xg + (this.height - this.imageres.imw) / 2;
                                imy = this.yg + (this.height - this.imageres.imh) / 2;
                                ctx.drawImage(this.imageres.image, imx, imy);
                            } else {
                                if (!this.stretch)
                                    this.drawimage(this.imageres, this.width, this.height, true)
                                else
                                    this.fillimage( );
                            }
                            ;
                            //his.drawimage()
                        }
                        
                        if (this.drawoutline) {
                            ctx.strokeStyle = this.linecolor;
                            //ctx.lineWidth = 0;
                            if (this.corner <= 0) {
                                ctx.beginPath();
                                ctx.rect(this.xg, this.yg, this.width, this.height);
                                ctx.stroke();
                            } else {
                                drawroundrect(ctx, this.xg, this.yg, this.width, this.height, this.corner, 0);
                            }
                        }
                        //////   after draw  user
                        // this.drawhitareas(ctx);
                        this.userdraw(ctx);
                        ///// draw childs
                        this.drawchilds(ctx);
                        if (this.tooltip) {
                            this.tooltip.visible = (this === overobject);
                        }
                        if (this.tooltip && this.tooltip.visible) {
                            this.drawrect(-1, -1, this.width + 2, this.height + 2, 0);
                        }
                        ctx.font = this.texth + "px Helvetica";
                        if (this.valuedraw) {
                            ctx.font = this.texth + "px Helvetica";
                            ctx.fillText(this.valuename + "=" + todecimal(this.value, this.valuedigits) + " " + this.valueunit, this.xg + this.valuex, this.height / 2 + this.yg + this.valuey)
                        }
                        ctx.globalCompositeOperation = "source-over";

                        if (this.cliptype > 1)
                            ctx.restore();


                        if (this.transformable) {
                            ctx.restore();
                        }


                    }; /// end draw definition
                    // 
                    // 
                    Form.prototype.userdraw = function (ctx) {
                        //override this to draw after form 
                    }



                    Form.prototype.drawchilds = function (ctx) {
                        for (var i = 0; i < this.childs.length; i++) {
                            this.childs[i].draw(ctx);
                        }
                    }
                    Form.prototype.drawtexts = function (ctx) {
                        var i = 0;
                        // draw texts
                        for (i = 0; i < this.texts.length; i++) {
                            ctx.fillText(this.texts[i], 8 + this.xg, (i + 1) * this.texth + this.yg);
                        }
                    }

                    Form.prototype.addparticleform = function (x, y, w, h) {
                        var nf = new ParticleForm(0, "", x, y, w, h);
                        this.addchild(nf);
                        return nf;
                    }

///// end form definition;//
//
//
//
//
//
////// drag value
                    function Drag(id, title, x, y, width, height, imageres) {


                        Form.call(this, id, title, x, y, width, height, imageres);
                        this.frm = this.addform(0, "", 0, 0, width, height);
                        this.frm.draggable = true;
                        this.frm.backout(false);
                        var frm = this.frm;
                        this.scope = this;
                        this.value0 = this.value;


                        frm.onmouseup = function () {
                            // frm.value=length(0,frm.x,0,frm.y);

                            frm.x = 0;
                            frm.y = 0;
                            this.parent.value0 = this.parent.value;
                        }

                    }



                    Drag.prototype = Object.create(Form.prototype);
                    Drag.prototype.constructor = Drag;

                    Drag.prototype.draw = function (ctx) {
                        Form.prototype.draw.call(this, ctx);  /// any way if must draw childs etc
                        var si = 1;
                        if (this.frm.x < 0 || this.frm.y > 0)
                            si = -1
                        this.value = this.value0 + si * step(length(0, this.frm.x, 0, this.frm.y) / 10, this.astep);

                        this.drawtext(todecimal(this.value, this.valuedigits), 0, 12, 10, true);

                    };

//// particle form

                    function ParticleForm(id, title, x, y, w, h) {


                        Form.call(this, id, title, x, y, w, h);

                        this.ps = jsoncopy(ParticleSystem);

                        //psInit(this.ps);
                        this.ps.x1 = 0;
                        this.ps.y1 = 0;
                        this.ps.x2 = w;
                        this.ps.y2 = h;


                        this.stopped = false;
                    }

/// caution after constructor 
                    ParticleForm.prototype = Object.create(Form.prototype);
                    ParticleForm.prototype.constructor = ParticleForm;

                    ParticleForm.prototype.step = function () {
                        /// override eg Step(ps,dt)
                    }

                    ParticleForm.prototype.draw = function (ctx) {
                        Form.prototype.draw.call(this, ctx);  /// any way if must draw childs etc
                        if (!this.visible)
                            return;
                        this.step();

                        psDraw(this.ps, this);



                    };

/// end part form


                   

                    function Sprite(id, title, x, y, w, h, imageres) {


                        Form.call(this, id, title, x, y, w, h, imageres);
                        this.kind = "sprite";
                        this.spriteres = imageres;
                        this.imageres = 0;
                        this.pickable = true;
                        /*
                         this.tx = x;
                         this.ty = y;
                         this.scx = 1;
                         this.scy = 1;
                         this.rot = 0;
                         this.pivx = 0;
                         this.pivy = 0;
                         
                         */
                        this.backout(false, false)
                    }

/// caution after constructor 
                    Sprite.prototype = Object.create(Form.prototype);
                    Sprite.prototype.constructor = Sprite;



                    Sprite.prototype.draw = function (ctx) {

                        Form.prototype.draw.call(this, ctx);
                        this.parent.drawimagetr(this.spriteres, this.tx, this.ty, this.rot, this.scx, this.scy, this.pivx, this.pivy);
                    };
                    Sprite.prototype.pivot = function (x, y) {

                        this.pivx = x;
                        this.pivy = y;
                    };


                    function Form3d(id, title, x, y, width, height) {
                        Form.call(this, id, title, x, y, width, height);
                        this.hitlist = [];
                        this.mixers = [];
                        this.kind = "3d";
                        this.rho = 10;
                        this.theta = 0;//3*Math.PI/2;
                        this.phi = 0;//torad(60);

                        //this.renderer=renderer;
                        this.scene;
                        this.camera;
                        this.light;
                        this.mouse3d = {
                            x: -1,
                            y: -1
                        };
                        // start 3d def
                        this.camera = new THREE.PerspectiveCamera(33, window.innerWidth / window.innerHeight, 0.01, 40);
                        this.camera.position.set(0, 7, 7);
                        this.camera.lookAt(0, 0, 0);
                        this.scene = new THREE.Scene();
                        this.mixer = undefined; // new THREE.AnimationMixer( this.scene );
                        this.scene.background = new THREE.Color(0x000000);
                        /////scene.fog = new THREE.Fog( 0xa0a0a0, 200, 10000 );
                        this.grid = new THREE.GridHelper(10, 10, 0xff00ff, 0xff0000);
                        this.scene.add(this.grid);
                        raycaster = new THREE.Raycaster();
                        var mat = new THREE.MeshLambertMaterial({
                            color: 0xffff00
                        });
                        //var box3 = box(1,1,1,mat);
                        //this.scene.add(box3);
                        //this.hitlist.push(box3);
                        //var light = new THREE.PointLight( 0xff0000, 1, 100 );
                        //light.position.set( 2, 3, 5  );
                        //this.scene.add( light );
                        this.p0 = this.scene.position.clone(); //this.scene.position.clone();
                        this.r0 = this.scene.rotation.clone();
                        this.sc0 = this.scene.scale.clone();
                        // end 3d def
                        this.controls = new THREE.OrbitControls(this.camera);
                        var controls = this.controls;
                        //controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop)
                        controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
                        controls.dampingFactor = 0.25;
                        controls.screenSpacePanning = false;
                        controls.minDistance = 0.1;
                        controls.maxDistance = 50;
                        //controls.maxPolarAngle =  Math.PI  ;


                        controls.enablePan = false;
                        controls.enabled = false;
                    }
                    Form3d.prototype = Object.create(Form.prototype);
                    Form3d.prototype.constructor = Form3d;
                    Form3d.prototype.onwheel = function (e) {
                        this.wheeldelta = -0.1 * sign(e.deltaY);
                        edeltay = e.deltaY;
                        //var nsc=this.sc0.x+((mousey-mousey0)/1280*wheel/100);
                        //var nsc=this.sc0.x+e.deltaY/1000;
                        //var nsc=this.sc0.x+this.wheeldelta ;
                        var nsc = this.scene.scale.x + this.wheeldelta;
                        if (nsc < 0.1) {
                            nsc = 0.1;
                            this.wheeldelta = -this.sc0.x + 0.1;
                        }
                        //  this.scene.scale.x = nsc;
                        //  this.scene.scale.y = nsc;
                        //   this.scene.scale.z = nsc;

                        this.rho -= this.wheeldelta * 2;
                        if (this.rho < 1)
                            this.rho = 1;
                    }; //

                    Form3d.prototype.setscale = function (nsc) {

                        this.scene.scale.x = nsc;
                        this.scene.scale.y = nsc;
                        this.scene.scale.z = nsc;
                        this.sc0.copy(this.scene.scale);
                    }; //

                    Form3d.prototype.draw = function (ctx) {
                        //Form.prototype.draw.call(this, ctx);  /// any way if must draw childs etc
                        //or 
                        if (!this.visible) {
                            return;
                        }
                        this.texts = [];

                        this.setpost();
                        if (control3d && mousemove && pressedobject === this) {
                            // drag view 

                            // this.scene.rotation.y = this.r0.y + ( (mousex - mousex0) / 314);
                            //  this.scene.rotation.x = this.r0.x + ((mousey - mousey0) / 314);
                            //this.scene.position.x = this.p0.x + ((mousex - mousex0) / 150);
                            //this.scene.position.y = this.p0.y - ((mousey - mousey0) / 150);
                            this.scene.rotation.z += mousedx / 340
                            //this.theta-=mousedx/340;//(mousex - mousex0) / 314
                            this.phi += mousedy / 160;//(mousex - mousex0) / 314
                            if (this.phi > Math.PI / 2)
                                this.phi = Math.PI / 2 - 0.0001;
                            if (this.phi < -Math.PI / 2)
                                this.phi = -Math.PI / 2 + 0.0001;
                        }


                        /// set camera pos ;
                        //
                        //
                        // var x=this.rho*cos(this.phi)*cos(this.theta);
                        // var y=this.rho*cos(this.phi)*sin(this.theta);
                        //var z=this.rho*sin(this.phi);
                        var z = this.rho * cos(this.phi) * cos(this.theta);
                        var x = this.rho * cos(this.phi) * sin(this.theta);
                        var y = this.rho * sin(this.phi);




                        this.camera.position.set(x, y, z);
                        this.camera.lookAt(0, 0, 0);
                        // *** not set mobile resize failure //renderer.setPixelRatio(window.devicePixelRatio);
                        this.camera.aspect = this.width / this.height;
                        this.camera.updateProjectionMatrix();
                        //renderw=this.width;
                        //renderh=this.height;
                        this.mouse3d.x = ((mousex - this.xg) / this.width) * 2 - 1;
                        this.mouse3d.y = -((mousey - this.yg) / this.height) * 2 + 1;
                        renderer.setViewport(0, 0, this.width, this.height);
                        renderer.setSize(logw, logh);
                        renderer.setPixelRatio(window.devicePixelRatio);
                        //renderer.setSize(this.width, this.height);//
                        //animate3d(this.dt, this.scene, this.camera, this.mouse3d, this.hitlist, this.mixer, this.mixers);
                        animate3d(this);
                        ctx.drawImage(canvas3d, this.xg, this.yg, this.width, this.height);
                        ///old was ..,xg ,yg ,width ,height
                        this.drawchilds(ctx);
                        this.drawtexts(ctx);
                        this.userdraw(ctx);
                    };

                    function App(id, title) {
                        Form.call(this, id, title, 0, 0, 1024, 768);
                    }
                    App.prototype = Object.create(Form.prototype);
                    App.prototype.constructor = App;
                    App.prototype.create = function () {}
                    App.prototype.init = function () {}
                    App.prototype.update = function () {}
                    App.prototype.render = function () {}

                    function Multistate(id, title, x, y, width, height, imageres) {
                        Form.call(this, id, title, x, y, width, height, imageres);
                        this.kind = MULTISTATE;
                    }
                    Multistate.prototype = Object.create(Form.prototype);
                    Multistate.prototype.constructor = Multistate;
                    Multistate.prototype.onclick = function () {
                        // if (overobject!==this) return;
                        this.state += 1;

                        if (this.state > this.childs.length - 1)
                            this.state = 0;
                    };
                    Multistate.prototype.draw = function (ctx) {
                        var v = this.getparentpos();
                        this.xg = v.x + 1 * (this === pressedobject);
                        this.yg = v.y + 1 * (this === pressedobject);
                        //ctx.fillStyle = this.backcolor;
                        //ctx.fillRect(this.xg, this.yg, this.width, this.height);
                        ctx.fillStyle = this.textcolor;
                        ctx.fillStyle = rgb(0, 0, 0);
                        ctx.font = this.texth + "px Helvetica";
                        //ctx.textAlign = "center";
                        //ctx.textBaseline = "top";
                        var str = this.title;
                        var imres;
                        var img;
                        var wi0 = 0;
                        var ch = this.childs;
                        if (ch) {
                            str = ch[this.state].title;
                            imres = ch[this.state].imageres;
                            if (imres)
                                img = imres.image;
                            if (img)
                                wi0 = img.width;
                        }
                        var ofsx = this.xg + wi0; // + ch[this.state].width / 2 + 40 * (imres);
                        var ofsy = this.yg;
                        ctx.fillText(str, ofsx, ofsy);
                        //ctx.textAlign = "start";
                        if (imres) {
                            ctx.drawImage(imres.image, this.xg, this.yg);
                        }
                    };
                    Multistate.prototype.addstate = function (id, title, imageres) {
                        var nw = new Form(id, title, 1, 1, 32, 32, imageres);
                        nw.kind = BUTTON;
                        nw.drawbackground = false;
                        nw.drawoutline = false;
                        nw.pickable = false;
                        this.childs.push(nw);
                        return nw;
                    };


                    //------------------------------------------------------------------
                    function Clockwin(id, title, x, y, width, height, imageres) {
                        Form.call(this, id, "", x, y, 48 * 6, 48, imageres);

                        this.stept = 0.1;
                        this.backcolor = rgb(243, 223, 223);
                        this.drawbackground = false;
                        this.drawoutline = false;
                        //this.draggable=true;
                        var d0 = 0;
                        this.ms = this.addmultistate(0, "", 0, d0, 48, 48);
                        this.ms.addstate(1, "", clock1);
                        this.ms.addstate(2, "", clock2);
                        this.ms.onclick = function () {

                            var par = this.parent;


                            Multistate.prototype.onclick.call(this);
                            if (this.state === 0)
                                par.stopped = true;
                            if (this.state === 1)
                                par.stopped = false;

                            this.parent.onmessage("clock");
                        };
                        var msl = this;
                        this.rst = this.addbutton(0, "", 48, d0, 48, 48, clock3);
                        this.rst.drawbackground = false;
                        this.rst.drawoutline = false;
                        this.rst.onclick = function () {
                            this.parent.t = 0;

                            this.parent.onmessage("clockreset");
                        };
                        this.ff1 = this.addbutton(0, "", 2 * 48, d0, 48, 48, clock4);
                        this.ff1.drawbackground = false;
                        this.ff1.drawoutline = false;
                        this.ff1.onmouseup = function () {
                            msl.clockstop();
                        };
                        this.ff1.onmousedown = function () {
                            msl.clockstart();
                            this.parent.onmessage("clock");
                        };
                        this.ff2 = this.addbutton(0, "", 3 * 48, d0, 48, 48, clock5);
                        this.ff2.drawbackground = false;
                        this.ff2.drawoutline = false;
                        this.ff2.onmouseup = function () {
                            msl.clockstop(this);
                            this.parent.timescale = Math.abs(this.parent.timescale);
                        };
                        this.ff2.onmousedown = function () {
                            this.parent.timescale = -Math.abs(this.parent.timescale);
                            msl.clockstart(this);

                        };
                        this.ff3 = this.addbutton(0, "", 4 * 48, d0, 48, 48, clock6);
                        this.ff3.drawbackground = false;
                        this.ff3.drawoutline = false;
                        this.ff3.onmouseup = function () {
                            this.parent.t += this.parent.stept * this.parent.timescale;
                        };
                        this.ff3.onmousedown = function () {
                            msl.clockstop(this);
                            this.parent.onmessage("clock");
                        };
                        this.ff4 = this.addbutton(0, "", 5 * 48, d0, 48, 48, clock7);
                        this.ff4.drawbackground = false;
                        this.ff4.drawoutline = false;
                        this.ff4.onmouseup = function () {
                            this.parent.t -= this.parent.stept * this.parent.timescale;
                            if (this.parent.t < 0)
                                this.parent.t = 0.0;
                        };
                        this.ff4.onmousedown = function () {
                            msl.clockstop(this);
                        };
                    }
                    Clockwin.prototype = Object.create(Form.prototype);
                    Clockwin.prototype.constructor = Clockwin;
                    Clockwin.prototype.draw = function (ctx) {
                        // this.drawbackground = true;
                        ctx.lineWidth = this.lw;
                        //ctx.lineStyle=rgb(0,0,0);
                        var v = this.getparentpos();
                        //drawroundrect(ctx, v.x, v.y, this.width, this.height, 4, 0, "black", this.backcolor);
                        Form.prototype.draw.call(this, ctx);
                        this.value = this.t;
                    };
                    Clockwin.prototype.reset = function () {
                        this.stopped = true;
                        this.ms.state = 0;
                        this.t = 0;
                    }
                    Clockwin.prototype.clockstop = function () {
                        this.stopped = true;
                        this.ms.state = 0;
                    }

                    Clockwin.prototype.clockstart = function () {
                        this.stopped = false;
                        this.ms.state = 1;
                    }
                    
                    /// class         ---------------------------- S c e n e     -----------------------------
                    function Scene() {
                        Form.call(this, "idscene", "title", 0, 0, 1024, 768);
                        ////  collection of stuff only with parent===0;
                    } // end scene def
                    Scene.prototype = Object.create(Form.prototype);
                    Scene.prototype.constructor = Scene;
                    Scene.prototype.draw = function (ctx) {
                        var i = 0;
                        for (i = 0; i < this.childs.length; i++) {
                            this.childs[i].draw(ctx);
                        }
                        if (draggedobject) {
                            /// todo stop timer             
                            if (draggedobject.dropable)
                                draggedobject.draw(ctx);
                        }
                    };
                    Scene.prototype.getclicks = function () {
                        var i = 0;
                        for (i = 0; i < this.childs.length; i++) {
                            this.childs[i].checkmouse(mousex, mousey);
                        }
                        for (i = 0; i < sm.childs.length; i++) {
                            sm.childs[i].checkmouse(mousex, mousey);
                        }
                    };
                    Scene.prototype.onevent = function (e, type) {
                        var i = 0;
                        var ob = undefined;
                        overobject = undefined;
                        var v = undefined;
                        var oldoverobject = undefined;
                        //draggedobject=undefined;
                        clickedobject = undefined;
                        clicks = [];
                        this.getclicks();
                        ob = getlastchild();
                        overover = ob;
                        overobject2 = getpreviouschild();
                        if (type === MOUSEWHEEL && overover) {
                            overover.onwheel(e);
                        }
                        if (type === MOUSEDOWN) {

                            pressedobject = undefined;
                            if (ob !== undefined) {

                                control3d = false;
                                if (ob.kind === "3d") {
                                    ob.p0.copy(ob.scene.position);
                                    ob.r0.copy(ob.scene.rotation);
                                    ob.sc0.copy(ob.scene.scale);
                                    control3d = true;
                                }
                                if (ob.kind === LISTITEM) {

                                    ob.pressed = 1;
                                }
                                ob.onmousedown();
                                if (ob.kind === BUTTON || ob.kind === PUSHBUTTON)
                                    ob.pressed = 1; //modify dx for buttons
                                if (ob.kind === SCROLLBAR) {

                                    ob.fixscrollbar(ob);
                                }
                                pressedobject = ob; //// ok 
                                overobject = ob;
                                if (ob.draggable)
                                    draggedobject = ob;
                                dragx = ob.x;
                                dragy = ob.y;
                                sm.ondragstart(ob);
                                ob.ondragstart(ob);
                                if (ob.parent)
                                    ob.parent.ondragstart(ob);

                                ////////  if is list toggle  
                            } ///// having clicked
                            //---

                            hidedown(); /// *** 

                        } //////// end mouse down
                        if (type === MOUSEMOVE) {
                            oldoverobject = overobject;
                            overobject = ob;
                            if (ob) {
                                if (oldoverobject !== overobject) {
                                    ob.onenter();
                                    if (oldoverobject)
                                        oldoverobject.onleave();
                                }


                                changecursor(ob.cursor);
                            } else
                                changecursor("default");
                            if (pressedobject) {
                                pressedobject.onmousemove();
                                // not only sb 
                                //    if (pressedobject.kind === SCROLLBAR) {
                                v = pressedobject.getparentpos();
                                pressedobject.clickx = mousex - v.x;
                                pressedobject.clicky = mousey - v.y;
                                pressedobject.fixscrollbar(pressedobject);
                                ///  }
                            }
                            if (overobject) {
                                overobject.onmousemove();
                            }



                            if (draggedobject !== undefined && mousest === 2) {
                                ///// update drag position
                                draggedobject.x = dragx + mousex - mousex0;
                                draggedobject.y = dragy + mousey - mousey0;
                                /// are we over another object ?
                                if (draggedobject.limited) {
                                    draggedobject.dolimit()
                                }
                            }
                        } ////end mouse move 
                        if (type === MOUSEUP) {
                            control3d = false;
                            overobject = ob;
                            if (pressedobject) {
                                pressedobject.onmouseup();
                                if (pressedobject.kind === "3d")
                                    control3d = true;

                            }

                            if (ob === pressedobject)
                                clickedobject = ob;
                            if (clickedobject) {
                                if (ob.kind === LISTITEM) {

                                    ob.checked = !ob.checked;
                                    ob.parent.selecteditem = ob; ////in any case 
                                    ob.parent.listpressed(ob);
                                    ob.pressed = 1;
                                    ob.parent.setselindex(ob);

                                    ob.parent.onclick(); ////// list item click notify parent
                                    /// handle auto dropdown list;
                                    if (ob.parent.parent.kind === "dropdown") {

                                        //ob.parent.visible = false;
                                        ob.parent.parent.childs[0].title = ob.title;

                                        ob.parent.parent.onclick();
                                    }

                                }
                                clickedobject.onclick(); //// 
                                if (clickedobject.parent) {
                                    clickedobject.parent.onchildclicked(clickedobject)
                                }

                                switch (clickedobject.command) {
                                    case 0:
                                        break;
                                    case SCFIRST:
                                        sm.gotoscene(0);
                                        break;
                                    case SCNEXT:
                                        sm.gonext();
                                        break;
                                    case SCPREVIOUS:
                                        sm.goprevious();
                                        break;
                                    case SCANY:
                                        sm.gotoscene(clickedobject.commandlist[0]);
                                        break;
                                    case "any":
                                        sm.gotoscene(clickedobject.commandlist[0]);
                                        break;
                                    case FSON:
                                        fullscreenon();
                                        break;
                                    case FSOFF:
                                        fullscreenoff();
                                        break;
                                } /// end switch
                            } /// end clicked 
                            /// if mousest=3 dragged dropped 
                            //////// handle drop
                            if (draggedobject && overobject2) {
                                sm.ondrop(draggedobject, overobject2);
                                overobject2.ondrop(draggedobject, overobject2);
                                if (overobject2.parent) {
                                    overobject2.parent.ondrop(draggedobject, overobject2)
                                }
                            }
                            ;

                            draggedobject = undefined;
                        } /// end mouseup
                        //////useless  
                        for (i = this.childs.length - 1; i > -1; i--) {
                            this.childs[i].onevent(e, type);
                        }
                        for (i = sm.childs.length - 1; i > -1; i--) {
                            sm.childs[i].onevent(e, type);
                        }
                    };
                    Scene.prototype.userevent = function (e, type) {
                        ///    override if have special message
                        //// do nothing user defines his event 
                        //all scene events handled by childs now user

                        // if (type === MOUSEUP) {
                        //        unpress(pressedobject);
                        //      pressedobject = 0;
                        //   }
                    };
                    /// class         ---------------------------- S c e n e  M a n a g e r    -----------------------------   
                    function SceneManager() {
                        fpst0 = 0; //Date.now();
                        ///var that=this;

                        Form.call(this, "idSM", "title", 0, 0, logw, logh);
                        this.messages = [];
                        //this.addbuttoncommand(SCFIRST, [], 0, " menu", 0, 0, 128, 64, iconhome);
                        this.name = "SceneManager";
                        this.scenes = []; ////  collection of scenes;
                        this.current = 0; //first scene
                        this.currentscene = 0; /// noscene
                        this.images = [];
                        this.dwin;

                        check1 = this.createimage("images/check1.png");
                        check2 = this.createimage("images/check2.png");
                        radio1 = this.createimage("images/radio1.png");
                        radio2 = this.createimage("images/radio2.png");
                        iconhome = this.createimage("images/iconhome.png");

                        iconinfo = this.createimage("images/iconinfo.png");

                        clock1 = this.createimage("images/clock1.png");
                        clock2 = this.createimage("images/clock2.png");
                        clock3 = this.createimage("images/clock3.png");
                        clock4 = this.createimage("images/clock4.png");
                        clock5 = this.createimage("images/clock5.png");
                        clock6 = this.createimage("images/clock6.png");
                        clock7 = this.createimage("images/clock7.png");


                        iconabout = this.createimage("images/aboutbtn.png");
                        iconhelp = this.createimage("images/helpbtn.png");
                        iconclose = this.createimage("images/closebtn.png");
                        icondropdown = this.createimage("images/dropdown.png");
                    } // end scene Manager def
                    SceneManager.prototype = Object.create(Form.prototype);
                    SceneManager.prototype.constructor = SceneManager;
                    SceneManager.prototype.adddebug = function () {
                        this.dwin = this.addform(0, "", 0, 0, 256 + 1000 * (debug === false), 512);
                        this.dwin.drawbackground = false;
                        //this.dwin.textcolor = "grey";
                        this.dwin.draggable = true;
                        this.dwin.drawoutline = true;
                    }
                    
                    SceneManager.prototype.setscene = function () {
                        this.currentscene = this.scenes[this.current]; //// always have scene
                        this.onresize();
                    };
                    SceneManager.prototype.createscene = function () {
                        gok = true;
                        var ns = new Scene();
                        this.scenes.push(ns);
                        this.setscene();
                        return ns;
                    };
                    SceneManager.prototype.addscene = function () {
                        var ns = new Scene();
                        this.scenes.push(ns);
                        //this.childs.push(awin);
                        //this.setscene();
                        return ns;
                    };
                    SceneManager.prototype.adddialog = function (w, h, imres, scenetogo) {
                        var ns = new Scene();
                        this.scenes.push(ns);
                        var nf = ns.addform(0, "", 0, 0, w, h, imres);

                        var cb = nf.addbutton(0, "", w - 48, 4, 48, 48, iconclose);
                        cb.onclick = function () {
                            sm.gotoscene(scenetogo);
                        }
                        return ns;
                    };
                    SceneManager.prototype.createimage = function (fn) {
                        var ns = new ImageResource(fn);
                        this.images.push(ns);
                        return ns;
                    };
                    SceneManager.prototype.scenexists = function (n) {
                        var le = this.scenes.length;
                        if (le < 1)
                            return false;
                        return (n > -1 && n < le);
                    };
                    SceneManager.prototype.gotoscene = function (n) {
                        this.current = 0;
                        if (this.scenes.length < 1) {
                            alert("NO SCENE NO APP");
                            return;
                        }
                        if (n > -1 && n < this.scenes.length) {
                            this.current = n;
                        }
                        //this.currentscene = this.scenes[this.current]; //// always have scene
                        this.setscene();
                    };
                    SceneManager.prototype.gonext = function () {
                        this.current++;
                        if (this.current >= this.scenes.length) {
                            this.current = 0;
                        }
                        //this.currentscene = this.scenes[this.current]; //// always have scene
                        this.setscene();
                    };
                    SceneManager.prototype.goprevious = function () {
                        this.current--;
                        if (this.current < 0) {
                            this.current = this.scenes.length - 1;
                        }
                        this.setscene();
                        //this.currentscene = this.scenes[this.current]; //// always have scene
                    };
                    SceneManager.prototype.draw = function (ctx) {
                        // this.messages=[]; 
                        this.dwin.visible = debug;
                        frames++;
                        fpst = time1; //Date.now();
                        if (fpst - fpst0 > 1) {
                            fps = frames;
                            fpst0 = fpst;
                            frames = 0;

                        }
                        // ctx2.fillStyle = rgb(0,0,255);// this.backcolor;
                        //ctx2.fillRect(0, 0, canvaswidth, canvasheight);
                        ctx.fillStyle = this.backcolor;
                        //if (this.drawbackground) ctx.fillRect(0, 0, canvas.width, canvas.height);
                        ctx.clearRect(0, 0, canvas.width, canvas.height);
                        ctx.save();
                        viewtr.reset();
                        //gsc=2.5;
                        viewtr.translate(0, 0);
                        viewtr.scale(gsc, gsc);
                        settransform(ctx, viewtr);
                        // set canvas transform
                        //canvas.style.transform="scale('+gsc+','+gsc+')";
                        //setelementpos(canvas,0,0);
                        if (this.scenes.length > 0) {
                            this.currentscene.draw(ctx);
                            // ctx.fillText(info, 0, 4);     
                        }
                        var i = 0;
                        for (i = this.childs.length - 1; i > -1; i--) {
                            this.childs[i].draw(ctx);
                        }

                        if (debug) {

                            this.dwin.texts = [];
                            this.dwin.addtext("fps", fps);
                            this.dwin.addtext("mousest", mousest);
                            this.dwin.addtext("over", obtitle(overobject));
                            if (overobject) {
                                this.dwin.addtext("overect", concat(toint(overobject.x), toint(overobject.y), toint(overobject.width), toint(overobject.height)));

                            }
                            this.dwin.addtext("over 2", obtitle(overobject2));

                            this.dwin.addtext("pressed", obtitle(pressedobject));
                            this.dwin.addtext("dragged", obtitle(draggedobject));
                            this.dwin.addtext("mouse x,y", toint(mousex), ",", toint(mousey));

                            this.dwin.addtext("w pix ratio", window.devicePixelRatio);
                            this.dwin.addtext("canvas", canvas.width, canvas.height);


                            this.dwin.addtext("wiw wih ", window.innerWidth, window.innerHeight);


                            this.dwin.addtext("outer ", window.outerWidth, window.outerHeight);


                            this.dwin.addtext("screen", window.screen.width, window.screen.height);


                            this.dwin.addtext("avail", window.screen.availWidth, window.screen.availHeight);
                            for (i = 0; i < debugs.length; i++) {
                                this.dwin.addtext(debugs[i]);
                            }
                            this.dwin.addtext("edeltay", edeltay);

                            //this.dwin.draw(ctx);
                            debugs = [];

                        }/// end debug
                        ctx.restore();
                    };
                    SceneManager.prototype.onevent = function (e, type) {
                        // hope all info in global vars

                        // this.currentscene.userevent(e, type); 
                        //   if (type === MOUSEUP) {
                        //     unpress(pressedobject);
                        //        pressedobject = 0;
                        //   } 

                        this.currentscene.onevent(e, type);
                        /// already all childs notified but if 
                        ///************* caution 
                        this.currentscene.userevent(e, type);
                        if (type === MOUSEUP) {
                            unpress(pressedobject);
                            pressedobject = 0;
                        }




                        //

                    };
                    SceneManager.prototype.onresize = function () {
                        var scx = (canvas.width) / logw;
                        var scy = (canvas.height) / logh;
                        //var scx = (wiw) / this.width;
                        //var scy = (wih) / this.height;
                        gsc = Math.min(scx, scy);
                        //gsc=gsc/ window.devicePixelRatio;
                        /// center form0
                        if (!gok)
                            return; /// no forms 0 to center
                        var fo = this.currentscene.childs[0];
                        if (fo) {
                            fo.x = (canvas.width / gsc - fo.width) / 2;
                            fo.y = (canvas.height / gsc - fo.height) / 2;

                        }
                    };

                    Form.prototype.addtoolbar = function (id, title, x, y, width, height, cols, rows, im1, im2, imw, imh) {
                        var tb = new Toolbar(id, title, x, y, width, height, cols, rows, im1, im2, imw, imh);
                        this.addchild(tb);
                        return tb;


                    };

                    function Toolbar(id, title, x, y, width, height, cols, rows, im1, im2) {


                        Form.call(this, id, title, x, y, width, height, im1);
                        this.imw = width / cols;
                        this.imh = height / rows;
                        this.mask = this.addform(0, "", 0, 0, this.imw, this.imh, im2);
                        this.drawbackground = false;
                        this.mask.pickable = false;
                        this.mask.drawbackground = false;
                        this.cols = cols;
                        this.rows = rows;

                        this.im1 = im1;
                        this.im2 = im2;
                        this.col = 0;
                        this.row = 0;
                    }

/// caution after constructor 
                    Toolbar.prototype = Object.create(Form.prototype);
                    Toolbar.prototype.constructor = Toolbar;

                    Toolbar.prototype.drawmask = function (ctx) {
                        ///override this to your own draw
                        // make mask invisible



                    };

                    Toolbar.prototype.draw = function (ctx) {

                        Form.prototype.draw.call(this, ctx);  /// any way if must draw childs etc
                        //or  
                        // compute x,y    
                        // var x=this.xg+this.col*this.imw;
                        //var y=this.yg+this.row*this.imh;

                        this.mask.x = this.col * this.imw;
                        this.mask.y = this.row * this.imh;

                        this.drawmask(ctx);



                    };




                    Toolbar.prototype.onmousedown = function () {
                        this.col = toint(this.clickx / this.imw);
                        this.row = toint(this.clicky / this.imh);
                        /// check 	 
                    };
                    Toolbar.prototype.onmousemove = function () {

                    };
                    Toolbar.prototype.onmouseup = function () {};
                    Toolbar.prototype.onclick = function () {
                        //this.col=toint(this.clickx/this.imw);
                        // this.row=toint(this.clicky/this.imh);
                        /// check 

                    };

                    function fullscreenon(element) {
                        element = document.documentElement;
                        //element = window;
                        if (element.requestFullscreen) {
                            element.requestFullscreen();
                        } else if (element.mozRequestFullScreen) {
                            element.mozRequestFullScreen();
                        } else if (element.webkitRequestFullscreen) {
                            element.webkitRequestFullscreen();
                        } else if (element.msRequestFullscreen) {
                            element.msRequestFullscreen();
                        }

                        onresize();
                    }

                    function fullscreenoff() {
                        if (document.exitFullscreen) {
                            document.exitFullscreen();
                        } else if (document.mozCancelFullScreen) {
                            document.mozCancelFullScreen();
                        } else if (document.webkitExitFullscreen) {
                            document.webkitExitFullscreen();
                        }

                        onresize();
                    }

                    ////----------------------------------end drawing functions -------------------
                    ///------------------------------------------    app start 

                    ///----------------------------------------------------------------------------    
                    ///--------------------------------init 3d
                    function init3d() {
                        if (!Detector.webgl)
                            Detector.addGetWebGLMessage();
                        ///initmaterials();
                        canvas3d = getelement("canvas3d");
                        canvas3d.width = logw;
                        canvas3d.height = logh;
                        renderer = new THREE.WebGLRenderer({
                            canvas: canvas3d,
                            antialias: true
                        });
                        renderer.setSize(logw, logh);
                        renderer.setSize(canvas3d.width, canvas3d.height);

                        renderer.shadowMap.enabled = true;
                    }

                    function animate3d(frm) {
                        var dt = frm.dt;
                        var ascene = frm.scene;
                        var acamera = frm.camera;
                        var amouse = frm.mouse3d;
                        var ahitlist = frm.hitlist;
                        var amixer = frm.mixer;
                        var amixers = frm.mixers;
                        raycaster.setFromCamera(amouse, acamera);
                        var intersects = raycaster.intersectObjects(ahitlist);

                        if (intersects.length > 0) {

                            if (INTERSECTED !== intersects[0].object) {
                                if (INTERSECTED)
                                    INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
                                INTERSECTED = intersects[0].object;
                                INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
                                INTERSECTED.material.emissive.setHex(0x555555);
                            }
                        } else {
                            if (INTERSECTED)
                                INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
                            INTERSECTED = null;
                        }
                        renderer.render(ascene, acamera);
                        //stats.update();
                        if (frm.controls)
                            frm.controls.update;

                        if (amixer)
                            amixer.update(dt);
                    }

                    function render3d() {}
                    var w = window;
                    var requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
                    //////////////----------create sm    -----------------------------
                    var sm = new SceneManager();

                    function getmanager() {
                        return sm;
                    }

                    function main() {

                        time1 = Date.now() / 1000;
                        mousedx = mousex - pmousex;
                        mousedy = mousey - pmousey;
                        timedelta = (time1 - time0);//*(sm.stopped===false);// * timescale;
                        time = time + (timedelta);
                        if (timedelta > interval) {
                            //time0 = time1;
                            time0 = time1 - (timedelta % interval)
                            sm.draw(ctx); //////  render();
                            sm.messages = [];
                        }
                        pmousex = mousex;
                        pmousey = mousey;
                        // Request to do this again ASAP
                        requestAnimationFrame(main);
                    }


                    function start() {
                        time0 = Date.now() / 1000;
                        time = 0;
                        initialize();
                        if (can3d)
                            init3d();
                        sm.onresize();
                        main();
                    }

                    return {
                        start: start,
                        getmanager: getmanager,
                        renderer: renderer,
                        Form: Form,
                        Form3d: Form3d,
                        Clockwin: Clockwin,
                        Multistate: Multistate,
                        Toolbar: Toolbar
                    };
                }; /// end frame work
// notes renderer set pixelratio  renderer.setPixelRatio(window.devicePixelRatio);e