
// use with:
// $ ffplay -i <input> -ffglitch mv_set.js
// or
// $ ffedit -i <input> -s mv_set.js

let sdl;
let cur_off = [ 0, 0 ];
const step = 4;

function setup(args)
{
    args.features = [ "mv" ];
    args.output = "/tmp/output.avi";
    sdl = new SDL();
    if ( sdl )
    {
        // we are being called by ffplay
        const njoysticks = sdl.numJoysticks();
        console.log("number of joysticks: " + njoysticks);
        if ( njoysticks > 0 )
            sdl.joystickOpen(0);
    }
}

// NOTE: the following keys are already being used by ffplay:
//       ESC, space, '/', '*', '0', '9', 'a', 'c', 'f', 'm', 'p', 'q',
//       's', 't', 'v', 'w', down, left, right, up, pageup, pagedown.
function SDL_Event(event)
{
    // uncomment the following line to print the values from the events
    // console.log(JSON.stringify(event));

    // event.type
    // event.timestamp

    if ( event.type === SDL.SDL_KEYDOWN
      || event.type === SDL.SDL_KEYUP )
    {
        // event.state
        // event.repeat
        // event.keysym.scancode   https://wiki.libsdl.org/SDL_Scancode
        // event.keysym.sym        https://wiki.libsdl.org/SDLKeycodeLookup
        // event.keysym.mod
        if ( event.keysym.sym == SDL.SDLK_u )
            cur_off[0]++;
        else if ( event.keysym.sym == SDL.SDLK_i )
            cur_off[0]--;
    }
    else if ( event.type === SDL.SDL_JOYAXISMOTION )
    {
        // event.which
        // event.axis
        // event.value
        const axis = event.axis;
        const value = event.value;
        if ( axis === 0 )
        {
            // horizontal
            if ( value > 0 )
                cur_off[0] -= step;
            else if ( value < 0 )
                cur_off[0] += step;
        }
        else if ( axis === 1 )
        {
            // vertical
            if ( value > 0 )
                cur_off[1] -= step;
            else if ( value < 0 )
                cur_off[1] += step;
        }
    }
    else if ( event.type === SDL.SDL_JOYBALLMOTION )
    {
        // event.which
        // event.ball
        // event.xrel
        // event.yrel
    }
    else if ( event.type === SDL.SDL_JOYHATMOTION )
    {
        // event.which
        // event.hat
        // event.value
        const hat = event.hat;
        if ( hat === 0 )
        {
            const value = event.value;
            if ( (value & 0x01) !== 0 ) /* up */
                cur_off[1] += step;
            if ( (value & 0x02) !== 0 ) /* left */
                cur_off[0] -= step;
            if ( (value & 0x04) !== 0 ) /* down */
                cur_off[1] -= step;
            if ( (value & 0x08) !== 0 ) /* right */
                cur_off[0] += step;
        }
    }
    else if ( event.type === SDL.SDL_JOYBUTTONDOWN
           || event.type === SDL.SDL_JOYBUTTONUP )
    {
        // event.which
        // event.button
        // event.state
        const state = event.state;
        if ( state === 1 )
        {
            // button down
            const button = event.button;
            // A B X Y
            // 0 1 2 3
            if ( button === 0 )
                cur_off = [ 0, 0 ];
            else if ( button === 1 )
                cur_off = [ cur_off[1], cur_off[0] ];
            else if ( button === 2 )
                cur_off = [ -cur_off[0], -cur_off[1] ];
        }
    }
    else if ( event.type === SDL.SDL_CONTROLLERAXISMOTION )
    {
        // event.which
        // event.axis
        // event.value
    }
    else if ( event.type === SDL.SDL_CONTROLLERBUTTONDOWN
           || event.type === SDL.SDL_CONTROLLERBUTTONUP )
    {
        // event.which
        // event.button
        // event.state
    }
}

function glitch_frame(frame)
{
    let mvs = frame["mv"];
    // bail out if we have no forward motion vectors
    if ( !mvs || !mvs["forward"] )
        return;
    let fwd_mvs = mvs["forward"];

    mvs["overflow"] = "truncate";

    while ( sdl )
    {
        const event = sdl.getEvent();
        if ( !event )
            break;
        SDL_Event(event);
    }

    ffedit.mv_add_val(fwd_mvs, cur_off);
    // there are many other optimized functions in the 'ffedit' object:
    // ffedit.mv_copy(dst, src);           // copies the motion vectors from src to dst
    // ffedit.mv_add(dst, src);            // adds the motion vectors from src to dst
    // ffedit.mv_sub(dst, src);            // subtracts the motion vectors from src to dst
    // ffedit.mv_add_sub(dst, src1, src2); // adds src1 and subtracts src2 to dst
    // ffedit.mv_add_val(dst, [ x, y ] );  // adds the value [ x, y ] to all motion vectors in dst
    // ffedit.mv_div(dst, src, num);       // divides (and rounds) the motion vectors in src by num, and save it in dst
    // ffedit.mv_div_val(dst, num);        // divides (and rounds) the motion vectors in dst by num (in place)
}
