//   digitize() - digitize points from a 2D plot image.
//
//   Pre-requisites: Scilab Computer Vision Toolbox (scicv).
//
//   With no input argument, digitize() first prompts the user to
//   select an image file to display, otherwise the given image is displayed.
//
//   The user is then asked to graphically identify the location of
//   the origin, the X and Y axes of the plot.
//
//   The user is asked if rotation must be taken
//   in account in the processing.
//   If there is a rotation, the axes must cross the origin,
//   otherwise the output data will be wrong.
//
//   The user then graphically selects an arbitrary number of data points
//   from anywhere on the image using the right mouse button.
//   Data acquisition is terminated by clicking the left mouse button.
//
//   The function returns in the first argument the data as a matrix
//   (each row contains the coordinates of a point).
//
//   Optionally (if the user has specified a second output argument)
//   the user is prompted to select a file, to save the data in that file as text,
//   and the path to this file is returned in the second output argument.
//
//   Ported by Scilab Enterprises from original digitize2 function (author: A. Prasad):
//   https://fr.mathworks.com/matlabcentral/fileexchange/928-digitize2-m

function [data, dataFileName] = digitize(varargin)
    data = [];
    dataFileName = [];

    // Check for proper number of input arguments
    // Get image fileName
    if size(varargin) == 0 then
        fileName = uigetfile( ..
           ["*.jpg;*.tif;*.gif;*.png;*.bmp", ..
            "Image files (*.jpg,*.tif,*.gif,*.png,*.bmp)"; ..
            "*.jpg;*.jpeg", ..
            "JPEG files (*.jpg,*.jpeg)"; ..
            "*.tif;*.tiff", ..
            "TIFF files (*.tif,*.tiff)"; ..
            "*.gif", ..
            "GIF files (*.gif)"; ..
            "*.png", ..
            "PNG files (*.png)"; ..
            "*.bmp", ..
            "Bitmap files (*.bmp)"; ..
            "*.*", ..
            "All files (*.*)"], ..
           "Select image file");
        if isempty(fileName) then
            return
        end
    else
        fileName = varargin(1);
    end

    // Read image from target fileName
    scicv_Init();
    img = imread(fileName);
    matplot(img);
    show_window();

    fig_handle = gcf();
    fig_handle.figure_name = "Image: " + fileName;
    fig_handle.menubar_visible = "off";
    fig_handle.toolbar_visible = "off";

    // Determine location of origin with mouse click
    button = messagebox(..
        "Click on the origin point with the left mouse button.", ..
        "digitize", "question", ["OK", _(_("Cancel"))], "modal");
    if button == 2 then
        close(fig_handle);
        return
    end

    show_window();
    coords = locate(1);
    Xopixels = coords(1);
    Yopixels = coords(2);
    xpoly(Xopixels, Yopixels, "marks", 0);

    // Prompt user for X- & Y- values at origin
    boxMsg = ["X value of the origin: ", ..
            "Y value of the origin: "];
    def = ["0", "0"];
    answer = x_mdialog("", boxMsg, def);
    if ~isempty(answer) then
        originXYdata = evstr(answer);
    else
        close(fig_handle);
        return
    end

    // Define X-axis
    button = messagebox(..
          "Click on a point on the X axis with the left mouse button.", ..
          "digitize", "question", [_("OK"), _("Cancel")], "modal");
    if button == 2 then
        close(fig_handle);
        return
    end

    show_window();
    coords = locate(1);
    XAxisXpixels = coords(1);
    XAxisYpixels = coords(2);
    xpoly(XAxisXpixels, XAxisYpixels, "marks", 0);

    // Prompt user for XLim value
    boxMsg = "X value of the clicked point:";
    def = "1";
    answer = x_mdialog("", boxMsg, def);
    if ~isempty(answer) then
        XAxisXdata = evstr(answer);
    else
        close(fig_handle);
        return
    end

    // Determine X-axis scaling
    choice = x_choose(..
        ["Linear", "Logarithmic"], ..
        "Select the type of the X axis:");
    select choice
        case 1
            logx = %f;
            scaleFactorXdata = XAxisXdata - originXYdata(1);
        case 2
            logx = %t;
            scaleFactorXdata = log10(XAxisXdata/originXYdata(1));
        case 0
            close(fig_handle);
            return
    end

    // Define Y-axis
    button = messagebox(..
        "Click on a point on the Y axis with the left mouse button.", ..
        "digitize", "question", [_("OK"), _("Cancel")], "modal");
    if button == 2 then
        close(fig_handle);
        return
    end

    show_window();
    coords = locate(1);
    YAxisXpixels = coords(1);
    YAxisYpixels = coords(2);
    xpoly(YAxisXpixels, YAxisYpixels, "marks", 0);

    // Prompt user for YLim value
    boxMsg = "Y value of the clicked point:";
    def = "1";
    answer = x_mdialog("", boxMsg, def);
    if ~isempty(answer) then
        YAxisYdata = evstr(answer);
    else
        close(fig_handle);
        return
    end

    // Determine Y-axis scaling
    choice = x_choose(..
        ["Linear", "Logarithmic"], ..
        "Select the type of the Y axis:");
    select choice
        case 1
            logy = %f;
            scaleFactorYdata = YAxisYdata - originXYdata(2);
        case 2
            logy = %t;
            scaleFactorYdata = log10(YAxisYdata/originXYdata(2));
        case 0
            close(fig_handle);
            return
    end

    button = messagebox(..
        ["Take in account rotation ?"; ..
        "Note: the X-axis you have clicked on must cross the origin, otherwise all data will be wrong."], ..
        "digitize", "question", [_("No"), _("Yes"), _("Cancel")], "modal");
    if button == 1 then
        rotmat = eye(2, 2);
    elseif button == 2 then
        // axis rotation angle
        th = atan((XAxisYpixels-Yopixels)/(XAxisXpixels-Xopixels));
        // axis rotation matrix
        rotmat = [cos(th) sin(th); -sin(th) cos(th)];
    else
        close(fig_handle);
        return
    end

    // Complete rotation matrix definition as necessary
    delxyx = rotmat*[XAxisXpixels-Xopixels; XAxisYpixels-Yopixels];
    delxyy = rotmat*[YAxisXpixels-Xopixels; YAxisYpixels-Yopixels];
    delXcal = delxyx(1);
    delYcal = delxyy(2);

    // Start data acquisition from image
    messagebox(..
        ["Click on the right mouse button to acquire a new point, left mouse button to quit."], ..
        "digitize", "info", _("OK"), "modal");

    show_window();
    coords = locate(-1, 1);
    n = size(coords, "c");

    if n > 0 then
        printf("Index\tX\tY\n");
        for i=1:n
            x = coords(1,i);
            y = coords(2,i);
            xy = rotmat*[x-Xopixels;y-Yopixels];

            if logx then
                xpt(i) = originXYdata(1)*10^(xy(1)/delXcal*scaleFactorXdata);
            else
                xpt(i) = originXYdata(1) + xy(1)/delXcal*scaleFactorXdata;
            end
            if logy then
                ypt(i) = originXYdata(2)*10^(xy(2)/delYcal*scaleFactorYdata);
            else
                ypt(i) = originXYdata(2) + xy(2)/delYcal*scaleFactorYdata;
            end

            printf("%4d\t%3.2f\t%3.2f\n", i, xpt(i), ypt(i));
        end

        data = [xpt ypt];

        if argn(1) >= 2 then
            // Save data to file
            dataFileName = uiputfile("*.dat", "Save data as");
            if ~isempty(dataFileName) then
                [path, name, ext] = fileparts(dataFileName);
                if ext == "" then
                    dataFileName = dataFileName + ".dat";
                end
                fprintfMat(dataFileName, data, "%3.2f");
            end
        end
    end
    close(fig_handle);
endfunction








