//------------------------------------------------------------------------------
// CLASS ImageSelection
//------------------------------------------------------------------------------
//
    function ImageSelection(manager,id,rid,layer,title) {
        
        this.manager = manager ;
        
        //dati
        this.id = id ;
        this.rid = rid ;
        this.layer = layer ;
        this.title = title ;

        //stato
        this.over = false ;
        this.selected = false ;
        this.modified = false ;
    }
    
    ImageSelection.prototype.changeID = function(newid, ownerLayer) {
        this.id = id ;
        this.layer.setAttribute("id", ownerLayer.id+"_sel"+newid) ;
    }
    
    ImageSelection.prototype.setTitle = function(title) {
        this.title = title ;
        this.layer.title = title ;
    }
    
    ImageSelection.prototype.highlight = function() {
        var cn = this.manager.editable ? 'selection ' : 'selection_invisible ' ;
        cn += this.over ? 'selection_over ' : '' ;
        cn += this.selected ? 'selection_sel ' : '' ;
        //cn += !this.selected && this.modified ? 'selection_mod ' : '' ;
        this.layer.className = cn ;
    }

    /**
     * Restituisce la percentuale in float della proprieta' passata nel range passato
     * 
     * @param styleProp la proprieta dello stile del layer corrente da utilizzare
     * @param range il range in base al quale scalare
     * @return un valore compreso tra 0 e 1 (verosimilmente)
     */
    ImageSelection.prototype.getFloatPercent = function(styleProp, range, correction) {
        var ret = parseInt(eval('this.layer.style.'+styleProp))+(correction ? correction : 0) ;
        ret = ret*1.0 / range ;
        return ret ;
    }
