/* 
 *
 *   File: properties.c
 *
 *   Copyright (C) 2009-2013 Darran Kartaschew
 *
 *   This file is part of the gMTP package.
 *
 *   gMTP is free software; you can redistribute it and/or modify
 *   it under the terms of the BSD License as included within the
 *   file 'COPYING' located in the root directory
 *
 */

#include "properties.h"

#include "main.h"
#include "interface.h"
#include "mtp.h"

GtkWidget *windowPropDialog;

/**
 * Add a row of information to the table
 * @param table The table to add to
 * @param row The row ID
 * @param title The title for column 1
 * @param field The label widget for column 2
 */
void addRow(GtkWidget* table, gint row, char* title, GtkWidget** field);

// ************************************************************************************************

GtkWidget* create_windowProperties() {
    GtkWidget *windowDialog;
    GtkWidget *windowNotebook;
    GtkWidget *windowBox;

    GtkWidget *tableDeviceInformation;
    GtkWidget *labelTableDeviceInformation;

    GtkWidget *tableRawInformation;
    GtkWidget *labelTableRawInformation;

    GtkWidget *labelName;
    GtkWidget *labelModel;
    GtkWidget *labelSerial;
    GtkWidget *labelBattery;
    GtkWidget *labelManufacturer;
    GtkWidget *labelDeviceVer;
    GtkWidget *labelStorage;
    GtkWidget *labelSupportedFormat;
    
    GtkWidget *labelDeviceVendor;
    GtkWidget *labelDeviceProduct;
    GtkWidget *labelVenID;
    GtkWidget *labelProdID;
    GtkWidget *labelBusLoc;
    GtkWidget *labelDevNum;

    GtkWidget *closeButtonBox;
    GtkWidget *buttonClose;

    GString *tmp_string2;
    gchar *tmp_string = NULL;

    windowDialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gchar * winTitle;
    winTitle = g_strconcat(DeviceMgr.devicename->str, _(" Properties"), NULL);
    gtk_window_set_title(GTK_WINDOW(windowDialog), winTitle);
    gtk_window_set_modal(GTK_WINDOW(windowDialog), TRUE);
    gtk_window_set_transient_for(GTK_WINDOW(windowDialog), GTK_WINDOW(windowMain));
    gtk_window_set_position(GTK_WINDOW(windowDialog), GTK_WIN_POS_CENTER_ON_PARENT);
    gtk_window_set_resizable(GTK_WINDOW(windowDialog), FALSE);
    gtk_window_set_type_hint(GTK_WINDOW(windowDialog), GDK_WINDOW_TYPE_HINT_DIALOG);
    gtk_container_set_border_width(GTK_CONTAINER(windowDialog), 5);
    g_free(winTitle);

    // Main Window
#if HAVE_GTK3 == 0
    windowBox = gtk_vbox_new(FALSE, 5);
#else
    windowBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
#endif
    gtk_container_set_border_width(GTK_CONTAINER(windowBox), 5);
    gtk_widget_show(windowBox);
    gtk_container_add(GTK_CONTAINER(windowDialog), windowBox);

    // Device Properties Pane
    labelTableDeviceInformation = gtk_label_new("");
    gtk_label_set_markup(GTK_LABEL(labelTableDeviceInformation), _("<b>MTP Device Properties</b>"));
    gtk_widget_show(labelTableDeviceInformation);

    // Raw Device Information Pane
    labelTableRawInformation = gtk_label_new("");
    gtk_label_set_markup(GTK_LABEL(labelTableRawInformation), _("<b>Raw Device Information</b>"));
    gtk_widget_show(labelTableRawInformation);

    // Start the Device Properties Pane.
#if HAVE_GTK3 == 0
    tableDeviceInformation = gtk_table_new(10, 2, FALSE);
    gtk_widget_show(tableDeviceInformation);
    gtk_container_set_border_width(GTK_CONTAINER(tableDeviceInformation), 5);
    gtk_table_set_row_spacings(GTK_TABLE(tableDeviceInformation), 5);
    gtk_table_set_col_spacings(GTK_TABLE(tableDeviceInformation), 5);
#else
    tableDeviceInformation = gtk_grid_new();
    gtk_widget_show(tableDeviceInformation);
    gtk_container_set_border_width(GTK_CONTAINER(tableDeviceInformation), 5);
    gtk_grid_set_row_spacing(GTK_GRID(tableDeviceInformation), 5);
    gtk_grid_set_column_spacing(GTK_GRID(tableDeviceInformation), 5);
#endif

    // Start the Raw Device Pane.
#if HAVE_GTK3 == 0
    tableRawInformation = gtk_table_new(6, 2, FALSE);
    gtk_widget_show(tableRawInformation);
    gtk_container_set_border_width(GTK_CONTAINER(tableRawInformation), 5);
    gtk_table_set_row_spacings(GTK_TABLE(tableRawInformation), 5);
    gtk_table_set_col_spacings(GTK_TABLE(tableRawInformation), 5);
#else
    tableRawInformation = gtk_grid_new();
    gtk_widget_show(tableRawInformation);
    gtk_container_set_border_width(GTK_CONTAINER(tableRawInformation), 5);
    gtk_grid_set_row_spacing(GTK_GRID(tableRawInformation), 5);
    gtk_grid_set_column_spacing(GTK_GRID(tableRawInformation), 5);
#endif    

    // Build the Notebook.
    windowNotebook = gtk_notebook_new();
    gtk_widget_show(windowNotebook);
    gtk_notebook_append_page(GTK_NOTEBOOK(windowNotebook), tableDeviceInformation, labelTableDeviceInformation);
    gtk_notebook_append_page(GTK_NOTEBOOK(windowNotebook), tableRawInformation, labelTableRawInformation);
    gtk_container_add(GTK_CONTAINER(windowBox), windowNotebook);

    // Start the content    

    addRow(tableDeviceInformation, 0, _("<b>Name:</b>"), &labelName);
    addRow(tableDeviceInformation, 1, _("<b>Model Number:</b>"), &labelModel);
    addRow(tableDeviceInformation, 2, _("<b>Serial Number:</b>"), &labelSerial);
    addRow(tableDeviceInformation, 3, _("<b>Device Version:</b>"), &labelDeviceVer);
    addRow(tableDeviceInformation, 4, _("<b>Manufacturer:</b>"), &labelManufacturer);
    addRow(tableDeviceInformation, 5, _("<b>Battery Level:</b>"), &labelBattery);
    addRow(tableDeviceInformation, 6, _("<b>Storage:</b>"), &labelStorage);
    addRow(tableDeviceInformation, 7, _("<b>Supported Formats:</b>"), &labelSupportedFormat);

    addRow(tableRawInformation, 0, _("<b>Vendor:</b>"), &labelDeviceVendor);
    addRow(tableRawInformation, 1, _("<b>Product:</b>"), &labelDeviceProduct);
    addRow(tableRawInformation, 2, _("<b>Vendor ID:</b>"), &labelVenID);
    addRow(tableRawInformation, 3, _("<b>Product ID:</b>"), &labelProdID);
    addRow(tableRawInformation, 4, _("<b>Device Number:</b>"), &labelDevNum);
    addRow(tableRawInformation, 5, _("<b>Bus Location:</b>"), &labelBusLoc);

#if HAVE_GTK3 == 0
    closeButtonBox = gtk_hbox_new(FALSE, 0);
    buttonClose = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
#else
    closeButtonBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    buttonClose = gtk_button_new_with_mnemonic(_("_Close"));
#endif
    gtk_widget_show(closeButtonBox);
    gtk_box_pack_start(GTK_BOX(windowBox), closeButtonBox, TRUE, TRUE, 0);
    gtk_widget_show(buttonClose);
    gtk_box_pack_end(GTK_BOX(closeButtonBox), buttonClose, FALSE, FALSE, 0);

    g_signal_connect((gpointer) windowDialog, "destroy",
            G_CALLBACK(on_quitProp_activate),
            NULL);

    g_signal_connect((gpointer) buttonClose, "clicked",
            G_CALLBACK(on_quitProp_activate),
            NULL);

    // Now we need to update our strings for the information on the unit.
    gtk_label_set_text(GTK_LABEL(labelName), DeviceMgr.devicename->str);
    gtk_label_set_text(GTK_LABEL(labelModel), DeviceMgr.modelname->str);
    gtk_label_set_text(GTK_LABEL(labelSerial), DeviceMgr.serialnumber->str);
    if (DeviceMgr.maxbattlevel != 0) {
        tmp_string = g_strdup_printf("%d / %d (%d%%)", DeviceMgr.currbattlevel, DeviceMgr.maxbattlevel,
                (int) (((float) DeviceMgr.currbattlevel / (float) DeviceMgr.maxbattlevel) * 100.0));
    } else {
        tmp_string = g_strdup_printf("%d / %d", DeviceMgr.currbattlevel, DeviceMgr.maxbattlevel);
    }
    gtk_label_set_text(GTK_LABEL(labelBattery), tmp_string);
    g_free(tmp_string);
    gtk_label_set_text(GTK_LABEL(labelManufacturer), DeviceMgr.manufacturername->str);
    gtk_label_set_text(GTK_LABEL(labelDeviceVer), DeviceMgr.deviceversion->str);


    if (DeviceMgr.storagedeviceID == MTP_DEVICE_SINGLE_STORAGE) {
        tmp_string = g_strdup_printf(_("%d MB (free) / %d MB (total)"),
                (int) (DeviceMgr.devicestorage->FreeSpaceInBytes / MEGABYTE),
                (int) (DeviceMgr.devicestorage->MaxCapacity / MEGABYTE));
        gtk_label_set_text(GTK_LABEL(labelStorage), tmp_string);
         g_free(tmp_string);
    } else {
        tmp_string2 = g_string_new("");
        // Cycle through each storage device and list the name and capacity.
        LIBMTP_devicestorage_t* deviceStorage = DeviceMgr.device->storage;
        while (deviceStorage != NULL) {
            if (tmp_string2->len > 0)
                tmp_string2 = g_string_append(tmp_string2, "\n");
            if (deviceStorage->StorageDescription != NULL) {
                tmp_string2 = g_string_append(tmp_string2, deviceStorage->StorageDescription);
            } else {
                tmp_string2 = g_string_append(tmp_string2, deviceStorage->VolumeIdentifier);
            }
            tmp_string = g_strdup_printf(" : %d MB (free) / %d MB (total)",
                    (int) (deviceStorage->FreeSpaceInBytes / MEGABYTE),
                    (int) (deviceStorage->MaxCapacity / MEGABYTE));
            tmp_string2 = g_string_append(tmp_string2, tmp_string);
            g_free(tmp_string);
            deviceStorage = deviceStorage->next;
        }
        gtk_label_set_text(GTK_LABEL(labelStorage), tmp_string2->str);
        g_string_free(tmp_string2, TRUE);
    }

    tmp_string2 = g_string_new("");
    // Build a string for us to use.
    gint i = 0;
    for (i = 0; i < DeviceMgr.filetypes_len; i++) {
        if (tmp_string2->len > 0)
            tmp_string2 = g_string_append(tmp_string2, "\n");
        tmp_string2 = g_string_append(tmp_string2, LIBMTP_Get_Filetype_Description(DeviceMgr.filetypes[i]));
    }

    gtk_label_set_text(GTK_LABEL(labelSupportedFormat), tmp_string2->str);
    g_string_free(tmp_string2, TRUE);

    // This is our raw information.
    gtk_label_set_text(GTK_LABEL(labelDeviceVendor), DeviceMgr.Vendor->str);
    gtk_label_set_text(GTK_LABEL(labelDeviceProduct), DeviceMgr.Product->str);
    tmp_string = g_strdup_printf("0x%x", DeviceMgr.VendorID);
    gtk_label_set_text(GTK_LABEL(labelVenID), tmp_string);
    g_free(tmp_string);
    tmp_string = g_strdup_printf("0x%x", DeviceMgr.ProductID);
    gtk_label_set_text(GTK_LABEL(labelProdID), tmp_string);
    g_free(tmp_string);
    tmp_string = g_strdup_printf("0x%x", DeviceMgr.BusLoc);
    gtk_label_set_text(GTK_LABEL(labelBusLoc), tmp_string);
    g_free(tmp_string);
    tmp_string = g_strdup_printf("0x%x", DeviceMgr.DeviceID);
    gtk_label_set_text(GTK_LABEL(labelDevNum), tmp_string);
    g_free(tmp_string);
    return windowDialog;
}

