# -*- coding: utf-8 -*-
##############################################################################
#
#    Odoo, Open Source Management Solution
#    Copyright (C) 2016 Prime Consulting SA, Cape Verde (<http://prime.cv>).
#
##############################################################################

from odoo import api, models
import re


re_digits_nondigits = re.compile(r'\d+|\D+')

def _commafy(s):
            r = []
            for i, c in enumerate(reversed(s)):
                if i and (not (i % 3)):
                    r.insert(0, '.')
                r.insert(0, c)
            return ''.join(r)

def FormatWithCommas(value):
            format = '%.2f'
            parts = re_digits_nondigits.findall(format % (value,))
            for i in xrange(len(parts)):
                s = parts[i]
                if s.isdigit():
                    parts[i] = _commafy(s)
                    break
            return ''.join(parts)

def SeparaCommas(value):
            res  = str(FormatWithCommas(value)).split('.')
            result=''
            size=len(res)
            j = []
            for i in range (0,size):
                     j.append(i)
                     if i == 0:
                           result +=res[i]
                     elif  (i +1) == size:
                           result += '$'+res[i]
                     else:
                           result +='.'+res[i]
                    
            return result

# Portuguese added by AMA
# Updated by NSS 
#-------------------------------------------------------------

to_19_pt = ( 'Zero',  'Um',   'Dois',  u'Três', 'Quatro',   'Cinco',   'Seis',
          'Sete', 'Oito', 'Nove', 'Dez',   'Onze', 'Doze', 'Treze',
          'Quatorze', 'Quinze', 'Dezaseis', 'Dezasete', 'Dezoito', 'Dezanove' )
tens_pt  = ( 'Vinte', 'Trinta', 'Quarenta', 'Cinquenta', 'Sessenta', 'Setenta', 'Oitenta', 'Noventa')
cent_pt  = ('Cento','Duzentos','Trezentos','Quatrocentos','Quinhentos','Seiscentos','Setecentos','Oitocentos','Novecentos')
denom_pt = ( '',
          'Mil',     u'Milhões',         'Milhares',       u'Bilhões',       u'Quadriliões',
          'Quintilião', u'Sextilião',      u'Septilião',    u'Octilião',      u'Nonilião',
          'Décilião',    'Undecilião',     'Duodecilião',  'Tredecilião',   'Quatuordecilião',
          'Sexdecilião', 'Septendecilião', 'Octodecilião', 'Icosilião', 'Vigintilião' )

# convert a value < 100 to Portuguese.
def _convert_nn_pt(val):
    if val < 20:
        return to_19_pt[val]
    for (dcap, dval) in ((k, 20 + (10 * v)) for (v, k) in enumerate(tens_pt)):
        if dval + 10 > val:
            if val % 10:
                return dcap + ' e ' + to_19_pt[val % 10]
            return dcap

# convert a value < 1000 to portuguese, special cased because it is the level that kicks 
# off the < 100 special case.  The rest are more general.  This also allows you to
# get strings in the form of 'forty-five hundred' if called directly.
def _convert_nnn_pt(val):
    word = ''
    (mod, rem) = (val % 100, val // 100)
    if rem > 0:
        if rem in[1,2,3,4,5,6,7,8,9] and mod == 0:
            if rem == 1:
                word = 'Cem'
            else:
                word = cent_pt [rem-1] #'Cem'
        else:
            word = cent_pt [rem-1] #to_19_pt[rem] + ' Cento'
            
        if mod > 0:
            word = word + ' e '
    if mod > 0:
        word = word + _convert_nn_pt(mod)
    return word

def portuguese_number(val):
    if val < 100:
        return _convert_nn_pt(val)
    if val < 1000:
         return _convert_nnn_pt(val)
    for (didx, dval) in ((v - 1, 1000 ** v) for v in range(len(denom_pt))):
        if dval > val:
            mod = 1000 ** didx
            l = val // mod
            r = val - (l * mod)
            if l == 1 and denom_pt[didx] == 'Mil':
                ret = denom_pt[didx]
            else:
                ret = _convert_nnn_pt(l) + ' ' + denom_pt[didx]    
            if r > 0:
                ret = ret + ', ' + portuguese_number(r)
            return ret

def amount_to_text_pt(number, currency):
    number = '%.2f' % number
    units_name = currency
    list = str(number).split('.')
    start_word = portuguese_number(abs(int(list[0])))
    end_word = portuguese_number(int(list[1]))
    cents_number = int(list[1])
    cents_name = (cents_number > 1) and ' e Cents' or ' e Cent'
    final_result = start_word +' '+units_name 
    return final_result

def amount_text(amount):
    moeda = amount_to_text_pt(int(amount),'escudos')
    return  moeda


class PaymentReceiptReport(models.AbstractModel):
    _name = 'report.account_payment_receipt_prime.report_payment_receipt2'


    def get_bom_variant_name(self, product_id=False):
        if product_id:
            name = product_id.name_get()[0][1]
            if ']' in name:
                idx = name.index(']')
                return name[idx+1:]
            return name
        return ''

    def get_amount(self, amount=0.0):
        amount = str(SeparaCommas(amount))
        return amount

    def get_amount_in_words(self, amount=0.0):
        amount_in_words = str(amount_text(amount))
        return amount_in_words or '-'

    @api.multi
    def render_html(self, docids, data=None):
        docargs = {
            'doc_ids': docids,
            'doc_model': 'account.payment',
            'docs': self.env['account.payment'].browse(docids),
            'get_amount': self.get_amount,
            'get_amount_in_words': self.get_amount_in_words,
            'data': data,
        }
        return self.env['report'].render('account_payment_receipt_prime.report_payment_receipt2', docargs)
