/* Copyright 1996 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#if 0
#define debugbut(k) dprintf k
#else
#define debugbut(k) /* Disabled */
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <time.h>

#include "os.h"
#include "wimp.h"
#include "wimpt.h"
#include "event.h"
#include "dbox.h"
#include "msgs.h"

#include "Options.h"
#include "malloc+.h"
#include "listfiles.h"
#include "memmanage.h"
#include "allerrs.h"
#include "actionwind.h"
#include "Buttons.h"
#include "debug.h"

#define No 0
#define Yes (!No)


static void null_activity( action_environment * );
static void pause_operation( action_environment * );
static void continue_operation( action_environment * );
#ifdef USE_FASTER_BUTTON
static void faster_operation( action_environment * );
#endif
static void skip_file( action_environment * );
static void operate_on_file( action_environment * );
static void to_end_of_list( action_environment * );
static void skip_operation( action_environment * );
static void retry_operation( action_environment * );
static void restart_operation( action_environment * );
static void run_object( action_environment * );
static void view_object( action_environment * );

const button_set abort_pause_buttons =
{
        {
                No,
                abort_operation,
                null_activity,
                null_activity,
                pause_operation,
#ifdef USE_FASTER_BUTTON
                faster_operation,
#else
                null_activity,
#endif
                {
                        "3",
                        "",
                        "",
                        "4",
#ifdef USE_FASTER_BUTTON
                        "FS"
#else
                        ""
#endif
                }
        },
        {
                "5",
                NULL,
                NULL,
                "6",
#ifdef USE_FASTER_BUTTON
                "F"
#else
                NULL
#endif
        }
};

const button_set confirm_buttons =
{
        {
                Yes,
                abort_operation,
                skip_file,
                operate_on_file,
                to_end_of_list,
                null_activity,
                {
                        "3",
                        "8",
                        "9",
                        "10",
                        ""
                }
        },
        {
                "5",
                "11",
                "12",
                "13",
                NULL
        }
};

const button_set ok_button =
{
        {
                Yes,
                null_activity,
                null_activity,
                null_activity,
                null_activity,
                abort_operation,
                {
                        "",
                        "",
                        "",
                        "",
                        "14"
                }
        },
        {
                NULL,
                NULL,
                NULL,
                NULL,
                "15"
        }
};

const button_set norestart_button =
{
        {
                Yes,
                abort_operation,
                null_activity,
                null_activity,
                retry_operation,
                skip_operation,
                {
                        "3",
                        "",
                        "",
                        "16",
                        "8"
                }
        },
        {
                "5",
                NULL,
                NULL,
                "17",
                "18"
        }
};

const button_set restart_button =
{
        {
                Yes,
                abort_operation,
                skip_operation,
                restart_operation,
                retry_operation,
                null_activity,
                {
                        "5",
                        "8",
                        "19",
                        "16",
                        ""
                }
        },
        {
                "5",
                "18",
                "20",
                "17",
                NULL
        }
};

const button_set abort_retry_buttons =
{
        {
                Yes,
                abort_operation,
                null_activity,
                null_activity,
                retry_operation,
                null_activity,
                {
                        "3",
                        "",
                        "",
                        "16",
                        ""
                }
        },
        {
                "5",
                NULL,
                NULL,
                "17",
                NULL
        }
};

const button_set run_view_buttons =
{
        {
                Yes,
                abort_operation,
                run_object,
                view_object,
                continue_operation,
                null_activity,
                {
                        "3",
                        "21",
                        "22",
                        "23",
                        ""
                }
        },
        {
                "5",
                "24",
                "25",
                "26",
                NULL
        }
};

const button_set open_buttons =
{
        {
                Yes,
                abort_operation,
                null_activity,
                null_activity,
                continue_operation,
                run_object,
                {
                        "3",
                        "",
                        "",
                        "23",
                        "27"
                }
        },
        {
                "5",
                NULL,
                NULL,
                "26",
                "28"
        }
};


