/*
 Copyright (C) 2003 Niels Elken Sønderby

 This file is part of QuantLib for Mathematica, a Mathematica extension for
 QuantLib, a free-software/open-source financial C++ library
 http://www.nielses.dk/quantlib/mma
 http://quantlib.org/

 QuantLib for Mathematica is free software: you can redistribute it and/or
 modify it under the terms of the QuantLib license.  You should have received
 a copy of the license along with this program; if not, please email
 ferdinando@ametrano.net The license is also available online at
 http://quantlib.org/html/license.html

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

#include "qlmma.hpp"

void QLMLSignalError(const char* errorMsg, bool returnFailed)
{
    MLNewPacket(stdlink);
    MLPutFunction(stdlink, "EvaluatePacket", 1);
    MLPutFunction(stdlink, "Message", 2);
    MLPutFunction(stdlink, "MessageName", 2);
    MLPutSymbol(stdlink, "QuantLibMma");
    MLPutString(stdlink, "error");
    MLPutString(stdlink, errorMsg);
    MLEndPacket(stdlink);
    MLAnswer(stdlink);
//    MLNewPacket(stdlink); // Is this neccessary?
    if (returnFailed) {
        MLPutSymbol( stdlink, "$Failed");
    }
}

void QLMLSignalError(const std::exception& e, bool returnFailed)
{
    QLMLSignalError(e.what(), returnFailed);
}

void QLMLPutBoolean(MLINK mlp, bool val)
{
    if (val)
        MLPutSymbol(mlp, "True");
    else
        MLPutSymbol(mlp, "False");
}

void QLMLPutDate(MLINK mlp, Date date)
{
    MLPutFunction(stdlink, "List", 3);
    MLPutInteger(stdlink, date.year());
    MLPutInteger(stdlink, date.month());
    MLPutInteger(stdlink, date.dayOfMonth());
}

void QLMLPutRule(MLINK mlp, const char* symbol, double value)
{
    MLPutFunction(stdlink, "Rule", 2);
    MLPutSymbol(stdlink, symbol);
    MLPutReal(stdlink, value);
}

Handle<TermStructure> makeFlatCurve(double forward) {
    Date today = Date::todaysDate();
    Calendar calendar = TARGET();
    Date reference = calendar.advance(today,2,Days);
    return Handle<TermStructure>(
        new FlatForward(today,reference,
                        forward,Actual365()));
}

Handle<BlackVolTermStructure> makeFlatVolatility(double volatility) {
    Date today = Date::todaysDate();
    Calendar calendar = TARGET();
    Date reference = calendar.advance(today,2,Days);
    return Handle<BlackVolTermStructure>(
        new BlackConstantVol(reference, volatility, Actual365()));
}

