#include "balanceknob.h"

#include <tqpainter.h>
#include <tqpixmap.h>
#include <tqimage.h>
#include <tqevent.h>
#include <math.h>

static const double DEG2RAD  = M_PI / 180.0;
static const double TRAVEL   = 135.0;   // degrees each side from centre

BalanceKnob::BalanceKnob( int minVal, int maxVal, int val, TQWidget *parent )
    : TQWidget(parent),
      m_min(minVal), m_max(maxVal), m_value(val),
      m_dragY(0), m_dragValue(0), m_dragging(false)
{
    setFixedSize( 30, 30 );
    setBackgroundMode( TQt::NoBackground );
}

void BalanceKnob::setValue( int v )
{
    v = v < m_min ? m_min : v > m_max ? m_max : v;
    if ( v == m_value ) return;
    m_value = v;
    update();
    emit valueChanged( v );
}

void BalanceKnob::paintEvent( TQPaintEvent * )
{
    // 2× supersampling for smooth edges (TQt3 has no native AA)
    const int S = 2;
    int W = width() * S, H = height() * S;
    int cx = W / 2, cy = H / 2;
    int r  = ( W < H ? W : H ) / 2 - S;

    TQPixmap pm( W, H );
    pm.fill( paletteBackgroundColor() );
    TQPainter p( &pm );

    double mid  = ( m_min + m_max ) / 2.0;
    double half = ( m_max - m_min ) / 2.0;

    // ---- range track arc (270° from 7:30 clockwise to 4:30) -----------------
    p.setPen( TQPen( TQColor(90, 90, 90), S * 2 ) );
    p.setBrush( TQt::NoBrush );
    p.drawArc( cx - r, cy - r, 2*r, 2*r, 225*16, -270*16 );

    // ---- value arc (from 12-o'clock to current position) --------------------
    double current_qt = 90.0 - ( (m_value - mid) / half ) * TRAVEL;
    int spanAngle = (int)( (current_qt - 90.0) * 16.0 );
    if ( spanAngle != 0 ) {
        p.setPen( TQPen( TQColor(90, 140, 220), S * 2 ) );
        p.drawArc( cx - r, cy - r, 2*r, 2*r, 90*16, spanAngle );
    }

    // ---- knob body -----------------------------------------------------------
    int kr = r - S * 3;
    p.setPen( TQt::NoPen );

    p.setBrush( TQColor(38, 38, 42) );
    p.drawEllipse( cx - kr, cy - kr, 2*kr, 2*kr );

    p.setBrush( TQColor(68, 68, 74) );
    p.drawEllipse( cx - kr + S, cy - kr + S, 2*kr - S*3, 2*kr - S*3 );

    // ---- centre rest dot ----------------------------------------------------
    p.setPen( TQt::NoPen );
    p.setBrush( TQColor(100, 100, 110) );
    p.drawEllipse( cx - S, cy - kr + S*2, S*2, S*2 );

    // ---- indicator line -----------------------------------------------------
    double angle_rad = ( (m_value - mid) / half ) * TRAVEL * DEG2RAD;
    int ix = cx + (int)( (kr - S*3) * sin( angle_rad ) );
    int iy = cy - (int)( (kr - S*3) * cos( angle_rad ) );

    p.setPen( TQPen( TQt::white, S * 2 ) );
    p.drawLine( cx, cy, ix, iy );

    p.end();

    // Scale back down and blit
    TQImage scaled = pm.convertToImage().smoothScale( width(), height() );
    TQPainter out( this );
    out.drawImage( 0, 0, scaled );
}

void BalanceKnob::mousePressEvent( TQMouseEvent *e )
{
    if ( e->button() == TQt::LeftButton ) {
        m_dragY     = e->globalPos().y();
        m_dragValue = m_value;
        m_dragging  = true;
        grabMouse();
    }
}

void BalanceKnob::mouseMoveEvent( TQMouseEvent *e )
{
    if ( !m_dragging ) return;
    int delta = m_dragY - e->globalPos().y();   // drag up = increase
    setValue( m_dragValue + delta );
}

void BalanceKnob::mouseReleaseEvent( TQMouseEvent * )
{
    if ( m_dragging ) {
        m_dragging = false;
        releaseMouse();
    }
}

void BalanceKnob::mouseDoubleClickEvent( TQMouseEvent * )
{
    setValue( (int)( (m_min + m_max) / 2.0 ) );
}

void BalanceKnob::wheelEvent( TQWheelEvent *e )
{
    setValue( m_value + ( e->delta() > 0 ? 5 : -5 ) );
}

#include "balanceknob.moc"
