#include "TZ_Vendor_debug_tl.h"
#include "tl_tui_bc_error_msg.h"
#include "Vendor_Interface.h"

#include "TuiButton.h"
#include "TuiConfirmScreenController.h"
#include "TuiTextBox.h"
#include "TuiImageView.h"
#include "TuiScreenResource.h"
#include "TuiPng.h"
#include <string.h>
#include <ctype.h>

#include "TuiLayout.h"

#define MAX_LENGTH 35

#define MAX_STRING 100
#define MAX_DATA_STRING 210
#define MAX_VALUE 100
#define MAX_UNIT 4
#define MAX_TO_ADDRESS 10

#define MAX_AMOUNT_STR_LENGTH 27
#define MAX_TOKEN_STR_LENGTH 22

#ifdef _WIN32
#define strtok_r strtok_s
#endif

char *rtrim(char *s);

typedef enum COIN_TYPE {
    NONE_COIN, BTC, ETH, KLAY, TRX, XLM, UNKNOWN_COIN
} CoinType;

typedef enum METHOD {
    Transfer, Transferfrom, approve, allowance
} Method;

typedef enum AMOUNT_TYPE {
    AMOUNT_NONE, AMOUNT_ETH, AMOUNT_TOKEN
} AmountType;

typedef struct {
    CoinType coinType; // can use it for unit.
    uint8_t method[MAX_STRING];
    uint8_t toAddress[MAX_TO_ADDRESS][MAX_STRING];
    uint32_t toAddressCount;
    uint32_t addressNumber[MAX_STRING]; // for BTC

    uint8_t amount[MAX_VALUE];
    uint8_t amountUnit[MAX_UNIT];

    uint8_t tokenName[MAX_STRING];
    uint8_t tokenAddress[MAX_STRING];
    uint8_t tokenAmount[MAX_VALUE];
    uint8_t tokenAmountUnit[MAX_VALUE];


    uint8_t gasPrice[MAX_VALUE];
    uint8_t gasPriceUnit[MAX_UNIT];

    uint8_t gasLimit[MAX_VALUE];

    uint8_t dataLength[MAX_VALUE];
    uint8_t data[MAX_DATA_STRING];

    uint8_t fee[MAX_VALUE];
    uint8_t feeUnit[MAX_UNIT];

    uint8_t total[MAX_VALUE];
    uint8_t totalUnit[MAX_UNIT];

    uint8_t resourceType[MAX_VALUE];
    uint8_t superRepresentativeName[MAX_VALUE];
    uint8_t voteCount[MAX_VALUE];

    uint8_t assetName[MAX_STRING];
    uint8_t assetAmount[MAX_VALUE];

    uint8_t memovalue[MAX_STRING];

} TransactionStr;

static char emptyString[1] = {'\0'};

static uint32_t startY;

void setStartY(uint32_t y) {
    startY = y;
}

Node gConfirmScreenControlNode[MAX_CONTROL];

uint32_t initConfirmScreenController() {
    initLayout();
    initTextBuffer();

    return TIMA_SUCCESS;
}

Node *getConfirmScreenControlNode() {
    return gConfirmScreenControlNode;
}