// ************************************************************************************************

void on_deviceProperties_activate(GtkWidget *item, gpointer user_data) {
    UNUSED(item);
    UNUSED(user_data);
    gchar *tmp_string;

    // We confirm our device properties, this should setup the device structure information we use below.
    deviceProperties();

    // Update the status bar with our information.
    if (DeviceMgr.storagedeviceID == MTP_DEVICE_SINGLE_STORAGE) {
        tmp_string = g_strdup_printf(_("Connected to %s - %d MB free"), DeviceMgr.devicename->str,
                (int) (DeviceMgr.devicestorage->FreeSpaceInBytes / MEGABYTE));
    } else {
        if (DeviceMgr.devicestorage->StorageDescription != NULL) {
            tmp_string = g_strdup_printf(_("Connected to %s (%s) - %d MB free"),
                    DeviceMgr.devicename->str,
                    DeviceMgr.devicestorage->StorageDescription,
                    (int) (DeviceMgr.devicestorage->FreeSpaceInBytes / MEGABYTE));
        } else {
            tmp_string = g_strdup_printf(_("Connected to %s - %d MB free"), DeviceMgr.devicename->str,
                    (int) (DeviceMgr.devicestorage->FreeSpaceInBytes / MEGABYTE));
        }
    }
    statusBarSet(tmp_string);
    g_free(tmp_string);

    // No idea how this could come about, but we should take it into account so we don't have a
    // memleak due to recreating the window multiple times.
    if (windowPropDialog != NULL) {
        gtk_widget_hide(windowPropDialog);
        gtk_widget_destroy(windowPropDialog);
    }

    // Create and show the dialog box.
    windowPropDialog = create_windowProperties();
    gtk_widget_show(GTK_WIDGET(windowPropDialog));
} // end on_deviceProperties_activate()

