int BitcoinUnits::decimals(int unit)
{
    if(walletModel && walletModel->getOptionsModel())
    {
        if (walletModel->getOptionsModel()->getDecimalPoints() > maxdecimals(unit))
            return maxdecimals(unit);
        else
            return walletModel->getOptionsModel()->getDecimalPoints();
    }
    else
    {
        return maxdecimals(unit);
    }
}
QString BitcoinUnits::formatFee(int unit, qint64 n, bool fPlus)
{
    // Note: not using straight sprintf here because we do NOT want
    // localized number formatting.
    if(!valid(unit))
        return QString(); // Refuse to format invalid unit
    qint64 coin = factor(unit);
    qint64 n_abs = (n > 0 ? n : -n);
    qint64 quotient = n_abs / coin;
    qint64 remainder = n_abs % coin;
    QString quotient_str = QString("%L1").arg(quotient);
    QString remainder_str = QString::number(remainder).rightJustified(maxdecimals(unit), '0');

    // Right-trim excess zeros after the decimal point
    int nTrim = 0;
    for (int i = remainder_str.size()-1; i>=2 && (remainder_str.at(i) == '0'); --i)
        ++nTrim;
    remainder_str.chop(nTrim);

    if (n < 0)
        quotient_str.insert(0, '-');
    else if (fPlus && n > 0)
        quotient_str.insert(0, '+');

    if (remainder_str.size())
        return quotient_str + QString(".") + remainder_str;
    else
        return quotient_str;
}
QString BitcoinUnits::formatMaxDecimals(int unit, qint64 n, int decimals, bool fPlus, bool fHideAmounts)
{
    // Note: not using straight sprintf here because we do NOT want
    // localized number formatting.
    if(!valid(unit))
        return QString(); // Refuse to format invalid unit
    qint64 coin = factor(unit);
    qint64 n_abs = (n > 0 ? n : -n);
    qint64 quotient = n_abs / coin;
    qint64 remainder = n_abs % coin;
    QString quotient_str = QString("%L1").arg(quotient);
    QString remainder_str = QString::number(remainder).rightJustified(maxdecimals(unit), '0').left(decimals);

    // Pad zeros after remainder up to number of decimals
    for (int i = remainder_str.size(); i < decimals; ++i)
        remainder_str.append("0");

    if(fHideAmounts)
    {
        quotient_str.replace(QRegExp("[0-9]"),"*");
        remainder_str.replace(QRegExp("[0-9]"),"*");
    }

    if (n < 0)
        quotient_str.insert(0, '-');
    else if (fPlus && n > 0)
        quotient_str.insert(0, '+');

    if (remainder_str.size())
        return quotient_str + QString(".") + remainder_str;
    else
        return quotient_str;
}
bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out)
{
    if(!valid(unit) || value.isEmpty())
        return false; // Refuse to parse invalid unit or empty string
    int num_decimals = maxdecimals(unit);
    QStringList parts = value.split(".");

    if(parts.size() > 2)
    {
        return false; // More than one dot
    }
    QString whole = parts[0];
    QString decimals;

    if(parts.size() > 1)
    {
        decimals = parts[1];
    }
    if(decimals.size() > num_decimals)
    {
        return false; // Exceeds max precision
    }
    bool ok = false;
    QString str = whole + decimals.leftJustified(num_decimals, '0');

    if(str.size() > 18)
    {
        return false; // Longer numbers will exceed 63 bits
    }
    qint64 retvalue = str.toLongLong(&ok);
    if(val_out)
    {
        *val_out = retvalue;
    }
    return ok;
}
// draw the chartchartheight
void
QTAChartCore::draw (void)
{
  QWidget *gqw;
  QTACObject *object, *delobject;
  
  if (Q_UNLIKELY (!tfinit))
  {
	QString title;  
	createTFButtons ();  
	HLOC = &TIMEFRAME[0].HLOC;
    HEIKINASHI = &TIMEFRAME[0].HEIKINASHI; 
    startbar = &TIMEFRAME[0].TFStartBar;
    excess_drag_width = &TIMEFRAME[0].TFExcess_Drag_Width;
    title = Symbol + " - " + TIMEFRAME[0].TFName;
    currenttf = TIMEFRAME[0].TFName;
    setTitle (title, QString::fromUtf8 (subtitletext));
    tfinit = true;
  }  
  
  // collect garbage objects
  do
  { 
	delobject = NULL;  
    foreach (object, Object)
      if (object->deleteit)
        delobject = object;
  
    if (delobject != NULL)
      deleteObject (delobject);
  }
  while (delobject != NULL);
  
  
  // collect garbase QWidgets
  if (garbageQWidget.size () > 0)
  {
	gqw = garbageQWidget[0];
	gqw->deleteLater ();
	garbageQWidget.remove (0); 
  }
  
  if (reloaded)
  {
    points = maxdecimals (HLOC);
    decimals = qCeil (qAbs (qLog10 (points)));
    OPEN.clear ();
    CLOSE.clear ();
    HIGH.clear ();
    LOW.clear ();
    VOLUME.clear ();
    foreach (const QTAChartFrame &frame, *HLOC)
    {
      OPEN += frame.Open;
      CLOSE += frame.Close;
      HIGH += frame.High;
      LOW += frame.Low;
      VOLUME += frame.Volume;
    }
    reloaded = false;
  }

  // geometry
  geom (this);
  
  // draw the objects
  foreach (object, Object)
    object->draw ();
  
  // draw the chart frame, grid, bottom text 
  ruller_cursor_x = chartrightmost + 2;
  ruller_cursor->setPos (ruller_cursor_x, ruller_cursor_y);
  bottom_text->setPos (chartleftmost, height - (bottomline_height + 5));

  topedge->setLine (chartleftmost, charttopmost, chartrightmost + 3, charttopmost);
  bottomedge->setLine (chartleftmost, chartbottomost + 5, width, chartbottomost + 5);
  rightedge->setLine (chartrightmost + 3, 0, chartrightmost + 3, height);
  leftedge->setLine (chartleftmost, 0, chartleftmost, height);
  
  if (show_grid)
    drawGRID ();
  else
    clearGRID ();
      
  if (linear)
    scaletitle->setPlainText ("Linear");
  else  
    scaletitle->setPlainText ("Logarithmic");
    
  if (chart_style == QTACHART_CANDLE)
  {
    typetitle->setPlainText ("Candle");
    drawCandleChart ();
  }  
  else  if (chart_style == QTACHART_HEIKINASHI)  
  {
    typetitle->setPlainText ("Heikin-Ashi");
    drawCandleChart ();
  }  
  else if (chart_style == QTACHART_BAR)
  {
    typetitle->setPlainText ("Bar");
    drawBarChart ();
  }  
  else if (chart_style == QTACHART_LINE)
  {
    typetitle->setPlainText ("Line");
    drawPriceLine (linecolor, linethickness);
  }  
  
  clearITEMS ();
  setRullerCursor (ruller_cursor_y);
}