uint32_t parserTransactionStr(TransactionStr *tranStr, uint8_t *str) {
    char *ret_itor = (char *) str;
    char *remain_itor = (char *) str;
    char *itor_unit;
    char *itor_number;

    const char unit_delimit[] = " ";
    const char delimit[] = ",:";
    const char content_delimit[] = ",";
    uint32_t ret = 0;
    size_t length = 0;

    //init
    memset(tranStr, 0, sizeof(TransactionStr));

    do {
        ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
        if (ret_itor == NULL)
            break;

        if (strcmp(ret_itor, "type") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            if (strcmp(ret_itor, "BTC") == 0) {
                tranStr->coinType = BTC;
            } else if (strcmp(ret_itor, "ETH") == 0) {
                tranStr->coinType = ETH;
            } else if (strcmp(ret_itor, "KLAY") == 0) {
                tranStr->coinType = KLAY;
            } else if (strcmp(ret_itor, "TRX") == 0) {
                tranStr->coinType = TRX;
            } else if (strcmp(ret_itor, "XLM") == 0) {
                tranStr->coinType = XLM;
            } else {
                TTY_LOG("%s unknown coin type : %s", LOG_TAG, ret_itor);
                return ERROR_BC_TUI;
            }
            continue;
        }

        if (strcmp(ret_itor, "method") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            strcpy((char *) tranStr->method, ret_itor);
            continue;
        }

        if (strncmp(ret_itor, "recipientaddress", strlen("recipientaddress")) == 0) {
            if (tranStr->coinType == BTC) {
                strtok_r(ret_itor, " ", &itor_number);
                strcpy((char *) tranStr->addressNumber, itor_number);
            }

            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            strcpy((char *) tranStr->toAddress[tranStr->toAddressCount], ret_itor);
            //addressNumber = ;
            ++tranStr->toAddressCount;
            continue;
        }

        if (strcmp(ret_itor, "contractaddress") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            strcpy((char *) tranStr->toAddress[tranStr->toAddressCount], ret_itor);
            ++tranStr->toAddressCount;
            continue;
        }

        if (strcmp(ret_itor, "amount") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            //ret_itor = strtok_r(ret_itor, unit_delimit, &itor_unit);
            strcpy((char *) tranStr->amount, ret_itor);
            //strcpy((char*)tranStr->amountUnit, itor_unit);
            continue;
        }


        if (strcmp(ret_itor, "tokenamount") == 0 || strcmp(ret_itor, "tokenid") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            //ret_itor = strtok_r(ret_itor, unit_delimit, &itor_unit);
            strcpy((char *) tranStr->tokenAmount, ret_itor);
            //strcpy((char*)tranStr->tokenAmountUnit, itor_unit);
            continue;
        }

        if (strcmp(ret_itor, "tokenaddress") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            strcpy((char *) tranStr->tokenAddress, ret_itor);
            continue;
        }

        if (strcmp(ret_itor, "tokenname") == 0) {
            ret_itor = strtok_r(remain_itor, content_delimit, &remain_itor);
            //ret_itor = strtok_r(ret_itor, unit_delimit, &itor_unit);
            strcpy((char *) tranStr->tokenName, ret_itor);
            //strcpy((char*)tranStr->tokenAmountUnit, itor_unit);
            continue;
        }

        if (strcmp(ret_itor, "gasprice") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            //ret_itor = strtok_r(ret_itor, unit_delimit, &itor_unit);
            strcpy((char *) tranStr->gasPrice, ret_itor);
            //strcpy((char*)tranStr->gasPriceUnit, itor_unit);
            continue;
        }

        if (strcmp(ret_itor, "gaslimit") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            //ret_itor = strtok_r((char*)ret_itor, unit_delimit, &itor_unit);
            strcpy((char *) tranStr->gasLimit, ret_itor);
            continue;
        }

        if (strcmp(ret_itor, "data") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            strcpy((char *) tranStr->data, ret_itor);
            continue;
        }

        if (strcmp(ret_itor, "datalength") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            strcpy((char *) tranStr->dataLength, ret_itor);
            continue;
        }

        if (strcmp(ret_itor, "fee") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            //ret_itor = strtok_r((char*)ret_itor, unit_delimit, &itor_unit);
            strcpy((char *) tranStr->fee, ret_itor);
            //strcpy((char*)tranStr->feeUnit, itor_unit);
            continue;
        }

        if (strcmp(ret_itor, "total") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            //ret_itor = strtok_r((char*)ret_itor, unit_delimit, &itor_unit);
            strcpy((char *) tranStr->total, ret_itor);
            //strcpy((char*)tranStr->feeUnit, itor_unit);
            continue;
        }

        if (strcmp(ret_itor, "resourcetype") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            //ret_itor = strtok_r((char*)ret_itor, unit_delimit, &itor_unit);
            strcpy((char *) tranStr->resourceType, ret_itor);
            //strcpy((char*)tranStr->feeUnit, itor_unit);
            continue;
        }

        if (strcmp(ret_itor, "superrepresentative") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            strcpy((char *) tranStr->superRepresentativeName, ret_itor);
            continue;
        }

        if (strcmp(ret_itor, "votecount") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            strcpy((char *) tranStr->voteCount, ret_itor);
            continue;
        }

        if (strcmp(ret_itor, "assetname") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            strcpy((char *) tranStr->assetName, ret_itor);
            continue;
        }
        if (strcmp(ret_itor, "assetamount") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
            strcpy((char *) tranStr->assetAmount, ret_itor);
            continue;
        }
        if (strcmp(ret_itor, "memovalue") == 0) {
            ret_itor = strtok_r(remain_itor, delimit, &remain_itor);
//            strcpy((char*)tranStr->memovalue, ret_itor);
            continue;
        }

    } while (remain_itor != '\0');

    return TIMA_SUCCESS;
}

