//draws rectangular frame, initially hidden
function _uFrame(opts) {
        this.props=$.extend({
            color: 'white', //background value for lines
            width: 1, //width of lines in pixel
            parentnode: document.body, //where children will be inserted
            callmousemove: null, //html object to which mousemove events will be triggered
            css: {} //additional css rules
        },opts || {});
        this.obj=[]; //[top,bottom,left,right div]
        for(var i=0;i<=3;i++) {
            this.obj[i]=$('<div></div>').css(this.props.css).css({position: 'absolute', display: 'none', 
                background: this.props.color,width: this.props.width+'px', height: this.props.width+'px',
                fontSize:0,overflow:'hidden'}).prependTo(this.props.parentnode).get(0);
            if(this.props.callmousemove) $(this.obj[i]).bind("mousemove",this.props.callmousemove,_uFrame._trigmousemove);
            }
        }
_uFrame._trigmousemove=function(e) {$(e.data).trigger(e);};
_uFrame.prototype={
    show:function(x,y,xs,ys) {
        if(xs<1 || ys<1) return;
        var w=this.props.width;
        $(this.obj[0]).css({left:x+'px',top:y+'px',width:(xs-w)+'px'});
        $(this.obj[1]).css({left:(x+w)+'px',top:(y+ys-w)+'px',width:(xs-w)+'px'});
        $(this.obj[2]).css({left:x+'px',top:(y+w)+'px',height:(ys-w)+'px'});
        $(this.obj[3]).css({left:(x+xs-w)+'px',top:y+'px',height:(ys-w)+'px'});
        $(this.obj).css("display","");
    },
    hide:function() {
        $(this.obj).css("display","none");
    },
    destroy:function() {
        $(this.obj).remove();
        this.obj=null;
    }
};



//number - number of frames in a pile
//numberneg - last numberneg of number will grow outside the specified box during show
function _uFramePile(number,numberneg,opts,defshow) {
    this.n=number;
    this.neg=numberneg;
    this.defshow=defshow;
    this.props=$.extend({
        colors: [],
        widths: [],
        empty: [], //true value means that corresponding frame is just empty space (no element created for it)
        parentnode: document.body,
        callmousemove: null,
        css: {}
    },opts || {});
    this.objs=[];
    for(var i=0;i<number;i++) {
        if(!this.props.empty[i]) 
            this.objs[i]=new _uFrame({color:this.props.colors[i],width:this.props.widths[i],css:this.props.css,parentnode:this.props.parentnode,callmousemove:this.props.callmousemove});
        else
            this.objs[i]=null;
    }
}

_uFramePile.prototype={
    show: function(x,y,xs,ys,bmask) {
	var mask=bmask ? bmask: this.defshow;
	var offset=0;
	for(var j=0;j<this.n-this.neg;j++) {
            if(this.objs[j])
	        if(mask & (1<<j)) this.objs[j].show(x+offset,y+offset,xs-offset*2,ys-offset*2);
		    else this.objs[j].hide();
	    offset+=this.props.widths[j];
	    }
	offset=0;
	for(var j=this.n-this.neg;j<this.n;j++) {
	    offset+=this.props.widths[j];
            if(this.objs[j])
	        if(mask & (1<<j)) this.objs[j].show(x-offset,y-offset,xs+offset*2,ys+offset*2);
		    else this.objs[j].hide();
	    }
    },
    hide: function() {
	for(var j=0;j<this.n;j++) if(this.objs[j]) this.objs[j].hide();
    },
    destroy: function() {
	for(var j=0;j<this.n;j++) if(this.objs[j]) {this.objs[j].destroy();this.objs[j]=null;}
    }
};


