/*
 * PiAnoS (Picture Annotation System), A fingerprint examiner training tool
 * Copyright (C) 2011-2012 University of Lausanne, Switzerland
 * https://ips-labs.unil.ch/pianos
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */

/**
 * @constructor
 */
function Pianos4ToolTPS( params )
{
    // ------------------------------
    // Constructor
    // ------------------------------
    
    params = params || {};
    if( typeof ( params.v3 ) == 'undefined' )
        params.v3 = false;
    
    // ------------------------------
    // Public methods
    // ------------------------------
    
    this.getName = function()
    {
        return 'TPS';
    }
    
    this.getLabel = function()
    {
        return 'TPS';
    }
    
    this.getIcon = function()
    {
        return 'icons/TPS.png';
    }
    
    this.bind = function( aView )
    {
        assert( !view );
        view = aView;
    }
    
    this.unbind = function()
    {
        assert( view );
        view = null;
    }
    
    this.activate = function()
    {
        views = pianos.getViewsdict();
        
        bindTo( 'mark' );
        bindTo( 'print' );
        
        update_TPS_parameters();
        
        log( 'TPS tool activate' );
    }
    
    this.deactivate = function()
    {
        views.mark.remove_Ghost_Cursor_live();
        views.print.remove_Ghost_Cursor_live();
        
        unbindFrom( 'mark' );
        unbindFrom( 'print' );
        
        log( 'TPS tool de-activate' );
    }

    this.onMouseDown = function( pos, target, event )
    {
    }

    this.onMouseUp = function( pos, target, event )
    {
        if( typeof( TPS_g.mark.be ) === "undefined" )
            update_TPS_parameters();
        
        var viewtype = view.getType();
        var clickedView = views[ viewtype ];
        
        var p = TPS_project( TPS_g[ viewtype ], pos );
        
        clickedAnchor = new Pianos4TPSAnchore( viewtype, "user", pos );
        
        action = new Pianos4Action_CreateAnnotation( clickedView, 'GC', clickedAnchor );
        pianos.exec( action );
        
        updateAllViews();
        
        // Force toggle the GC layer
        pianos.toggleLayer( 'GC', true );
        
        return true;
    }

    this.onMouseMove = function( pos, target, event )
    {
    }

    this.getOptionsPanel = function()
    {
        if( !options )
        {
            var panel = $( '<div class="pianos4_TPS_options" />' );
            
            var generate = $( '<a />' )
                .text( 'Generate' )
                .attr( 'href', '#generate' )
                .bind( 'click', update_TPS_parameters );
            
            var update = $( '<a />' )
                .text( 'Update' )
                .attr( 'href', '#update' )
                .bind( 'click', updateAllViews );
            
            panel.append( generate );
            panel.append( $( '<br />' ) );
            panel.append( update );
            
            options = panel;
        }
        
        return options;
    }

    this.getHelp = function()
    {
        return Pianos4Help.compile();
    }

    // ------------------------------
    // Private variables
    // ------------------------------
    
    var self = this;
    var view = null;
    var views = null;
    var popup = null;
    var options = null;
    var drawTimestamp = Date.now();
    var TPS_g = {};
    
    // ------------------------------
    // Private functions
    // ------------------------------
    
    var bindTo = function( to )
    {
        var d3svg = d3.select('#pianos .pianos4_' + to + ' .pianos4_view_canvas');
        d3svg.on('mousemove', function()
        {
            onMouseMoveLive( d3.event, views[ to ], to );
        });
    }
    
    var unbindFrom = function( from )
    {
        d3.select( '#pianos .pianos4_' + from + ' .pianos4_view_canvas' )
            .on( 'mousemove', null ); 
    }
    
    var onMouseMoveLive = function( event, view, viewtype )
    {
        if( typeof( TPS_g.mark.be ) !== "undefined" && Date.now() - drawTimestamp > 1000 / 60 )
        {
            var pos = view.getCanvasPos( [ event.clientX, event.clientY ] );
            
            // var viewtype = view.getType();
            var otherview = viewtype == "print" ? "mark" : "print";
            var p = TPS_project( TPS_g[ viewtype ], pos );
            
            views[ otherview ].update_Ghost_Cursor_live( p );
            views[ viewtype ].remove_Ghost_Cursor_live();
            
            drawTimestamp = Date.now();
        }
    }
    
    var getAllPairedMinutiae = function()
    {
        var mark = pianos.getView( 'mark' );
        var ref = pianos.getView( "print" );
        var mannotations = mark.getAnnotationsDict();
        
        var markpos = Array();
        var refpos = Array();
        
        for( var i in mannotations.minutiae )
        {
            var m = mannotations.minutiae[ i ];
            if( 'pairing' in m )
            {
                markpos.push( m.pos );
                refpos.push( ref.getPairedMinutia( m.pairing ).pos );
            }
        }
        
        return {
            mark: markpos,
            ref: refpos
        };
    }
    var update_TPS_parameters = function()
    {

        var pair = getAllPairedMinutiae();
        TPS_g.mark  = TPS_generate( pair.mark, pair.ref );
        TPS_g.print = TPS_generate( pair.ref, pair.mark );
    }
    
    var updateView = function( from, to, fg )
    {
        to.clear_Ghost_Cursor_Projected();
        
        var anno = from.getData().GC;
        
        for( var key in anno )
        {
            var pos = TPS_project( fg, anno[ key ].pos );
            var projectedAnchor = new Pianos4TPSAnchore( to, "projected", pos );
            to.draw_Ghost_Cursor_Projected( projectedAnchor );
        }
    }
    
    var updateAllViews = function()
    {
        update_TPS_parameters();
        updateView( views.mark, views.print, TPS_g.mark  );
        updateView( views.print, views.mark, TPS_g.print );
    }
}