bool isZeroAmount(char *str) {
    char amountStr[3] = {str[0], str[1], '\0'};
    char zeroAmountStr[3] = "0 \0";

    if (strcmp(amountStr, zeroAmountStr) == 0) {
        return true;
    }
    return false;
}

bool isEmptyStr(char *str) {
    if (strcmp(str, emptyString) == 0) {
        return true;
    }
    return false;
}

void drawDividerType(Location *loc) {
    uint8_t *resource;
    uint32_t resourceSize = 0;
    uint32_t resourceWidth = 0;
    uint32_t resourceHeight = 0;

    resource = getScreenResource(ID_RESOURCE_CONFIRM_DIVIDER, &resourceSize);
    showPng(CONFIRM_DIVIDER_SIDE_MARGIN, loc->y1, resource, resourceSize);
    getPngWidthAndHeight(resource, &resourceWidth, &resourceHeight);

    loc->y1 += resourceHeight;
    loc->y1 += CONFIRM_DIVIDER_LINE_DISTANCE;
    return;
}

bool drawAddressType(uint32_t id, uint8_t *value, Location *loc) {
    TextInfo textInfo;
    Control control;
    if (isEmptyStr((char *) value) == false) {
        loc->y1 += CONFIRM_TEXT_ADDRESS_TYPE_TOP_MARGIN;
        textInfo.font = getScreenFontType(ID_FONT_TYPE_CONFIRM_ADDRESS);
        textInfo.text = value;
        initTextBox(&control, id, *loc, CONFIRM_TEXT_AREA_WIDTH, CONFIRM_TEXT_ADDRESS_HEIGHT, NULL,
                    0,
                    NULL, 0, textInfo, LEFT_CONTENT_ALIGN, VERTICAL_TOP_CONTENT_ALIGN);
        addTextViewBox(&control, executeTextViewBox);
        loc->y1 += CONFIRM_TEXT_ADDRESS_HEIGHT;
        loc->y1 += CONFIRM_DIVIDER_LINE_DISTANCE;
        return true;
    }
    return false;
}

bool _drawValueStandardType(uint32_t id, uint8_t *value, Location *loc, int32_t customPadding,
                            uint8_t maxStrLength) {
    TextInfo textInfo;
    Control control;
    uint32_t fontHeight;

    if (isEmptyStr((char *) value) == false) {
        textInfo.text = value;
        textInfo.font = getScreenFontType(ID_FONT_TYPE_CONFIRM_AMOUNT);

        fontHeight = getFontHeight(textInfo.font);

        if (!(getScreenType() == SCREEN_TYPE_WINNER_MAIN) &&
            strlen((char *) value) > maxStrLength) {
            loc->y1 += (fontHeight + CONFIRM_TEXT_GAS_PRICE_LINE_DISTANCE);
        }

        initTextBox(&control, id, *loc, CONFIRM_TEXT_AREA_WIDTH, fontHeight, NULL, 0, NULL, 0,
                    textInfo, RIGHT_CONTENT_ALIGN, VERTICAL_CENTER_CONTENT_ALIGN);
        addTextViewBox(&control, executeTextViewBox);
        loc->y1 += fontHeight;

        if (customPadding > 0) {
            loc->y1 += customPadding;
        } else {
            loc->y1 += CONFIRM_TEXT_AMOUNT_LINE_DISTANCE;
        }


        return true;
    }
    return false;
}

bool drawValueStandardType(uint32_t id, uint8_t *value, Location *loc) {
    return _drawValueStandardType(id, value, loc, -1, MAX_AMOUNT_STR_LENGTH);
}

bool drawValueStandardTypeWithMaxAmountLength(uint32_t id, uint8_t *value, Location *loc,
                                              uint8_t max_length) {
    return _drawValueStandardType(id, value, loc, -1, max_length);
}