//photo  -  IMG object or id
//frames=[]; //[[x1,y1,xs1,ys1,param1],[x2,y2,xs2,ys2,param2],...]
function _uPhotoGUI(photo,width,height,frames,opts) {
    this.obj=typeof(photo)=='string' ? $('#'+photo)[0] : photo;
    if(!this.obj)return;

    this.width=width ? width : this.obj.width; 
    this.obj.width=this.width;
    this.height=height ? height: this.obj.height; 
    this.obj.height=this.height;
    if(this.width<20 || this.height<20) return;

    this.idx=_uPhotoGUI.nextidx++;
    _uPhotoGUI.all[this.idx]=this;
    this.destroyed=0;

    this.mode=0;//edit mode:0 - disabled, 1 - enabled, 2 - edit dialog enabled
    this.frames=frames || [];

    this.props=$.extend({
        edit:0,//if true then allow adding and removing marks
        parentnode: document.body, //parent of all controls and photo;here new children will be added (boxframe elements);it must be positioned or BODY
        firstshow: '<div style="border:1px solid white"></div>',//html text or object to be used for first show of all parts
        tipbox:'<div style="padding:2px; background:white;opacity:0.80; filter:alpha(opacity=80)"></div>', //html of box with frame title or HTML object
        tipframe: '<div style="background:url(/.s/img/1px.gif); z-index:2"></div>', //html text or object of frame box when no editing enabled
        tipframepile:[3,1,['black','white','#E0E030'],[1,1,1],3], //total number of lines, number or lines (among total) with grow outside their box,colors of lines,widths of lines,default show mask,empty values of lines (array of flags)
        pilelinecss: {opacity:0.90,zIndex:2}, //common style of pile lines
        startbut:null,//id or html object which will be hidden on start of edit and shown on finish of edit
        stopbut:null,//id or html object which will be shown on start of edit and hidden on finish of edit
        sizeboxcss:{background:'white',opacity:0.80,zIndex:3},
        indframe: '<div style="background:black; opacity:0.10; filter:alpha(opacity=10);z-index:6"></div>', //html text or object of frame box which selects starting point of editing
        indframepile:[2,1,['black','white'],[1,1],3],
        editframe: '<div style="cursor:move;background:#FFFF00; opacity:0.10; filter:alpha(opacity=10); z-index:2"></div>', //html text or object of resizing frame box when user selected starting point
        editframepile:[2,1,['black','white'],[1,1],3],
        addwndtitle:'New',
        addwndcont:'&nbsp;',
        addwndw:-200,
        addwndh:-80,
        addwndparent:null,
        app:null, //app for add window and THIS for functions
        tipfunc: null, //(param); by PARAM element in provided frames returnes html string for tip box
        addfunc: null, //(gidx,idx,param,editmode,init);gidx - idx of this gui object (index in _uPhotoGUI.all),idx - index of current frame, param - params of frame or NULL if must be skiped,editmode - true if we are in edit mode (for ability to rebuild list), init - true if list must be cleared as all frames will be enumed
        rebuildonedit: 0, //if true, then frame list is rebuilt (by calling addfunc) when edit starts or stops (for accounting of editmode param)
        delfunc: null, //(idx,userparam); idx - index of frame being removed, userparam - param passed to delpart
        showdialog: null //(gui,addwnd); called after addwnd is shown for ability to set focus in it or assign something
    },opts || {});
    this.edit=this.props.edit;
    this.tmtip=-1;//timer for tips
    this.tipactive=0;
    this.tipbox=typeof(this.props.tipbox)=='string' ? $(this.props.tipbox)[0] : this.props.tipbox;
    this.tipframe=typeof(this.props.tipframe)=='string' ? $(this.props.tipframe)[0] : this.props.tipframe;
    this.tipframepile=new _uFramePile(this.props.tipframepile[0],this.props.tipframepile[1],{colors:this.props.tipframepile[2],widths:this.props.tipframepile[3],empty:this.props.tipframepile[5],css:this.props.pilelinecss,parentnode:this.props.parentnode},this.props.tipframepile[4]);
    with (this) {
        $([tipbox,tipframe]).css({display:'none',position:'absolute',zIndex:1}).prependTo(props.parentnode);
        $([tipframe]).css({overflow:'hidden',fontSize:0});
    }
    this.firstshow=1;
    

    this.sizebox={}; //divs of size boxes
    this.editbox=[];//[x,y,w,h] of current editbox
    this.indwsize=this.indhsize=(this.width+this.height)/20 > 20 ? Math.floor((this.width+this.height)/40)*2 : 20;

    //these vars are necessary in edit mode only
    if(this.edit) {
        this.indframe=typeof(this.props.indframe)=='string' ? $(this.props.indframe)[0] : this.props.indframe;
        this.indframepile=new _uFramePile(this.props.indframepile[0],this.props.indframepile[1],{colors:this.props.indframepile[2],widths:this.props.indframepile[3],empty:this.props.indframepile[5],css:this.props.pilelinecss,parentnode:this.props.parentnode,callmousemove:this.obj},this.props.indframepile[4]);
        this.editframe=typeof(this.props.editframe)=='string' ? $(this.props.editframe)[0] : this.props.editframe;
        this.editframepile=new _uFramePile(this.props.editframepile[0],this.props.editframepile[1],{colors:this.props.editframepile[2],widths:this.props.editframepile[3],empty:this.props.editframepile[5],css:this.props.pilelinecss,parentnode:this.props.parentnode,callmousemove:this.obj},this.props.editframepile[4]);
        with (this) {
            $([indframe,editframe]).css({display:'none',position:'absolute',fontSize:0,overflow:'hidden',zIndex:1}).prependTo(props.parentnode);
        }

        this._resize=new _uDraggable(this,this._onrsmousemove,null);//,this.onstartrs,this.onstoprs),
        this._moveedit=new _uDraggable(this,this._ondrageditmousemove,null);//,this.onstartrs,this.onstoprs),
        this._resizeind=new _uDraggable(this,this._onrsindmousemove,null,null,this._onrsindstop);//,this.onstartrs,this.onstoprs),
        for (var i in {nw:1,ne:1,sw:1,se:1,n:1,s:1,w:1,e:1}) 
            this.sizebox[i]=$('<div></div>').css(this.props.sizeboxcss).
                css({position: 'absolute', display: 'none', width:'6px',height:'6px', fontSize: 0, cursor: i+'-resize', overflow:'hidden'}).
                prependTo(this.props.parentnode).bind("mousedown",{obj:this,tp:i},_uPhotoGUI._ondownsizebox).get(0);
        this.addwnd=new _uWnd('',this.props.addwndtitle,this.props.addwndw,this.props.addwndh,{
            hidden:1,autosize:0,min:0,max:0,fadetype:0,fadeclosetype:0,closeonesc:1,
            parent:this.props.addwndparent,resize:0,fixed:0,
            onbeforeclose:function(w){w.hide();w._phgui.startedit();return 1;}
            },this.props.addwndcont,null,this.props.app);
        this.addwnd._phgui=this;
        this.startbut=typeof(this.props.startbut)=='string' ? $('#'+this.props.startbut)[0] : this.props.startbut;
        this.stopbut=typeof(this.props.stopbut)=='string' ? $('#'+this.props.stopbut)[0] : this.props.stopbut;

        $(this.indframe).bind("click",this,function(e){e.data._onclickind(e);}).bind("mousedown",this,_uPhotoGUI._ondownindframe);
        $(this.editframe).bind("mousedown",this,_uPhotoGUI._ondowneditframe);
    } 

    var dt=this.frames;
    for(var i=0;i<dt.length;i++) {
	dt[i][0]=Math.floor(dt[i][0]*this.width);
	dt[i][1]=Math.floor(dt[i][1]*this.height);
	dt[i][2]=Math.floor(dt[i][2]*this.width);
	dt[i][3]=Math.floor(dt[i][3]*this.height);
        if(this.props.addfunc) this.props.addfunc.call(this.props.app,this.idx,i,dt[i][4],false,i==0?1:0); //build initial list of frames
    }
    this.firstdivs=null;
    if(dt.length>0) $(this.obj).bind("mousemove",this,_uPhotoGUI._onphotomousemove);
    $(this.obj).bind("click",this,_uPhotoGUI._onphotoclick);

    this.lastrecalc=0;
    this.parentoff=null;
    this.photooff=null;

    if(!_uPhotoGUI.globalset) {
        _uPhotoGUI.globalset=1;
        $(document).bind("mousemove",_uPhotoGUI._onmousemove);
    }
}
_uPhotoGUI.globalset=0;
_uPhotoGUI.all={};
_uPhotoGUI.nextidx=1;