static void set_button( action_environment *env, int button, const char *text )
{
    int dbox_handle = dbox_syshandle( env->status_box );


    if ( text != NULL )
    {
        /*
                Ensure button exists before setting field
        */
        wimp_iconflags flags = (wimp_iconflags) 0;
        wimp_iconflags mask = (wimp_iconflags) (wimp_IDELETED | wimp_IREDRAW);
        wimp_set_icon_state( dbox_handle, button, flags, mask );
        dbox_setfield( env->status_box, button, msgs_lookup((char *)text) );
    }
    else
    {
        wimp_redrawstr r;
        wimp_icon icondata;
        os_error *err;

        /*
             delete button
        */
        err = wimp_get_icon_info( dbox_handle, button, &icondata );

        if ( !err )
        {
            wimp_iconflags flags = (wimp_iconflags) (wimp_IDELETED | wimp_IREDRAW);
            wimp_iconflags mask = flags;
            wimp_set_icon_state( dbox_handle, button, flags, mask );

            r.w = dbox_handle;
            r.box = icondata.box;

            wimp_force_redraw( &r );
        }
    }
}

static void set_all_buttons( action_environment *env, const button_texts *texts )
{
    set_button( env, Abort_Button, texts->abort_text );
    set_button( env, No_Skip_Button, texts->no_skip_text );
    set_button( env, Yes_Retry_Button, texts->yes_retry_text );
    set_button( env, Misc_Button, texts->misc_text );
    set_button( env, Skip_Button, texts->skip_text );
}

void switch_buttons( action_environment *env, const button_set *new_buttons )
{
    env->button_actions = new_buttons->actions;
    set_all_buttons( env, &new_buttons->texts );

    if ( new_buttons->actions.requires_interaction )
    {
        /*
             Pop up the dialogue box and turn off NULL events
        */
        dbox_showstatic( env->status_box );

        show_faster_stuff( env );

        wimp_emask mask = (wimp_emask) (wimp_EMNULL | wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG);

        event_setmask( mask );
    }
    else
    {
        if ( !env->verbose )
        {
                switch_dbox_on_off( env, -1, Remove_Delay );
        }

        /*
                Things might have changed, so update ourselves
        */
        read_next_node_parameters( env->test_search );

        wimp_emask mask = (wimp_emask) (wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG);

        event_setmask( mask );
    }

    #ifdef USE_FASTER_BUTTON
    /* Ensure we get the buttons we really need */
    if ( new_buttons == &abort_pause_buttons )
    {
        set_faster_state( env );
    }
    #endif
}

void abort_operation( action_environment *env )
{
    dispose_search_context( env->test_search );

    exit( 0 );
}

static void pause_operation( action_environment *env )
{
    set_button( env, Misc_Button, "26" );

    env->button_actions.button_helps[ Misc_Button - Abort_Button ] = "79";

    env->button_actions.misc_action = continue_operation;

    set_top_info_field_with_current_info(env, "80a", "80");

    dbox_showstatic( env->status_box );

    wimp_emask mask = (wimp_emask) (wimp_EMNULL | wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG );

    event_setmask( mask );
}

#ifdef USE_FASTER_BUTTON
/* JRF: Calls the same thing as the menu option */
static void faster_operation( action_environment *env )
{
    toggle_faster( env );
}

void set_faster_state( action_environment *env )
{
    if ( !env->button_actions.requires_interaction )
    {
        if ( env->faster )
            set_button( env, Skip_Button, "S" );
        else
            set_button( env, Skip_Button, "F" );
    }
}
#endif

static void continue_operation( action_environment *env )
{
    switch_buttons( env, &abort_pause_buttons );
}

static void null_activity( action_environment *env )
{
    IGNORE(env);
}

/*
     confirm Yes button
*/
static void operate_on_file( action_environment *env )
{
    switch_buttons( env, &abort_pause_buttons );
}