bool drawValueStandardTypeWithCustomPadding(uint32_t id, uint8_t *value, Location *loc,
                                            int32_t customPadding) {
    return _drawValueStandardType(id, value, loc, customPadding, MAX_AMOUNT_STR_LENGTH);
}


bool drawValueSubType(uint32_t id, uint8_t *value, Location *loc, int32_t customPadding) {
    TextInfo textInfo;
    Control control;
    uint32_t fontHeight;

    if (isEmptyStr((char *) value) == false) {
        textInfo.text = value;
        textInfo.font = getScreenFontType(ID_FONT_TYPE_CONFIRM_GAS);
        fontHeight = getFontHeight(textInfo.font);
        initTextBox(&control, id, *loc, CONFIRM_TEXT_AREA_WIDTH, fontHeight, NULL, 0, NULL, 0,
                    textInfo, RIGHT_CONTENT_ALIGN, VERTICAL_CENTER_CONTENT_ALIGN);
        addTextViewBox(&control, executeTextViewBox);
        loc->y1 += fontHeight;

        if (customPadding > 0) {
            loc->y1 += customPadding;
        }

        return true;
    }
    return false;
}

bool drawDataType(uint32_t id, TransactionStr *tranStr, Location *loc) {
    TextInfo textInfo;
    Control control;
    uint32_t fontHeight;

    uint32_t resourceWidth = 0;
    uint32_t resourceHeight = 0;

    if (isEmptyStr((char *) tranStr->dataLength) == false) {
        textInfo.font = getScreenFontType(ID_FONT_TYPE_CONFIRM_DATA);
        textInfo.text = tranStr->dataLength;

//        loc.y1 + CONFIRM_TEXT_DATA_LENGTH_LINE_DISTANCE;
        fontHeight = getFontHeight(textInfo.font);

        initTextBox(&control, id, *loc, CONFIRM_TEXT_AREA_WIDTH, fontHeight, NULL, 0, NULL, 0,
                    textInfo, RIGHT_CONTENT_ALIGN, VERTICAL_CENTER_CONTENT_ALIGN);
        addTextViewBox(&control, executeTextViewBox);
    } else {
        return false;
    }

    if (isEmptyStr((char *) tranStr->data) == false) {
        textInfo.font = getScreenFontType(ID_FONT_TYPE_CONFIRM_DATA);
        textInfo.text = tranStr->data;

        loc->y1 += CONFIRM_TEXT_ADDRESS_TYPE_TOP_MARGIN;
        fontHeight = getFontHeight(textInfo.font);

        initTextBox(&control, id, *loc, CONFIRM_TEXT_AREA_WIDTH, CONFIRM_TEXT_EXTRA_GUIDE_HEIGHT,
                    NULL, 0, NULL, 0, textInfo, LEFT_CONTENT_ALIGN, VERTICAL_TOP_CONTENT_ALIGN);
        addTextViewBox(&control, executeTextViewBox);

        loc->y1 += CONFIRM_TEXT_DATA_LINE_DISTANCE + CONFIRM_TEXT_EXTRA_GUIDE_HEIGHT;
        return true;
    }
    return false;
}

uint32_t drawTotalType(uint32_t id, uint8_t *str, Location *loc) {
    TextInfo textInfo;
    Control control;
    uint32_t fontHeight;

    uint32_t resourceWidth = 0;
    uint32_t resourceHeight = 0;

    if (isEmptyStr((char *) str) == false && strcmp((char *) str, "0\0") != 0) {
        textInfo.text = str;
        textInfo.font = getScreenFontType(ID_FONT_TYPE_CONFIRM_TOTAL);

        fontHeight = getFontHeight(textInfo.font);
        if (!(getScreenType() == SCREEN_TYPE_WINNER_MAIN) &&
            strlen((char *) str) > MAX_AMOUNT_STR_LENGTH) {
            loc->y1 += (fontHeight + CONFIRM_TEXT_GAS_PRICE_LINE_DISTANCE);
        }

        initTextBox(&control, id, *loc,
                    CONFIRM_TEXT_AREA_WIDTH - resourceWidth - (resourceHeight / 2), fontHeight,
                    NULL, 0, NULL, 0, textInfo, RIGHT_CONTENT_ALIGN, VERTICAL_CENTER_CONTENT_ALIGN);
        addTextViewBox(&control, executeTextViewBox);
        loc->y1 += fontHeight;

        return true;
    }
    return false;
}