_uPhotoGUI._onphotomousemove=function(e) {
    var o=e.data;
    $(o.obj).unbind("mousemove");
    o.showall();
};
_uPhotoGUI._onphotoclick=function(e) {
    if(e.which!=1) return;
    e.data._onclickphoto(e);
};

_uPhotoGUI._onmousemove=function(e) {
    for(var i in _uPhotoGUI.all) if(_uPhotoGUI.all[i]) _uPhotoGUI.all[i]._onglobalmousemove(e);
};
_uPhotoGUI._ondownsizebox=function(e) {
    if(e.which!=1) return;
    var o=e.data.obj;
    if(o.mode!=2) return;
    o._resize.start(e,o.editbox[0],o.editbox[1],o.editbox[2],o.editbox[3],e.data.tp);
}
_uPhotoGUI._ondowneditframe=function(e) {
    if(e.which!=1) return;
    var o=e.data;
    if(o.mode!=2) return;
    o._moveedit.start(e,o.editbox[0],o.editbox[1]);
}
_uPhotoGUI._ondownindframe=function(e) {
    if(e.which!=1) return;
    var o=e.data;
    if(o.mode!=1) return;
    o._recalcoff();
    o._resizeind.start(e,e.pageX-o.photooff.left,e.pageY-o.photooff.top,[0]);
}