/*
     confirm Quiet button
*/
static void to_end_of_list( action_environment *env )
{
    switch_buttons( env, &abort_pause_buttons );

    env->confirm = No;
}

/*
     confirm Skip button
*/
static void skip_file( action_environment *env )
{
    env->action = Next_File;

    skip_list_file( env->test_search );

    switch_buttons( env, &abort_pause_buttons );
}

/*
     error Skip button
*/
static void skip_operation( action_environment *env )
{
    if ( env->action == Next_File )
    {
        skip_failed_selection( env->test_search );
    }
    else
    {
        switch ( env->operation )
        {
        case Action_Copying:
        case Action_CopyMoving:
        case Action_CopyLocal:
            if ( env->action == Check_Full_Reading )
            {
                    skip_file_read();
                    switch_to_reading( env );
            }
            else if ( env->action == Check_Empty_Writing )
            {
                    skip_file_write();
                    switch_to_writing( env );
            }
            else
            {
                    env->action = Next_File;
            }
            break;

        case Action_Moving:
        case Action_Deleting:
        case Action_Setting_Access:
        case Action_Setting_Type:
        case Action_Counting:
        case Action_Stamping:
        case Action_Finding:
            env->action = Next_File;
            break;
        }
    }

    switch_buttons( env, &abort_pause_buttons );
}

static void run_object( action_environment *env )
{
    char *filename;
    char *command;
    os_error *err;

    err = next_nodename( env->test_search, &filename );

    if ( err )
    {
        wimpt_complain( err );
        return;
    }

    command = overflowing_malloc( strlen( "Filer_Run " ) + strlen( filename ) + 1 );

    if ( !command )
    {
        wimpt_complain( error( mb_malloc_failed ) );
        return;
    }

    sprintf( command, "Filer_Run %s", filename );

    overflowing_free( filename );

    wimpt_complain( os_cli( command ));

    overflowing_free( command );
}

static void view_object( action_environment *env )
{
    wimp_msgstr m;
    char *filename;
    os_error *err;

    err = next_nodename( env->test_search, &filename );

    if ( err )
    {
        wimpt_complain( err );
        return;
    }

    /*
        strrchr is guaranteed to work correctly due to the nature of the
        filename.
    */
    *strrchr( filename, '.' ) = '\0';

    m.hdr.size = 256;
    m.hdr.your_ref = 0;
    m.hdr.action = wimp_FilerOpenDir;
    m.data.words[ 0 ] = 0;
    m.data.words[ 1 ] = 0;
    strcpy( (char *)&m.data.words[2], filename );

    overflowing_free( filename );

    wimpt_complain( wimp_sendmessage( wimp_ESEND, &m, 0 ));
}

/*
     error Restart button
*/
static void restart_operation( action_environment *env )
{
    debugbut(( "restart_operation: env=&%8X\n", (int)env ));
    if ( env->action == Check_Full_Reading )
        restart_file_read();

    if ( env->action == Check_Empty_Writing )
        restart_file_write();

    switch_buttons( env, &abort_pause_buttons );
}

/*
     error Retry button
*/
static void retry_operation( action_environment *env )
{
    switch_buttons( env, &abort_pause_buttons );
}

/*
     This intercepts and handles the button events
*/
void button_event_handler( dbox db, void *handle )
{
    action_environment *env = handle;

    IGNORE(db);

    switch( dbox_get( env->status_box ))
    {
    case Abort_Button:
        env->button_actions.abort_action( env );
        break;

    case No_Skip_Button:
        env->button_actions.no_skip_action( env );
        break;

    case Yes_Retry_Button:
        env->button_actions.yes_retry_action( env );
        break;

    case Misc_Button:
        env->button_actions.misc_action( env );
        break;

    case Skip_Button:
        env->button_actions.skip_action( env );
        break;

    default:
        /* do nothing on other fields */
        break;
    }
}