uint32_t drawScreenForETH(TransactionStr tranStr) {

    Location loc;
    uint32_t controlId = 1;

    // BORDER
    // RECIPIENT ADDRESS
    // CONTRACT ADDRESS (Opt)
    // Token Name (Opt)
    // Data (Opt)
    // BORDER
    // TOKEN AMOUNT or TOKEN_AMOUNT_NL (Opt)
    // TOKEN_ID or TOKEN_ID_NL (Opt)
    // AMOUNT or AMOUNT_NL (Opt)
    // FEE
    // GP
    // GL
    // BORDER (Opt)
    // TOTAL (Opt)

    bool hasEth = (isEmptyStr((char *) tranStr.method) == true) ||
                  (isZeroAmount((char *) tranStr.amount) == false);

    loc.x1 = CONFIRM_TEXT_SIDE_MARGIN;
    loc.y1 = startY;

    // BORDER
    drawDividerType(&loc);


    // RECIPIENT ADDRESS
    // CONTRACT ADDRESS (Opt)
    for (int i = 0; i < tranStr.toAddressCount; i++) {
        drawAddressType(controlId++, tranStr.toAddress[i], &loc);
    }

    // Token Name (Opt)
    if (isEmptyStr((char *) tranStr.tokenName) == false) {
        drawAddressType(controlId++, tranStr.tokenName, &loc);
    }

    // Data (Opt)
    if (isEmptyStr((char *) tranStr.data) == false) {
        drawDataType(controlId++, &tranStr, &loc);
    }

    // BORDER
    drawDividerType(&loc);


    // TOKEN AMOUNT or TOKEN_AMOUNT_NL (Opt)
    // TOKEN_ID or TOKEN_ID_NL (Opt)
    if (isEmptyStr((char *) tranStr.tokenAmount) == false) {
        drawValueStandardTypeWithMaxAmountLength(controlId++,
                                                 (uint8_t *) rtrim((char *) tranStr.tokenAmount), &loc,
                                                 MAX_TOKEN_STR_LENGTH);
    }

    // AMOUNT or AMOUNT_NL (Opt)
    if (hasEth) {
        drawValueStandardType(controlId++, tranStr.amount, &loc);
    }

    // FEE
    if (isEmptyStr((char *) tranStr.fee) == false) {
        drawValueStandardTypeWithCustomPadding(controlId++, tranStr.fee, &loc,
                                               BACKUP_QUIZ_TEXTINPUT_LINE_DISTANCE);
    }

    // GP
    if (isEmptyStr((char *) tranStr.gasPrice) == false) {
        drawValueSubType(controlId++, tranStr.gasPrice, &loc, -1);
    }

    // GL
    if (isEmptyStr((char *) tranStr.gasPrice) == false) {
        drawValueSubType(controlId++, tranStr.gasLimit, &loc, CONFIRM_TEXT_AMOUNT_LINE_DISTANCE);
    }

    // BORDER (Opt)
    // TOTAL (Opt)
    if (isEmptyStr((char *) tranStr.total) == false) {
        drawDividerType(&loc);
        drawTotalType(controlId++, tranStr.total, &loc);
    }


    return TIMA_SUCCESS;
}

uint32_t drawScreenForBTC(TransactionStr tranStr) {
    Control control;
    Location loc;
    uint32_t controlId = 1;
    TextInfo textInfo;
    uint32_t fontHeight = 0;

    uint32_t resourceWidth = 0;
    uint32_t resourceHeight = 0;
    bool ret = 0;

    loc.x1 = CONFIRM_TEXT_SIDE_MARGIN;
    loc.y1 = startY;

    if (tranStr.toAddressCount > 1)
        return FAILED_TUI_STATE;

    drawDividerType(&loc);

    ret = drawAddressType(controlId++, tranStr.toAddress[0], &loc);

    drawDividerType(&loc);

    if (isEmptyStr((char *) tranStr.method) == true ||
        isZeroAmount((char *) tranStr.amount) == false) {
        ret = drawValueStandardType(controlId++, tranStr.amount, &loc);
    }

    ret = drawValueStandardType(controlId++, tranStr.fee, &loc);

    if (isEmptyStr((char *) tranStr.total) == false) {
        drawDividerType(&loc);
        drawTotalType(controlId++, tranStr.total, &loc);
    }

    return TIMA_SUCCESS;
}