_uPhotoGUI.prototype={
    showall: function() {
        var dt=this.frames;
        if(this.firstdivs || dt.length==0)return; //if already created, then return
        this.firstdivs=[];
        this._recalcoff();
        var offx=this.photooff.left-this.parentoff.left,offy=this.photooff.top-this.parentoff.top;
        for(var i=0;i<dt.length;i++) {
            this.firstdivs[i]=typeof(this.props.firstshow)=='string' ? $(this.props.firstshow)[0] : $(this.props.firstshow).clone().get(0);
            $(this.firstdivs[i]).css({position:'absolute',fontSize:0,overflow:'hidden',zIndex:1}).prependTo(this.props.parentnode).
                css({left:(dt[i][0]+offx)+'px',top:(dt[i][1]+offy)+'px',width:(dt[i][2]-2)+'px',height:(dt[i][3]-2)+'px'});
        }
        setTimeout('var a=_uPhotoGUI.all['+this.idx+'];if(a)a.hideall();',1000);
    },
    hideall: function() {
      with(this) {
        if(!firstdivs) return;
        $(firstdivs).remove();
        firstdivs=null;
      }
    },
    _recalcoff: function() {
      var t=(new Date()).getTime();
      with(this) {
        if(t-lastrecalc>500 || t<lastrecalc) {
            parentoff=$(props.parentnode).offset();
            photooff=$(obj).offset();
            lastrecalc=t;
        }
      }
    },
    _ondrageditmousemove:function(dx,dy,x,y) {
        var box=this.editbox;
	box[0]=x+dx;
	if(box[0]<0) box[0]=0;
	if(box[0]+box[2]>this.width) box[0]=this.width-box[2];

	box[1]=y+dy;
	if(box[1]<0) box[1]=0;
	if(box[1]+box[3]>this.height) box[1]=this.height-box[3];
        this._updateeditbox();
    },
    _onclickphoto:function(e) {
        if(this.destroyed || this.mode!=2)return;
        this._recalcoff();
	var box=this.editbox,p=this.photooff;
	box[0]=e.pageX-p.left-Math.floor(box[2]/2);
	box[1]=e.pageY-p.top-Math.floor(box[3]/2);
	if(box[0]<0) box[0]=0;
	if(box[0]+box[2]>this.width) box[0]=this.width-box[2];
	if(box[1]<0) box[1]=0;
	if(box[1]+box[3]>this.height) box[1]=this.height-box[3];
	this._updateeditbox();
        e.stopPropagation();
        e.preventDefault();
    },
    _onrsmousemove:function(dx,dy,x,y,xs,ys,m) {
        var minw=20,minh=20,box=this.editbox;
	if(m.indexOf('n')>=0) {
		box[1]=y+dy;
		if(box[1]<0) box[1]=0;
		box[3]=y+ys-box[1];
		if(box[3]<minh) {box[1]=y+ys-minh;box[3]=minh;}
		}
	if(m.indexOf('s')>=0) {
		box[3]=ys+dy;
		if(box[3]<minh) box[3]=minh;
		if(y+box[3]>this.height) box[3]=this.height-y;
		}
	if(m.indexOf('w')>=0) {
		box[0]=x+dx;
		if(box[0]<0) box[0]=0;
		box[2]=x+xs-box[0];
		if(box[2]<minw) {box[0]=x+xs-minw;box[2]=minw;}
		}
	if(m.indexOf('e')>=0) {
		box[2]=xs+dx;
		if(box[2]<minw) box[2]=minw;
		if(x+box[2]>this.width) box[2]=this.width-x;
		}
        this._updateeditbox();
    },
    _updateeditbox:function() {
      with(this) {
        if(destroyed)return;
        _recalcoff();
	var x=editbox[0]+photooff.left-parentoff.left,y=editbox[1]+photooff.top-parentoff.top,
	    xs=editbox[2],ys=editbox[3];
	indwsize=xs;
	indhsize=ys;
        $(editframe).css({left:x+'px',top:y+'px',width:xs+'px',height:ys+'px',display:""});
        editframepile.show(x,y,xs,ys);

	$(sizebox.nw).css({left:(x+1)+'px',top:(y+1)+'px',display:''});
	$(sizebox.ne).css({left:(x+xs-6-1)+'px',top:(y+1)+'px',display:''});
	$(sizebox.n).css({left:(x+Math.floor((xs-6)/2))+'px',top:(y+1)+'px',display:''});
	$(sizebox.w).css({left:(x+1)+'px',top:(y+Math.floor((ys-6)/2))+'px',display:''});
	$(sizebox.e).css({left:(x+xs-6-1)+'px',top:(y+Math.floor((ys-6)/2))+'px',display:''});
	$(sizebox.sw).css({left:(x+1)+'px',top:(y+ys-6-1)+'px',display:''});
	$(sizebox.se).css({left:(x+xs-6-1)+'px',top:(y+ys-6-1)+'px',display:''});
	$(sizebox.s).css({left:(x+Math.floor((xs-6)/2))+'px',top:(y+ys-6-1)+'px',display:''});

        var d=_uWnd.getdims();
        var rtl=window._rtl && x+parentoff.left-addwnd.width-10>d.clientLeft+10; //do put window too close to left edge of screen
        if(window._rtl || x+xs+parentoff.left+10+addwnd.width>d.clientLeft+d.clientW-10) addwnd.moveTo(x+parentoff.left-addwnd.width-10,y+parentoff.top);
            else addwnd.moveTo(x+xs+parentoff.left+10,y+parentoff.top);
        addwnd.show();
        addwnd.activate();
        if(this.props.showdialog) this.props.showdialog.call(this.props.app,this,this.appwnd);
      }
    },
    hideeditbox:function() {
        if(this.destroyed || !this.edit)return;
	$(this.editframe).css('display','none');
        this.editframepile.hide();
        for(var i in {nw:1,ne:1,sw:1,se:1,n:1,s:1,w:1,e:1}) $(this.sizebox[i]).css('display','none');
        this.addwnd.hide();
    },
    _onglobalmousemove: function(e) {
        if(this.destroyed) return;
        this._recalcoff();
        var x=e.pageX,y=e.pageY,p=this.photooff;
        if(x>=p.left && x<p.left+this.width && y>=p.top && y<p.top+this.height) {
            if(this.mode==0) this.checktip(x-p.left,y-p.top);
                else if(this.mode==1 && !this._resizeind.active) this.showind(x-p.left,y-p.top,1);
        } else { //cursor is outside the photo
            if(this.mode==1 && !this._resizeind.active) this.hideind();
        }
    },
    checktip: function (x,y) { //check that we must show a tip at specified position relative to photo
        if(this.destroyed)return;
	var dt=this.frames;
	var nearest=-1;//,nearest_len=0;
	for(var i=0;i<dt.length;i++) {
		if(!dt[i]) continue;
		if(x>=dt[i][0] && x<dt[i][0]+dt[i][2] && y>=dt[i][1] && y<dt[i][1]+dt[i][3]) {
			nearest=i;break;
		}
        }
	if(this.tmtip!=-1) {clearTimeout(this.tmtip);this.tmtip=-1;}
	if(nearest>=0) {
		this.showtip(dt[nearest]);
		this.tmtip=setTimeout('var a=_uPhotoGUI.all['+this.idx+'];if(a){a.tmtip=-1;a.hidetip();}',5000);
		return;
		}
	if(this.tipactive)
		this.tmtip=setTimeout('var a=_uPhotoGUI.all['+this.idx+'];if(a){a.tmtip=-1;a.hidetip();}',800);
    },
    showpart:function(idx,short) { //shows specified tip until explicit hide
        if(this.destroyed)return;
	var dt=this.frames;
	if(!dt[idx]) return;
	if(this.tmtip!=-1) {clearTimeout(this.tmtip);this.tmtip=-1;}
	this.showtip(dt[idx],short);
    },
    delpart:function(idx,param) { //remove specified frame
        if(this.destroyed)return;
	var dt=this.frames;
	if(!dt[idx]) return;
	dt[idx]=null;
	if(this.props.delfunc) this.props.delfunc.call(this.props.app,idx,param);
	this.hidetip();
    },
    addframe:function(params) {
      with(this) {
        if(destroyed || mode!=2 || !edit)return;
	var t=editbox,arr=frames,i;
	i=arr.length;
	arr[i]=[t[0],t[1],t[2],t[3],params];
        if(props.addfunc)
            props.addfunc.call(props.app,idx,i,params,true,0);

	startedit();
	showpart(i);
	tmtip=setTimeout('var a=_uPhotoGUI.all['+idx+'];if(a){a.tmtip=-1;a.hidetip();}',1500);
      }
    },
    showtip: function(coord,short) {
        if(this.destroyed)return;
        this._recalcoff();
        var offx=this.photooff.left-this.parentoff.left,offy=this.photooff.top-this.parentoff.top;
	$(this.tipframe).css({left:(coord[0]+offx)+'px',top:(coord[1]+offy)+'px',width:coord[2]+'px',height:coord[3]+'px',display:""});
	this.tipframepile.show(coord[0]+offx,coord[1]+offy,coord[2],coord[3],short ? 3 : 7);

	if(!short && this.props.tipfunc)
    	    $(this.tipbox).html(this.props.tipfunc(coord[4])).css({left:(coord[0]+offx)+'px',top:(coord[1]+coord[3]+offy)+'px',visibility:"visible",display:"block"});
	    else this.tipbox.style.display='none';
        this.tipactive=1;
    },
    _onrsindstop:function(ox,oy,st) {
        if(this.destroyed)return;
        if(st[0])this.stopind();
    },
    _onrsindmousemove:function(dx,dy,ox,oy,st) { //x and y are starting posing relative to photo;st - 1 element array with flag telling whether resize was started by passing minimal distance
        if(this.destroyed)return;
        this._recalcoff();
        if(!st[0]) { //resize has not been started yet
            if(Math.abs(dx)<5 || Math.abs(dy)<5) return;
            st[0]=1;
        }
        //correct dx and dy to not exceed photo boundaries
        var x=ox+dx,y=oy+dy;
	if(x<0) x=0;
	    else if(x>=this.width) x=this.width-1;
	if(y<0) y=0;
	    else if(y>=this.height) y=this.height-1;
        dx=x-ox;
        dy=y-oy;
        //dx and dy corrected
        x=ox;
        y=oy;
	if(dx<0) {x+=dx;dx=-dx;}
	if(dy<0) {y+=dy;dy=-dy;}
	if(dx<=0) dx=1;
	if(dy<=0) dy=1;

	this.indwsize=dx;
	this.indhsize=dy;
	this.showind(x,y);

	if(dx<20) dx=20;
	if(dy<20) dy=20;
	if(x+dx>=this.width) x=this.width-1-dx;
	if(y+dy>=this.height) y=this.height-1-dy;
	this.editbox=[x,y,dx,dy];
    },
    hidetip: function() {
      with(this) {
        if(destroyed)return;
	if(tmtip!=-1) {clearTimeout(tmtip);tmtip=-1;}
	$([tipbox,tipframe]).css('display','none');
        tipframepile.hide();
        tipactive=0;
      }
    },
    _onclickind: function(e) {
        if(this.destroyed || e.which!=1 || this.mode!=1)return;
        this._recalcoff();
        var x=e.pageX-Math.floor(this.indwsize/2),y=e.pageY-Math.floor(this.indhsize/2),p=this.photooff;
        x-=p.left;
        y-=p.top;
        if(x<0) x=0;
	    else if(x+this.indwsize>=this.width) x=this.width-this.indwsize;
        if(y<0) y=0;
	    else if(y+this.indhsize>=this.height) y=this.height-this.indhsize;
        this.stopind([x,y,this.indwsize,this.indhsize]);
    },
    stopind: function(edbox) {
        if(this.destroyed || !this.edit || this.mode<1)return;
	this.hideind();
	this.mode=2;
        if(edbox) for(var i=0;i<edbox.length;i++) this.editbox[i]=edbox[i];
	this._updateeditbox();
    },
    showind: function(x,y,center) { //draw indicator around specified coords relative to photo; center - true is coords need to be centered relative to indicator size
        if(this.destroyed)return;
        this._recalcoff();
//	_phui_hidetip();
        if(center) {
            x-=Math.floor(this.indwsize/2);
            y-=Math.floor(this.indhsize/2);
            if(x<0) x=0;
		else if(x+this.indwsize>=this.width) x=this.width-this.indwsize;
            if(y<0) y=0;
		else if(y+this.indhsize>=this.height) y=this.height-this.indhsize;
        }
        var offx=this.photooff.left-this.parentoff.left,offy=this.photooff.top-this.parentoff.top;
	$(this.indframe).css({left:(x+offx)+'px',top:(y+offy)+'px',width:this.indwsize+'px',height:this.indhsize+'px',display:""});
        this.indframepile.show(x+offx,y+offy,this.indwsize,this.indhsize);
    },
    hideind:function() {
        if(this.destroyed)return;
	$(this.indframe).css('display','none');
        this.indframepile.hide();
    },
    startedit: function() { //enteres edit mode=1
      with(this) {
        if(destroyed || !edit)return;
	if(tmtip!=-1) {clearTimeout(tmtip);tmtip=-1;}
	hidetip();

        if(stopbut) stopbut.style.display='';
        if(startbut) startbut.style.display='none';
	hideeditbox();

	if(mode<1 && props.addfunc && props.rebuildonedit) {
	    var arr=frames;
	    for(var i=0;i<arr.length;i++)
                props.addfunc.call(props.app,idx,i,arr[i] ? arr[i][4] : null,true,i==0?1:0); //rebuild list for edit mode
	}
	mode=1;
      }
    },
    finishedit: function() {
      with(this) {
        if(destroyed || mode==0)return;
        hideind();

        if(stopbut) stopbut.style.display='none';
        if(startbut) startbut.style.display='';
	hideeditbox();
	mode=0;

	if(props.addfunc && props.rebuildonedit) {
	    var arr=frames;
	    for(var i=0;i<arr.length;i++)
                props.addfunc.call(props.app,idx,i,arr[i] ? arr[i][4] : null,false,i==0?1:0); //rebuild list for non-edit mode
	}
      }
    },
    destroy: function() {
        with(this) {
        if(destroyed)return;
            tipframepile.destroy();
            tipbox=tipframe=tipframepile=null;
            if(edit) {
                indframepile.destroy();
                editframepile.destroy();
                indframe=editframe=indframepile=editframepile=startbut=stopbut=null;
                addwnd.close();
                addwnd=null;
                sizebox=null;
                _resize=null;
            }
            hideall();
            destroyed=1;
            props=null;
            _uPhotoGUI.all[idx]=null;
        }
    }
};



