/*!
  Creates a input tag with type="image" and src=\a "src". The \a src must
  be one of URL, a absolute path or a relative path. If \a src is a relative
  path, it must exist in the public/images directory.
*/
QString TViewHelper::submitImageTag(const QString &src, const THtmlAttribute &attributes) const
{
    THtmlAttribute attr = attributes;
    attr.prepend("src", imagePath(src));
    attr.prepend("type", "image");
    return selfClosingTag("input", attr);
}
/*!
  Creates a input tag with type="reset" and value=\a "value".
*/
QString TViewHelper::resetTag(const QString &value, const THtmlAttribute &attributes) const
{
    THtmlAttribute attr = attributes;
    attr.prepend("value", value);
    attr.prepend("type", "reset");
    return selfClosingTag("input", attr);
}
/*!
  Creates a \<textarea\> text area tag with name=\a "name", rows=\a "rows"
  and cols=\a "cols".
*/
QString TViewHelper::textAreaTag(const QString &name, int rows, int cols, const QString &content, const THtmlAttribute &attributes) const
{
    THtmlAttribute attr = attributes;
    attr.prepend("cols", QString::number(cols));
    attr.prepend("rows", QString::number(rows));
    attr.prepend("name", name);
    return tag("textarea", attr, content);
}
/*!
  Creates a \<script\> script tag with src=\a "src". The \a src must
  be one of URL, a absolute path or a relative path. If \a src is a
  relative path, it must exist in the public/js directory.
*/
QString TViewHelper::scriptTag(const QString &src, bool withTimestamp, const THtmlAttribute &attributes) const
{
    THtmlAttribute attr = attributes;
    if (!attr.contains("type")) {
        attr.prepend("type", "text/javascript");
    }
    attr.prepend("src", jsPath(src, withTimestamp));
    return tag("script", attr, QString());
}
/*!
  Creates a select tag with name=\a "name".
 */
QString TViewHelper::selectTag(const QString &name, int size, bool multiple, const THtmlAttribute &attributes) const
{
    THtmlAttribute attr = attributes;
    attr.prepend("size", QString::number(size));
    attr.prepend("name", name);

    if (multiple)
        attr.prepend("multiple", QString());

    return tag("select", attr, QString());
}
/*!
  Creates a \<input\> input tag with type=\a "type", name=\a "name" and
  value=\a "value".
*/
QString TViewHelper::inputTag(const QString &type, const QString &name, const QVariant &value,
                              const THtmlAttribute &attributes) const
{
    THtmlAttribute attr = attributes;
    if (!value.isNull()) {
        attr.prepend("value", value.toString());
    }
    attr.prepend("name", name);
    attr.prepend("type", type);
    return selfClosingTag("input", attr);
}
/*!
  Creates a \<link\> link tag for a style sheet with href=\a "src". The
  \a src must be one of URL, a absolute path or a relative path. If \a src
  is a relative path, it must exist in the public/css directory.
*/
QString TViewHelper::styleSheetTag(const QString &src, bool withTimestamp, const THtmlAttribute &attributes) const
{
    THtmlAttribute attr = attributes;
    if (!attr.contains("type")) {
        attr.prepend("type", "text/css");
    }
    if (!attr.contains("rel")) {
        attr.prepend("rel", "stylesheet");
    }
    attr.prepend("href", cssPath(src, withTimestamp));
    return selfClosingTag("link", attr);
}
/*!
  Creates a option tag for a select tag;
 */
QString TViewHelper::optionTag(const QString &text, const QVariant &value, bool selected,
                               const THtmlAttribute &attributes) const
{
    QString ret;
    THtmlAttribute attr = attributes;

    if (selected)
        attr.prepend("selected", QString());

    attr.prepend("value", value.toString());
    return tag("option", attr, text);
}
/*!
  Creates option tags for a select tag;
 */
QString TViewHelper::optionTags(const QList<QPair<QString, QVariant>> &valueList, const QVariant &selectedValue, const THtmlAttribute &attributes) const
{
    QString ret;
    THtmlAttribute attr = attributes;

    for (auto &val : valueList) {
        if (!val.second.isNull() && val.second == selectedValue) {
            attr.prepend("selected", QString());
        }
        attr.prepend("value", val.second.toString());
        ret += tag("option", attr, val.first);
        attr = attributes;
    }
    return ret;
}
/*!
  Creates option tags for a select tag;
  The option tag which value is equal to \a selectedValue parameter is selected.
 */
QString TViewHelper::optionTags(const QStringList &valueList, const QVariant &selectedValue, const THtmlAttribute &attributes) const
{
    QString ret;
    THtmlAttribute attr = attributes;

    for (auto &val : valueList) {
        if (!val.isEmpty() && val == selectedValue) {
            attr.prepend("selected", QString());
        }
        attr.prepend("value", val);
        ret += tag("option", attr, val);
        attr = attributes;
    }
    return ret;
}
/*!
  Creates a input tag (type="button") whose onclick handler triggers
  the passed JavaScript.
*/
QString TViewHelper::buttonToFunction(const QString &text, const QString &function,
                                      const THtmlAttribute &attributes) const
{
    QString onclick = function.trimmed();
    if (!onclick.isEmpty() && !onclick.endsWith(";")) {
        onclick += QLatin1Char(';');
    }
    onclick += QLatin1String(" return false;");

    THtmlAttribute attr = attributes;
    attr.prepend("onclick", onclick);
    attr.prepend("value", text);
    attr.prepend("type", "button");
    return selfClosingTag("input", attr);
}
/*!
  Creates a \<img\> image tag with src=\a "src". The \a src must be one
  of URL, a absolute path or a relative path. If \a src is a relative path,
  it must exist in the public/images directory. If \a withTimestamp is
  true, the timestamp of the image file is append to \a src as a query
  parameter.
*/
QString TViewHelper::imageTag(const QString &src, bool withTimestamp,
                              const QSize &size, const QString &alt,
                              const THtmlAttribute &attributes) const
{
    THtmlAttribute attr = attributes;
    if (!alt.isEmpty()) {
        attr.prepend("alt", alt);
    } else {
        attr.prepend("alt", "");  // output 'alt' always
    }

    if (size.height() > 0) {
        attr.prepend("height", QString::number(size.height()));
    }
    if (size.width() > 0) {
        attr.prepend("width", QString::number(size.width()));
    }

    attr.prepend("src", imagePath(src, withTimestamp));
    return selfClosingTag("img", attr);
}
QString TViewHelper::inlineImageTag(const QByteArray &data, const QString &mediaType,
                                    const QSize &size, const QString &alt,
                                    const THtmlAttribute &attributes) const
{
    THtmlAttribute attr = attributes;
    if (!alt.isEmpty()) {
        attr.prepend("alt", alt);
    } else {
        attr.prepend("alt", "");  // output 'alt' always
    }

    if (size.height() > 0) {
        attr.prepend("height", QString::number(size.height()));
    }
    if (size.width() > 0) {
        attr.prepend("width", QString::number(size.width()));
    }

    QByteArray dataUrl = "data:";
    dataUrl += mediaType.toLatin1() + ";base64,";
    dataUrl += data.toBase64();
    attr.prepend("src", dataUrl);
    return selfClosingTag("img", attr);
}