uint32_t drawScreenForKLAY(TransactionStr tranStr) {

    // BORDER
    // RECIPIENT ADDRESS
    // CONTRACT ADDRESS (Opt)
    // Token Name (Opt)
    // Data (Opt)
    // BORDER
    // TOKEN AMOUNT or TOKEN_AMOUNT_NL (Opt)
    // AMOUNT or AMOUNT_NL (Opt)
    // FEE
    // BORDER (Opt)
    // TOTAL (Opt)

    Location loc;
    uint32_t controlId = 1;

    bool hasAmount = (isEmptyStr((char *) tranStr.method) == true) ||
                     (isZeroAmount((char *) tranStr.amount) == false);
    bool hasData = (isEmptyStr((char *) tranStr.data) == false);

    loc.x1 = CONFIRM_TEXT_SIDE_MARGIN;
    loc.y1 = startY;

    // BORDER
    drawDividerType(&loc);

    // RECIPIENT ADDRESS
    // CONTRACT ADDRESS (Opt)
    for (int i = 0; i < tranStr.toAddressCount; i++) {
        drawAddressType(controlId++, tranStr.toAddress[i], &loc);
    }

    // Token Name (Opt)
    if (isEmptyStr((char *) tranStr.tokenName) == false) {
        drawAddressType(controlId++, tranStr.tokenName, &loc);
    }

    // Data (Opt)
    if (hasData) {
        drawDataType(controlId++, &tranStr, &loc);
    }

    // BORDER
    drawDividerType(&loc);

    // TOKEN AMOUNT or TOKEN_AMOUNT_NL (Opt)
    // TOKEN_ID or TOKEN_ID_NL (Opt)
    if (isEmptyStr((char *) tranStr.tokenAmount) == false) {
        drawValueStandardTypeWithMaxAmountLength(controlId++, tranStr.tokenAmount, &loc,
                                                 MAX_TOKEN_STR_LENGTH);
    }

    // AMOUNT or AMOUNT_NL (Opt)
    if (hasAmount) {
        drawValueStandardType(controlId++, tranStr.amount, &loc);
    }

    // FEE
    if (isEmptyStr((char *) tranStr.fee) == false) {
        drawValueStandardType(controlId++, tranStr.fee, &loc);
    }

    // BORDER (Opt)
    // TOTAL (Opt)
    if (isEmptyStr((char *) tranStr.total) == false) {
        drawDividerType(&loc);
        drawTotalType(controlId++, tranStr.total, &loc);
    }


    return TIMA_SUCCESS;
}

uint32_t drawScreenForTRX(TransactionStr tranStr) {

    Location loc;
    uint32_t controlId = 1;

    bool hasAmount = (isEmptyStr((char *) tranStr.method) == true) ||
                     (isZeroAmount((char *) tranStr.amount) == false);
    bool hasData = (isEmptyStr((char *) tranStr.data) == false);
    loc.x1 = CONFIRM_TEXT_SIDE_MARGIN;
    loc.y1 = startY;

    drawDividerType(&loc);

    if (isEmptyStr((char *) tranStr.superRepresentativeName) == false) {
        drawValueStandardType(controlId++, tranStr.superRepresentativeName, &loc);
    }

    drawAddressType(controlId++, tranStr.toAddress[0], &loc);

    if (hasData) {
        drawDataType(controlId++, &tranStr, &loc);
    }

    if (isEmptyStr((char *) tranStr.tokenName) == false) {
        drawAddressType(controlId++, tranStr.tokenName, &loc);
    }

    drawDividerType(&loc);

    if (isEmptyStr((char *) tranStr.tokenAmount) == false) {
        drawValueStandardTypeWithMaxAmountLength(controlId++,
                                                 (uint8_t *) rtrim((char *) tranStr.tokenAmount), &loc,
                                                 MAX_TOKEN_STR_LENGTH);
    }

    if (isEmptyStr((char *) tranStr.assetName) == false) {
        drawValueStandardType(controlId++, tranStr.assetName, &loc);
    }

    if (isEmptyStr((char *) tranStr.assetAmount) == false) {
        drawValueStandardType(controlId++, (uint8_t *) rtrim((char *) tranStr.assetAmount), &loc);
    }

    if (hasAmount) {
        drawValueStandardType(controlId++, tranStr.amount, &loc);
    }

    if (isEmptyStr((char *) tranStr.resourceType) == false) {
        drawValueStandardType(controlId++, tranStr.resourceType, &loc);

    }

    if (isEmptyStr((char *) tranStr.fee) == false) {
        drawValueStandardType(controlId++, tranStr.fee, &loc);
    }

    if (isEmptyStr((char *) tranStr.total) == false) {
        drawDividerType(&loc);
        drawTotalType(controlId++, tranStr.total, &loc);
    }

    return TIMA_SUCCESS;
}

