/***************************************************************************
                          scriptfunction.cpp  -  description
                             -------------------
    begin                : Thu Apr 17 2003
    copyright            : (C) 2003 by Jason Harris
    email                : kstars@30doradus.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "scriptfunction.h"

#include <QStringList>
#include <QDebug>

ScriptFunction::ScriptFunction( const QString &name, const QString &desc,
                                bool clockfcn, const QString &at1, const QString &an1,
                                const QString &at2, const QString &an2,
                                const QString &at3, const QString &an3,
                                const QString &at4, const QString &an4,
                                const QString &at5, const QString &an5,
                                const QString &at6, const QString &an6 ) : INDIProp(QString()) {
    Name = name;
    ClockFunction = clockfcn;

    ArgType[0] = at1;  ArgDBusType[0] = DBusType(at1); ArgName[0] = an1;
    ArgType[1] = at2;  ArgDBusType[1] = DBusType(at2); ArgName[1] = an2;
    ArgType[2] = at3;  ArgDBusType[2] = DBusType(at3); ArgName[2] = an3;
    ArgType[3] = at4;  ArgDBusType[3] = DBusType(at4); ArgName[3] = an4;
    ArgType[4] = at5;  ArgDBusType[4] = DBusType(at5); ArgName[4] = an5;
    ArgType[5] = at6;  ArgDBusType[5] = DBusType(at6); ArgName[5] = an6;

    //Construct a richtext description of the function
    QString nameStyle  = "<span style=\"font-family:monospace;font-weight:600\">%1</span>";  //bold
    QString typeStyle  = "<span style=\"font-family:monospace;color:#009d00\">%1</span>";    //green
    QString paramStyle = "<span style=\"font-family:monospace;color:#00007f\">%1</span>";    //blue

    Description =  "<html><head><meta name=\"qrichtext\" content=\"1\" /></head>";
    Description += "<body style=\"font-size:11pt;font-family:sans\">";
    Description += "<p>" + nameStyle.arg( Name + '(' );

    NumArgs = 0;
    if ( ! at1.isEmpty() && ! an1.isEmpty() ) {
        Description += ' ' + typeStyle.arg( at1 );
        Description += ' ' + paramStyle.arg( an1 );
        NumArgs++;
    }

    if ( ! at2.isEmpty() && ! an2.isEmpty() ) {
        Description += ", " + typeStyle.arg( at2 );
        Description += ' ' + paramStyle.arg( an2 );
        NumArgs++;
    }

    if ( ! at3.isEmpty() && ! an3.isEmpty() ) {
        Description += ", " + typeStyle.arg( at3 );
        Description += ' ' + paramStyle.arg( an3 );
        NumArgs++;
    }

    if ( ! at4.isEmpty() && ! an4.isEmpty() ) {
        Description += ", " + typeStyle.arg( at4 );
        Description += ' ' + paramStyle.arg( an4 );
        NumArgs++;
    }

    if ( ! at5.isEmpty() && ! an5.isEmpty() ) {
        Description += ", " + typeStyle.arg( at5 );
        Description += ' ' + paramStyle.arg( an5 );
        NumArgs++;
    }

    if ( ! at6.isEmpty() && ! an6.isEmpty() ) {
        Description += ", " + typeStyle.arg( at6 );
        Description += ' ' + paramStyle.arg( an6 );
        NumArgs++;
    }

    //Set Valid=false if there are arguments (indicates that this fcn's args must be filled in)
    Valid = true;
    if ( NumArgs ) Valid = false;

    //Finish writing function prototype
    if ( NumArgs ) Description += ' ';
    Description += nameStyle.arg( ")" ) + "</p><p>";

    //Add description
    Description += desc;

    //Finish up
    Description += "</p></body></html>";
}

//Copy constructor
ScriptFunction::ScriptFunction( ScriptFunction *sf )
{
    Name = sf->name();
    Description = sf->description();
    ClockFunction = sf->isClockFunction();
    NumArgs = sf->numArgs();
    INDIProp = sf->INDIProperty();
    Valid = sf->valid();

    for ( unsigned int i=0; i<6; i++ ) {
        ArgType[i] = sf->argType(i);
        ArgName[i] = sf->argName(i);
        ArgDBusType[i] = sf->argDBusType(i);
        //ArgVal[i] .clear();
        // JM: Some default argument values might be passed from another object as well
        ArgVal[i]  = sf->argVal(i);
    }
}

ScriptFunction::~ScriptFunction()
{
}

QString ScriptFunction::DBusType(const QString &type)
{

    if (type == QString("int"))
        return QString("int32");
    else if (type == QString("uint"))
        return QString("uint32");
    else if (type == QString("double"))
        return type;
    else if (type == QString("QString"))
        return QString("string");
    else if (type == QString("bool"))
        return QString("boolean");

    return NULL;
}

QString ScriptFunction::prototype() const {
    QString p = Name + '(';

    bool args( false );
    if ( ! ArgType[0].isEmpty() && ! ArgName[0].isEmpty() ) {
        p += ' ' + ArgType[0];
        p += ' ' + ArgName[0];
        args = true; //assume that if any args are present, 1st arg is present
    }

    if ( ! ArgType[1].isEmpty() && ! ArgName[1].isEmpty() ) {
        p += ", " + ArgType[1];
        p += ' ' + ArgName[1];
    }

    if ( ! ArgType[2].isEmpty() && ! ArgName[2].isEmpty() ) {
        p += ", " + ArgType[2];
        p += ' ' + ArgName[2];
    }

    if ( ! ArgType[3].isEmpty() && ! ArgName[3].isEmpty() ) {
        p += ", " + ArgType[3];
        p += ' ' + ArgName[3];
    }

    if ( ! ArgType[4].isEmpty() && ! ArgName[4].isEmpty() ) {
        p += ", " + ArgType[4];
        p += ' ' + ArgName[4];
    }

    if ( ! ArgType[5].isEmpty() && ! ArgName[5].isEmpty() ) {
        p += ", " + ArgType[5];
        p += ' ' + ArgName[5];
    }

    if ( args ) p += ' ';
    p += ')';

    return p;
}

QString ScriptFunction::scriptLine() const {
    QString out( Name );
    QString dbus_type;
    unsigned int i=0;

    while ( ! ArgName[i].isEmpty() && i < 6 )
    {
        //Make sure strings are quoted
        QString value = ArgVal[i];
        if ( ArgDBusType[i] == "string" ) {
            if ( value.isEmpty() ) {
                value = "\"\"";
            } else {
                if ( value.left(1) != "\"" && value.left(1) != "\'" ) {
                    value = '\"' + value;
                }
                if ( value.right(1) != "\"" && value.right(1) != "\'" ) {
                    value =  value + '\"';
                }
            }
        }

        // Write DBus style prototype compatible with dbus-send format
        out += ' ' + ArgDBusType[i] + ':' + value;
        ++i;
    }

    return out;
}