// Adjust image

var _phctr_state=[]; //[offx,offy,unused,unused,imgx,imgy,scale,origimgx,origimgy,minscale,draggable]

function _phctr_init(id,origimgx,origimgy,scale,sldID,initx,inity,repcount) { //repcount used internally!!!!
	var o=$('#'+id)[0];
	if(!o || origimgx<0 || origimgy<0) return;
	var p=o.parentNode;
	if(!p || p.offsetHeight<=0 || p.offsetWidth<=0) return;
        if(typeof(initx)!='number') {initx=NaN;}
        if(typeof(inity)!='number') {inity=NaN;}
        if(typeof(scale)!='number' || isNaN(scale)) {scale=0;}
	if(origimgx==0 || origimgy==0) { //get size from image, IMG tag cannot have incorrect width or height specification!
            origimgx=o.width;
            origimgy=o.height;
            if(origimgx==0 || origimgy==0) { //try after timeout
                if(typeof repcount!='number' || isNaN(repcount)) repcount=1;
                if(repcount<=20)//maximum number of tries
                    setTimeout("_phctr_init('"+id+"',0,0,"+scale+",'"+sldID+"',"+initx+","+inity+","+(repcount+1)+");",100);
                return;
            }
        }
	var minscale=p.offsetWidth/origimgx;
	if(p.offsetHeight/origimgy > minscale) minscale=p.offsetHeight/origimgy; //now minscale contains minimal allowed scale
	if(!scale || scale<0) { //guess optimal scale
		if(minscale>=1) { //image is too small, so it cannot be compressed
			scale=minscale;
		} else {
			scale=(1+minscale)/2; //average
		}
	}
	var imgx=Math.round(origimgx*scale);
	var imgy=Math.round(origimgy*scale);
        if(typeof(initx)!='number' || isNaN(initx)) initx=-(imgx-p.offsetWidth)/2;
        if(typeof(inity)!='number' || isNaN(inity)) inity=-(imgy-p.offsetHeight)/2;
	_phctr_state[id]=[initx,inity,0,0,imgx,imgy,scale,origimgx,origimgy,minscale,new _uDraggable()];
        _phctr_state[id][10]=new _uDraggable(_phctr_state[id],_phctr_ondrag,null,null,null);
	o.width=imgx;
	o.height=imgy;
	o.style.left=""+Math.round(_phctr_state[id][0])+"px";
	o.style.top=""+Math.round(_phctr_state[id][1])+"px";
        $(p).unbind('mousedown').bind('mousedown',id,_phctr_myondown);

	new _uSlider(sldID,'h',minscale,1,{step:0,initval:scale,onchange:_phctr_setscale,param:id,disabled:(minscale<1 ? 0 : 1)});

}