//
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
// CLASS ImageSelectionManager
//------------------------------------------------------------------------------
//
    /**
     * Nuovo gestore selezioni
     * 
     * @param layer il layer che contiene l'immagine (usato come contenitore
     *	dei layer di selezione e come sorgente degli eventi)
     * @param image l'immagine (come oggetto HTML)
     * @param xoff l'offset orizzontale eventuale del layer rispetto alla pagina (ATTENZ!)
     * @param yoff l'offset verticale eventuale del layer rispetto alla pagina (ATTENZ!)
     * @param selection la selezione iniziale
     */
    function ImageSelectionManager(layer,image,xoff,yoff,selection) {
        
        this.layer = layer ;
        this.image = image ;
        this.xoff = xoff ;
        this.yoff = yoff ;

        var instance = this ;
        this.layer.onmousedown = function(evt) {return instance.startSel(evt,instance) ;}
        //this.layer.onmousemove = function(evt) {instance.dragSel(evt,instance) ;}
        this.layer.onmouseup = function(evt) {instance.stopSel(evt,instance) ;}
        this.layer.onclick = function() {return true;}
        this.layer.onselectstart = function() {return false;}
        this.layer.ondragstart = function() {return false;}

        this.startEvt = new Object() ;
        this.startPnt = new Object() ;

        this.dragType = 1 ;
        this.dragging = false ;

        this.selections = new Array() ;
        this.selection = selection ;
        this.removedSelections = new Array() ;

        this.counter = 1 ;
        
        this.ajaxClient = new AjaxRequest() ;
        
        this.listenerList = new Array() ;
        this.editable = false ;
        this.blinkCounter = 0 ;

    }
        
    ImageSelectionManager.prototype.setEditable = function(editable) {
        if(this.editable!=editable) {
            this.editable = editable ;
            this.editableChanged = true ;
            this.clearSelection() ;
            this.refreshSelections() ;
        }
    }
    
    ImageSelectionManager.prototype.mousemove = function(evt) {
        this.dragSel(evt,this) ;
    }
    
    /*ImageSelectionManager.prototype.getSelectionClass = function(selection) {
        var ret = 'selection ' ;
        ret += (selection.layer.id==this.over) ? 'selection_over ' : '' ;
        ret += (selection.layer.id==this.selection) ? 'selection_sel ' : '' ;
        ret += (selection.layer.id!=this.selection && selection.modified) ? 'selection_mod ' : '' ;
        return ret ;
    }
    
    ImageSelectionManager.prototype.refreshSelectionClasses = function() {
        var i ;
        for(i=0;i<this.selections.length;i++) {
            var sel = this.selections[i] ;
            sel.layer.className = this.getSelectionClass(sel) ;
        }
    }*/
    
    /** Handler per il ricaricamento dell'immagine */
    ImageSelectionManager.prototype.imageChanged = function(rid, baseurl) {
        this.imgrid = rid ;
        this.load(baseurl) ;
    }
    
    ImageSelectionManager.prototype.setVisible = function(visible) {
        var i ;
        for(i=0;i<this.selections.length;i++)
            this.selections[i].style.visibility = visible ? 'visible' : 'hidden' ;
    }
    
    ImageSelectionManager.prototype.clearSelection = function() {
        var i ;
        for(i=0;i<this.selections.length;i++) {
            this.selections[i].over = false ;
            this.selections[i].selected = false ;
            this.selections[i].highlight() ;
        }
    }
    
    ImageSelectionManager.prototype.getZoneById = function(id) {
        var ret = null ;
        var i ;
        for(i=0;!ret && i<this.selections.length;i++)
            if(this.selections[i].id==id)
                ret = this.selections[i] ;
        return ret ;
    }
    
    /** Seleziona la selezione secondo l'evento passato e rllancia un'evento! */
    ImageSelectionManager.prototype.highlightById = function(source,evtType,id) {
        //this.clearSelection() ;
        if(id) {
            var i ;
            for(i=0;i<this.selections.length;i++) {
                var sel = this.selections[i] ;
                if(sel.id==id) {
                    switch(evtType) {
                        case 'out':       sel.over = false ;      break ;
                        case 'over':      sel.over = true ;       break ;
                        case 'deselected':sel.selected = false;   break ;
                        case 'selected':  sel.selected = true ;   break ;
                    }
                    sel.highlight() ;
                    if(sel!=source)
                        this.fireSelection(sel, evtType, id) ;
                }
            }
        }
    }
    
    ImageSelectionManager.prototype.selectOver = function() {
        var i ;
        for(i=0;i<this.selections.length;i++) {
            var sel = this.selections[i] ;
            if(sel.over) {
                if(!sel.selected) {
                    this.fireSelection(sel,'selected',sel.id) ;
                    sel.selected = true ;
                }
            } else {
                if(sel.selected) {
                    this.fireSelection(sel,'deselected',sel.id) ;
                    sel.selected = false ;
                }
            }
            sel.highlight() ;
        }
    }

    ImageSelectionManager.prototype.getSelectedZones = function() {
        var ret = new Array() ;
        var i ;
        for(i=0;i<this.selections.length;i++)
            if(this.selections[i].selected)
                ret.push(this.selections[i]) ;
        return ret ;
    }
        
    /*ImageSelectionManager.prototype.getEventZone = function(evtType) {
        var cmp = eval('this.'+evtType) ;
        var ret = null ;
        if(cmp) {
            var i ;
            for(i=0;!ret && i<this.selections.length;i++)
                if(this.selections[i].layer.id==cmp)
                    ret = this.selections[i] ;
        }
        return ret ;
    }*/

    ImageSelectionManager.prototype.deleteSelected = function() {
        var i ;
        var removal = new Array() ;
        var ids = "" ;
        for(i=0;i<this.selections.length;i++) {
            var sel = this.selections[i] ;
            if(sel.selected) {
                  removal.push(sel) ;
                  ids += sel.id+"," ;
            }
        }
        this.erase("mag?op=del-zones",ids+"0") ;//cancellazione non assicurata!
        for(i=0;i<removal.length;i++) {
            this.selections.remove(removal[i]) ;
            this.layer.removeChild(removal[i].layer) ;
            this.removedSelections.push(removal[i]) ;
        }
    }
    
    ImageSelectionManager.prototype.isDragEnabled = function() {
	//alert(this.image.parentNode.style.visibility) ;
	return this.image.parentNode.style.visibility=='visible' ;
    }
    
    ImageSelectionManager.prototype.getOffsetX = function() {
	return parseInt(document.body.scrollLeft)-this.layer.offsetLeft-this.xoff ;
    }
    ImageSelectionManager.prototype.getOffsetY = function() {
	return parseInt(document.body.scrollTop)-this.layer.offsetTop-this.yoff ;
    }
    
    ImageSelectionManager.prototype.addNewSelection = function(div,id,rid,minArea,modified) {

        var sel = new ImageSelection(this,id,rid,div) ;
        sel.modified = modified ;

        var man = this ;
        div.onmouseover = function(evt) {
            sel.over = true ;
            sel.highlight() ;
            man.over = true ;
            man.fireSelection(sel,'over',sel.id) ;
        }
        div.onmouseout = function(evt) {
            sel.over = false ;
            sel.highlight() ;
            man.dragType=1 ;
            man.over = false ;
            man.fireSelection(sel,'out',sel.id) ;
        }
        //div.onmousedown = function(evt) {man.startMove(evt,man,div) ;}
        //div.onmousemove = function(evt) {man.dragMove(evt,man,div) ;}
        //div.onmouseup = function(evt) {man.selectSel(this.id) ;}
        
        var ret = false ;
        if(!minArea || parseInt(div.style.width)*parseInt(div.style.height)>minArea) {
            var tit ;
            if(!modified || (tit=prompt("Titolo"))) {
                this.selections.push(sel) ;
                sel.setTitle(tit) ;
                this.counter++ ;
                
                if(modified) {
                    this.save("mag?op=save-zone",sel) ;
                }
                
                //div.className = this.getSelectionClass(sel) ;
                ret = sel ;
            }
        }
        if(!ret)
            this.layer.removeChild(sel.layer) ;
        
        return ret ;
    }
    
    /** Handler inizio selezione */
    ImageSelectionManager.prototype.startSel = function(evt, man) {
        evt = evt ? evt : window.event ;
        if(man.editable) {

            man.selectOver() ;
        
            if(man.dragType==1 && man.isDragEnabled()) {

                evt = evt ? evt : window.event ;
                man.startEvt.x = evt.clientX+man.getOffsetX() ;
                man.startEvt.y = evt.clientY+man.getOffsetY() ;

                man.dragging = true ;

                if(!this.over) {

                    var newDiv = document.createElement("div") ;
                    newDiv.setAttribute("id",man.layer.id+"_sel"+(-man.counter)) ;
                    man.layer.appendChild(newDiv) ;
                    newDiv.style.left = man.startEvt.x+'px' ;
                    newDiv.style.top = man.startEvt.y+'px' ;
                    newDiv.style.width = '1px' ;
                    newDiv.style.height = '1px' ;
                    newDiv.className = 'selection selection_new' ;

                } else {

                    if(evt.button!=2) {



                    }

                }
            }
            
        } else if(evt.button<2) {
            
            var i ;
            for(i=0;i<this.selections.length;i++) {
                var sel = this.selections[i] ;
                if(sel.over)
                    man.fireSelection(sel, "links", sel.rid) ;
            }
            
        }
        
        return false ;
        
    }

    /** Handler trascinamento selezione */
    ImageSelectionManager.prototype.dragSel = function(evt, man) {
        if(man.dragType==1 && man.dragging && man.editable) {
            evt = evt ? evt : window.event ;
            if(!this.over) {
                var sel = document.getElementById(man.layer.id+'_sel'+(-man.counter)) ;
                var x = evt.clientX+man.getOffsetX() ;
                var y = evt.clientY+man.getOffsetY() ;
                var w = x-man.startEvt.x ;
                var h = y-man.startEvt.y ;
                sel.style.left = (w<0 ? x : man.startEvt.x) + 'px' ;
                sel.style.top = (h<0 ? y : man.startEvt.y) + 'px' ;
                sel.style.width = Math.abs(w) + 'px' ;
                sel.style.height = Math.abs(h) + 'px' ;
            }
        }
    }

    /** Handler fine selezione */
    ImageSelectionManager.prototype.stopSel = function(evt, man) {
	
        if(man.dragging && man.dragType==1 && man.editable) {

            evt = evt ? evt : window.event ;

            if(!man.over) {
                
                var newDiv = document.getElementById(man.layer.id+'_sel'+(-man.counter)) ;

                //var ok = false ;
                //if(Math.abs(w)*Math.abs(h)>500) {

                    //newDiv.className = 'selection' ;
                    //newDiv.onmousedown = function(evt) {man.startMove(evt,man,newDiv) ;}
                    //newDiv.onmouseover = function(evt) {newDiv.className=man.getSelectionClass(newDiv.id)+' selection_over'}
                    //newDiv.onmousemove = function(evt) {man.dragMove(evt,man,newDiv) ;}
                    //newDiv.onmouseout = function(evt) {newDiv.className=man.getSelectionClass(newDiv.id);man.stopMove(evt,man);man.dragType=1}
                    //newDiv.onmouseup = function(evt) {man.stopMove(evt,man) ;}
                    //newDiv.title = 'Selezione n.'+man.counter+' ('+man.startEvt.x+','+man.startEvt.y+')' ;

                    //ok = man.addNewSelection(newDiv,-man.counter,1000) ;

                //}

                man.addNewSelection(newDiv,-man.counter,0,200,true) ;
                
            }

            man.dragging = false ;

        }
    }
    
    /** Handler inizio spostamento */
    ImageSelectionManager.prototype.startMove = function(evt, man, lay) {
          if(man.dragType==2 && man.isDragEnabled()) {
              man.selectSel(lay.id) ;
              evt = evt ? evt : window.event;
              man.startEvt.x = evt.clientX ;
              man.startEvt.y = evt.clientY ;
              man.startPnt.x = parseInt(lay.style.left) ;
              man.startPnt.y = parseInt(lay.style.top) ;
              man.dragging = true ;
          }
    }
    
    /** Handler spostamento */
    ImageSelectionManager.prototype.dragMove = function(evt, man, lay) {
        if(man.dragging && man.dragType==2) {
            lay.modified = true ;
            evt = evt ? evt : window.event ;
            lay.style.left = (man.startPnt.x+evt.clientX-man.startEvt.x) + 'px' ;
            lay.style.top = (man.startPnt.y+evt.clientY-man.startEvt.y) + 'px' ;
        } else if(man.dragType!=2)
            man.dragType = 2 ;
    }
    
    /** Handler fine spostamento */
    ImageSelectionManager.prototype.stopMove = function(evt, man) {
        if(man.dragType==2)
            if(man.dragging)
                man.dragging = false ;
    }
    
    ImageSelectionManager.prototype.load = function(baseurl) {
        
        var ajax = this.ajaxClient ;
        
        this.selections = new Array() ;
        
        var man = this ;
        var children = this.layer.childNodes ;
        var ci ;
        var toDel = new Array() ;
        for(ci=0;ci<children.length;ci++)
            if(children[ci].className.indexOf('selection')>=0)
                toDel.push(children[ci]) ;
        for(ci=0;ci<toDel.length;ci++)
            man.layer.removeChild(toDel[ci]) ;
        
        ajax.send(baseurl+"&rid="+this.imgrid, function(req) {
            if(req.getStatus()==200) {
                var xml = req.getResponseXML() ;
                var zones = xml.getElementsByTagName("z") ;
                var i ;
                for(i=0;i<zones.length;i++) {
                    var zone = zones.item(i) ;
                    var x = parseFloat(zone.getAttribute("x")) ;
                    var y = parseFloat(zone.getAttribute("y")) ;
                    var w = parseFloat(zone.getAttribute("w")) ;
                    var h = parseFloat(zone.getAttribute("h")) ;
                    var newDiv = document.createElement("div") ;
                    var id = parseInt(zone.getAttribute("id")) ;
                    var rid = parseInt(zone.getAttribute("rid")) ;
                    newDiv.setAttribute("id",man.layer.id+"_sel"+id) ;
                    //newDiv.className = 'selection' ;
                    newDiv.style.left = (parseInt(x*man.image.width)+man.image.offsetLeft)+'px' ;
                    newDiv.style.top = parseInt(y*man.image.height)+'px' ;
                    newDiv.style.width = parseInt(w*man.image.width)+'px' ;
                    newDiv.style.height = parseInt(h*man.image.height)+'px' ;
                    //newDiv.onmouseover = function(evt) {this.className=man.getSelectionClass(this.id)+' selection_over'}
                    //newDiv.onmouseout = function(evt) {this.className=man.getSelectionClass(this.id);man.stopMove(evt,man);man.dragType=1}
                    man.layer.appendChild(newDiv) ;
                    var sel = man.addNewSelection(newDiv, id, rid) ;
                    sel.selected = man.selection==id ;
                    sel.setTitle(zone.getAttribute("title")) ;
                }

                //aggiornamento grafica
                man.refreshSelections() ;
            }
        }) ;
        //this.ajaxClient.send(null) ;
    }
    
    ImageSelectionManager.prototype.blink = function(man) {
        if(!man.blinkStopper)
            if(man.blinkCounter<7) {
                man.blinkCounter++ ;
                man.editable = man.blinkCounter%2 == 0 ;
                man.highlight() ;
                window.setTimeout(man.blink,125,man) ;
            } else {
                man.blinkCounter = 0 ;
                man.editable = false ;
                man.highlight() ;
            }
        man.blinkStopper = false ;
    }
    
    ImageSelectionManager.prototype.highlight = function() {
        var i ;
        for(i=0;i<this.selections.length;i++)
            this.selections[i].highlight() ;
    }

    ImageSelectionManager.prototype.refreshSelections = function() {
        this.blinkStopper = false ;
        if(!this.editable)
            window.setTimeout(this.blink,500,this) ;
        else {
            this.highlight() ;
            if(this.blinkCounter)
                this.blinkStopper = true ;
        }
    }
    
    ImageSelectionManager.prototype.save = function(baseurl,sel) {
        var ajax = this.ajaxClient ;
        if(sel.modified) {
            var w = parseInt(this.image.width) ;
            var h = parseInt(this.image.height) ;            
            ajax.send(baseurl+
                    "&zid="+sel.id+
                    "&rid="+this.imgrid+
                    "&title="+sel.title+
                    "&x="+sel.getFloatPercent('left',w,-this.image.offsetLeft)+
                    "&y="+sel.getFloatPercent('top',h)+
                    "&w="+sel.getFloatPercent('width',w)+
                    "&h="+sel.getFloatPercent('height',h)
                , 
                function(req) {
                    if(req.getStatus()==200) {
                        var xml = req.getResponseXML() ;
                        var z = xml.getElementsByTagName("zone") ;
                        sel.id = parseInt(z.item(0).getAttribute("new-id")) ;
                        sel.modified = false ;
                    } else {
                        alert("Errore salvataggio zona: "+sel.title) ;
                    }
                }
            ) ;
        }
    }
    
    /** Handler AjaxRequest per il salvataggio asincrono ricorsivo */
    ImageSelectionManager.prototype.saveHandler = function(selnr, req, baseurl) {
        
        var ret = false ;
        var xml = req.getResponseXML() ;
        var retid = xml.getElementsByTagName("zone") ;
        
        if(selnr < this.selections.length) {
            
            //TODO: sostituzione id salvato (IMPORTANTE se non ci fosse il ricaricamento!)
            if(retid.length) {
                var retval = retid.item(0) ;
                var oldid = parseInt(retval.getAttribute("old-id")) ;
                //...
            }
            
            var sel = this.selections[selnr] ;
            if(sel.modified) {
                var w = parseInt(this.image.width) ;
                var h = parseInt(this.image.height) ;
                req.changeURL(baseurl+"&zid="+sel.id+
                    "&rid="+this.imgrid+
                    "&title="+sel.title+
                    "&x="+sel.getFloatPercent('left',w,-this.image.offsetLeft)+
                    "&y="+sel.getFloatPercent('top',h)+
                    "&w="+sel.getFloatPercent('width',w)+
                    "&h="+sel.getFloatPercent('height',h)
                ) ;
                ret = true ;
            }
        }
        
        return ret ;
    }
    
    ImageSelectionManager.prototype.erase = function(baseurl,ids) {
        var ajax = this.ajaxClient ;
        ajax.send(baseurl+"&ids="+ids, function(req) {
            if(req.getStatus()!=200) {
                alert("Errore cancellazione zone") ;
            }
        }) ;
    }
    
    /** Handler AjaxRequest per l'eliminazione asincrona delle zone cancellate */
    ImageSelectionManager.prototype.deleteHandler = function(req, baseurl) {
        var ret = false ;
        if(this.removedSelections.length) {
            var i ;
            var delids = "" ;
            for(i=0;i<this.removedSelections.length;i++) {
                var id = this.removedSelections[i].id ;
                if(id>0)
                    delids += id+"," ;
            }
            if(delids!="") {
                req.changeURL(baseurl+"&ids="+delids.substring(0,delids.length-1)) ;
                ret = true ;
            }
            this.removedSelections.splice(0) ;
        }
        return ret ;
    }
    
    ImageSelectionManager.prototype.addSelectionListener = function(listener) {
        this.listenerList.push(listener) ;
    }
     
    ImageSelectionManager.prototype.fireSelection = function(source,evtType,id) {
        var i ;
        for(i=0;i<this.listenerList.length;i++)
            this.listenerList[i](source,evtType,id) ;
    }
    
//
//------------------------------------------------------------------------------