// ************************************************************************************************

void on_quitProp_activate(GtkWidget *item, gpointer user_data) {
    UNUSED(item);
    UNUSED(user_data);
    gtk_widget_hide(windowPropDialog);
    gtk_widget_destroy(windowPropDialog);
    windowPropDialog = NULL;
} // end on_quitProp_activate()

// ************************************************************************************************

void addRow(GtkWidget* table, gint row, char* title, GtkWidget** field) {

    GtkWidget* label = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(label), title);
    gtk_widget_show(label);
#if HAVE_GTK3 == 0
    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1,
            (GtkAttachOptions) (GTK_FILL),
            (GtkAttachOptions) (0), 0, 0);
#else
    gtk_grid_attach(GTK_GRID(table), label, 0, row, 1, 1);
#endif
    gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);

#if HAVE_GTK3 == 0    
    gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
#else
    gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_START);
    gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_START);
#endif

    GtkWidget* fieldLabel = gtk_label_new((""));
    *field = fieldLabel;
    gtk_widget_show(fieldLabel);
#if HAVE_GTK3 == 0
    gtk_table_attach(GTK_TABLE(table), fieldLabel, 1, 2, row, row + 1,
            (GtkAttachOptions) (GTK_FILL),
            (GtkAttachOptions) (0), 0, 0);
#else
    gtk_grid_attach(GTK_GRID(table), fieldLabel, 1, row, 1, 1);
#endif

#if HAVE_GTK3 == 0    
    gtk_misc_set_alignment(GTK_MISC(fieldLabel), 0, 0.5);
#else
    gtk_widget_set_halign(GTK_WIDGET(fieldLabel), GTK_ALIGN_START);
    gtk_widget_set_valign(GTK_WIDGET(fieldLabel), GTK_ALIGN_CENTER);
#endif
}

