DatasetFibers::DatasetFibers( QString filename,
                                 QVector< QVector< float > > fibs,
                                 QVector< QVector< QVector< float > > >data,
                                 QVector<QString>dataNames,
                                 QVector< float > mins,
                                 QVector<float> maxes ) :
    Dataset( filename, Fn::DatasetType::FIBERS ),
    m_fibs( fibs ),
    m_data( data ),
    m_dataNames( dataNames ),
    m_dataMins( mins ),
    m_dataMaxes( maxes ),
    m_renderer( 0 ),
    m_tubeRenderer( 0 ),
    m_selector( 0 )
{
    int numPoints = 0;
    for ( int i = 0; i < fibs.size(); ++i )
    {
        numPoints += fibs[i].size() / 3;
    }

    m_properties.set( Fn::Property::NUM_POINTS, numPoints );
    m_properties.set( Fn::Property::NUM_LINES, fibs.size() );
    m_properties.set( Fn::Property::FIBER_RENDERMODE, {"lines", "tubes"}, 0, true );
    m_properties.set( Fn::Property::COLORMODE, { "global", "local", "user defined", "mri", "data" }, 0, true );
    m_properties.set( Fn::Property::DATAMODE, dataNames, 0, true );
    m_properties.set( Fn::Property::COLOR, QColor( 255, 0, 0 ), true );
    m_properties.set( Fn::Property::ALPHA, 1.f, 0.f, 1.f, true );
    m_properties.set( Fn::Property::FIBER_THICKNESS, 1.0f, 0.1f, 5.0f, true );
    m_properties.set( Fn::Property::COLORMAP, 1, true );
    m_properties.set( Fn::Property::MIN, 0.0f );
    m_properties.set( Fn::Property::MAX, 1.0f );
    m_properties.set( Fn::Property::SELECTED_MIN, 0.0f, 0.0f, 1.0f, true );
    m_properties.set( Fn::Property::SELECTED_MAX, 1.0f, 0.0f, 1.0f, true );
    m_properties.set( Fn::Property::LOWER_THRESHOLD, 0.0f, 0.0f, 1.0f );
    m_properties.set( Fn::Property::UPPER_THRESHOLD, 1.0f, 0.0f, 1.0f );
    m_properties.set( Fn::Property::DX, 100.0f, 0.0f, 100.0f, true );
    m_properties.set( Fn::Property::DY, 100.0f, 0.0f, 100.0f, true );
    m_properties.set( Fn::Property::DZ, 100.0f, 0.0f, 100.0f, true );
    m_properties.set( Fn::Property::NX, 800, 0, 1600, true );
    m_properties.set( Fn::Property::NY, 1000, 0, 2000, true );
    m_properties.set( Fn::Property::NZ, 800, 0, 1600, true );

    connect( m_properties.getProperty( Fn::Property::SELECTED_MIN ), SIGNAL( valueChanged( float ) ),
              m_properties.getProperty( Fn::Property::LOWER_THRESHOLD ), SLOT( setMax( float ) ) );
    connect( m_properties.getProperty( Fn::Property::SELECTED_MAX ), SIGNAL( valueChanged( float ) ),
              m_properties.getProperty( Fn::Property::UPPER_THRESHOLD ), SLOT( setMin( float ) ) );

    connect( m_properties.getProperty( Fn::Property::SELECTED_MIN ), SIGNAL( valueChanged( float ) ),
              m_properties.getProperty( Fn::Property::SELECTED_MAX ), SLOT( setMin( float ) ) );
    connect( m_properties.getProperty( Fn::Property::SELECTED_MAX ), SIGNAL( valueChanged( float ) ),
              m_properties.getProperty( Fn::Property::SELECTED_MIN ), SLOT( setMax( float ) ) );
    connect( m_properties.getProperty( Fn::Property::COLOR ), SIGNAL( colorChanged( QColor ) ), this, SLOT( colorChanged() ) );
    connect( m_properties.getProperty( Fn::Property::DATAMODE ), SIGNAL( valueChanged( int ) ), this, SLOT( dataModeChanged() ) );
}
void DatasetScalar::examineDataset()
{
    int nx = m_properties.get( Fn::Property::NX ).toInt();
    int ny = m_properties.get( Fn::Property::NY ).toInt();
    int nz = m_properties.get( Fn::Property::NZ ).toInt();

    float min = std::numeric_limits<float>::max();
    float max = 0;

    int size = nx * ny * nz;
    for ( int i = 0; i < size; ++i )
    {
        min = qMin( min, m_data[i] );
        max = qMax( max, m_data[i] );
    }

    m_properties.set( Fn::Property::SIZE, static_cast<int>( size * sizeof(float) ) );
    m_properties.set( Fn::Property::MIN, min );
    m_properties.set( Fn::Property::MAX, max );
    m_properties.set( Fn::Property::SELECTED_MIN, min, min, max, true );
    m_properties.set( Fn::Property::SELECTED_MAX, max, min, max, true );
    m_properties.set( Fn::Property::LOWER_THRESHOLD, min + (max-min)/1000., min, max, true );
    m_properties.set( Fn::Property::UPPER_THRESHOLD, max, min, max, true );

    connect( m_properties.getProperty( Fn::Property::SELECTED_MIN ), SIGNAL( valueChanged( float ) ),
              m_properties.getProperty( Fn::Property::LOWER_THRESHOLD ), SLOT( setMax( float ) ) );
    connect( m_properties.getProperty( Fn::Property::SELECTED_MAX ), SIGNAL( valueChanged( float ) ),
              m_properties.getProperty( Fn::Property::UPPER_THRESHOLD ), SLOT( setMin( float ) ) );

    connect( m_properties.getProperty( Fn::Property::SELECTED_MIN ), SIGNAL( valueChanged( float ) ),
              m_properties.getProperty( Fn::Property::SELECTED_MAX ), SLOT( setMin( float ) ) );
    connect( m_properties.getProperty( Fn::Property::SELECTED_MAX ), SIGNAL( valueChanged( float ) ),
              m_properties.getProperty( Fn::Property::SELECTED_MIN ), SLOT( setMax( float ) ) );

    if ( m_qform( 1, 1 ) < 0 || m_sform( 1, 1 ) < 0 )
    {
        qDebug() << m_properties.get( Fn::Property::NAME ).toString() << ": RADIOLOGICAL orientation detected. Flipping voxels on X-Axis";
        flipX();
    }
}