// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

/**
 * A currency formatter singleton that uses the currency information as written to
 * the smarty template in $ViisonCurrency to format values.
 */
Ext.define('Shopware.apps.ViisonCommonCurrencyFormatter.Formatter', {

    singleton: true,
    mixins: [
        'Shopware.apps.ViisonCommonApp.Mixin',
    ],
    alternateClassName: 'ViisonCurrencyFormatter',
    viisonConfigNamespace: 'ViisonCommonCurrencyFormatter',

    constructor: function () {
        this.currencySymbol = this.getViisonConfig('currencySymbol');
        this.currencyAtEnd = this.getViisonConfig('symbolAtEnd');
    },

    /**
     * Returns the given value in a currency format (with blank between symbol and number),
     * e.g. "$ 0.00", "0.00 €".
     *
     * If the given value is NULL, it is not formatted, but "-" is
     * returned instead.
     *
     * @param {number|string|null} value
     * @return {string}
     */
    renderer: function (value) {
        return ViisonCurrencyFormatter.formatWithSymbol(
            value,
            ViisonCurrencyFormatter.currencySymbol,
            ViisonCurrencyFormatter.currencyAtEnd
        );
    },

    /**
     * Returns a renderer function that formats the given value with the currency of the record that is accessed via the
     * currencyInformationAtPath given to this factory.
     *
     * The currency should hold the properties 'symbol' and 'symbolAtEnd'. If no 'symbol' is set, the fallback 'code' is
     * used instead. If no 'symbolAtEnd' is set, default true is used.
     *
     * @param {string} currencyInformationAtPath
     * @returns {function(float, mixed, object): (string)}
     */
    makeRendererWithCurrencyInformationAtPath: function (currencyInformationAtPath) {
        return function (value, meta, record) {
            var currency = record.get(currencyInformationAtPath);

            if (!currency) {
                return value;
            }

            return ViisonCurrencyFormatter.formatWithSymbol(
                value,
                currency.symbol ? currency.symbol : currency.code,
                currency.symbolAtEnd !== null ? currency.symbolAtEnd : true
            );
        };
    },

    /**
     * Returns a renderer function that formats the passed value with the given currencySymbol and symbolPosition.
     *
     * @param {string} currencySymbol
     * @param {number} currencyPosition Coming from Shopware's Shopware\Models\Shop\Currency the positions number
     * represents the position of the currency symbol in relation to the value (0 = default (right), 16 = right, 32 =
     * left).
     * @returns {function(float): (string)}
     */
    makeRendererWithSymbolAndPosition: function (currencySymbol, currencyPosition) {
        return function (value) {
            return ViisonCurrencyFormatter.formatWithSymbolAndPosition(value, currencySymbol, currencyPosition);
        };
    },

    /**
     * Returns the given value formatted with the given currencySymbol and currencyPosition.
     *
     * @param value
     * @param {string} currencySymbol
     * @param {number} currencyPosition Coming from Shopware's Shopware\Models\Shop\Currency the positions number
     * @returns {string}
     */
    formatWithSymbolAndPosition: function (value, currencySymbol, currencyPosition) {
        return ViisonCurrencyFormatter.formatWithSymbol(
            value,
            currencySymbol,
            currencyPosition !== 32
        );
    },

    /**
     * Returns the given value formatted in the Shopware.apps.Base.model.Currency that is found in the given record.
     *
     * The Shopware.apps.Base.model.Currency must be accessible via the getCurrency() getter.
     *
     * @param {float} value
     * @param {mixed} meta
     * @param {object} record
     * @returns {string}
     */
    formatWithCurrencyInRecord: function (value, meta, record) {
        var currency = record.getCurrency();

        if (!currency) {
            return ViisonCurrencyFormatter.renderer(value);
        }

        return ViisonCurrencyFormatter.formatWithSymbolAndPosition(
            value,
            currency.raw.symbol,
            currency.raw.symbolPosition
        );
    },

    /**
     * Returns the given value in a currency format (with blank between symbol and number), e.g. "$ 0.00", "0.00 €".
     *
     * @param {number|string|null} value
     * @param {string} currencySymbol
     * @param {boolean} currencyAtEnd
     * @return {string}
     */
    formatWithSymbol: function (value, currencySymbol, currencyAtEnd) {
        // Don't format NULL values
        if (value === null) {
            return '-';
        }

        // Use the ExtJS currency formatter to format the value
        return Ext.util.Format.currency(
            value,
            (' ' + currencySymbol + ' '),
            2,
            currencyAtEnd
        ).trim();
    },

});