uint32_t drawScreenForXLM(TransactionStr tranStr) {
    Location loc;
    uint32_t controlId = 1;

    loc.x1 = CONFIRM_TEXT_SIDE_MARGIN;
    loc.y1 = startY;

    // BORDER
    drawDividerType(&loc);

    if (strcmp((const char *) tranStr.method, "6") == 0) {
        if (isEmptyStr((char *) tranStr.tokenAddress) == false) {
            drawAddressType(controlId++, tranStr.tokenAddress, &loc);
        }
    } else {
        drawAddressType(controlId++, tranStr.toAddress[0], &loc);
    }

    loc.y1 += (CONFIRM_TEXT_ADDRESS_TYPE_TOP_MARGIN + CONFIRM_DIVIDER_LINE_DISTANCE +
               CONFIRM_TEXT_DATA_MEMO_HEIGHT); //memo


    if (isEmptyStr((char *) tranStr.assetName) == false) {        //payment #op : 1
        drawAddressType(controlId++, tranStr.assetName, &loc);
    }

    // BORDER
    drawDividerType(&loc);

    if (isEmptyStr((char *) tranStr.tokenName) == false) {           //change trust #op : 6
        drawValueStandardType(controlId++, tranStr.tokenName, &loc);
    }

    if (isEmptyStr((char *) tranStr.amount) == false) {
        drawValueStandardType(controlId++, tranStr.amount, &loc);
    }

    if (isEmptyStr((char *) tranStr.assetAmount) == false) {      //payment #op : 1
        drawValueStandardType(controlId++, tranStr.assetAmount, &loc);
    }

    if (isEmptyStr((char *) tranStr.fee) == false) {
        drawValueStandardType(controlId++, tranStr.fee, &loc);
    }

    if (isEmptyStr((char *) tranStr.total) == false) {
        drawDividerType(&loc);
        drawValueStandardType(controlId++, tranStr.total, &loc);
    }
    return TIMA_SUCCESS;

}

uint32_t drawConfirmScreen(uint8_t *str) {
    TransactionStr tranStr;
    uint32_t ret = TIMA_SUCCESS;


    ret = parserTransactionStr(&tranStr, str);
    if (ret != TIMA_SUCCESS) {
        TTY_LOG("%s failed parsing", LOG_TAG);
        return ERROR_BC_TUI;
    }

    switch (tranStr.coinType) {
        case ETH:
            ret = drawScreenForETH(tranStr);
            break;
        case BTC:
            ret = drawScreenForBTC(tranStr);
            break;
        case KLAY:
            ret = drawScreenForKLAY(tranStr);
            break;
        case TRX:
            ret = drawScreenForTRX(tranStr);
            break;
        case XLM:
            ret = drawScreenForXLM(tranStr);
            break;
        case NONE_COIN:
            break;
        case UNKNOWN_COIN:
            break;
        default:
            TTY_LOG("%d does not support", tranStr.coinType);
            break;
    }

    startY = 0;

    return ret;
}

char *rtrim(char *s) {

    if (!strlen(s)) {
        return s;
    }

    char *end;

    end = s + strlen(s) - 1;
    while (end != s && isspace(*end)){
        end--;
        TTY_LOG("end : %s", end);
    }
    *(end + 1) = '\0';

    return s;
}