function _phctr_setscale(v,id) {
	if(!_phctr_state[id]) return;
	var st=_phctr_state[id];
        var o=$('#'+id)[0];
	if(!o) return;
	var p=o.parentNode;
	if(!p || p.offsetHeight<=0 || p.offsetWidth<=0) return;
	if(v<st[9] || (st[9]>=1 && v!=st[9]) || (st[9]<1 && v>1)) v=st[9];
	var curscale=st[6];
//	st[0]=st[0]/curscale*v;
//	st[1]=st[1]/curscale*v;
	st[0]=-((-st[0]+p.offsetWidth/2)/curscale*v-p.offsetWidth/2);
	st[1]=-((-st[1]+p.offsetHeight/2)/curscale*v-p.offsetHeight/2);
	st[4]=Math.round(st[7]*v);
	st[5]=Math.round(st[8]*v);
	st[6]=v;
	if(Math.round(st[0])<-(st[4]-p.offsetWidth)) st[0]=-(st[4]-p.offsetWidth);
			else if(Math.round(st[0])>0) st[0]=0;
	if(Math.round(st[1])<-(st[5]-p.offsetHeight)) st[1]=-(st[5]-p.offsetHeight);
			else if(Math.round(st[1])>0) st[1]=0;
	o.width=st[4];
	o.height=st[5];	
	o.style.left=""+Math.round(st[0])+"px";
	o.style.top=""+Math.round(st[1])+"px";	
}


function _phctr_ondrag(dx,dy,id,x,y) {
    var o=$('#'+id)[0];
    var st=this;
    if(!st || !o) return;
    var p=o.parentNode;
    if(!p || p.offsetHeight<=0 || p.offsetWidth<=0) return;
    var offx=Math.round(x+dx);
    if(offx<-(st[4]-p.offsetWidth)) offx=-(st[4]-p.offsetWidth);
	else if(offx>0) offx=0;
    var offy=Math.round(y+dy);
    if(offy<-(st[5]-p.offsetHeight)) offy=-(st[5]-p.offsetHeight);
	else if(offy>0) offy=0;
    o.style.left=offx+"px";
    o.style.top=offy+"px";
    st[0]=offx;
    st[1]=offy;
}


function _phctr_myondown(e) {
        var id=e.data,st=_phctr_state[id];
        if(!$('#'+id)[0] || !st) return;
        st[10].start(e,id,st[0],st[1]);
}



