/*
 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
 *  Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
 *  Copyright (C) 2009 Torch Mobile, Inc.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library 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 GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "config.h"
#include "RegExpConstructor.h"

#include "Error.h"
#include "RegExpMatchesArray.h"
#include "RegExpPrototype.h"

namespace JSC {

static JSValue regExpConstructorInput(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorMultiline(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorLastMatch(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorLastParen(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorLeftContext(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorRightContext(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorDollar1(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorDollar2(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorDollar3(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorDollar4(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorDollar5(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorDollar6(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorDollar7(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorDollar8(ExecState*, JSValue, PropertyName);
static JSValue regExpConstructorDollar9(ExecState*, JSValue, PropertyName);

static void setRegExpConstructorInput(ExecState*, JSObject*, JSValue);
static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValue);

} // namespace JSC

#include "RegExpConstructor.lut.h"

namespace JSC {

const ClassInfo RegExpConstructor::s_info = { "Function", InternalFunction::s_classinfo(), 0, ExecState::regExpConstructorTable, CREATE_METHOD_TABLE(RegExpConstructor) };

/* Source for RegExpConstructor.lut.h
@begin regExpConstructorTable
    input           regExpConstructorInput          None
    $_              regExpConstructorInput          DontEnum
    multiline       regExpConstructorMultiline      None
    $*              regExpConstructorMultiline      DontEnum
    lastMatch       regExpConstructorLastMatch      DontDelete|ReadOnly
    $&              regExpConstructorLastMatch      DontDelete|ReadOnly|DontEnum
    lastParen       regExpConstructorLastParen      DontDelete|ReadOnly
    $+              regExpConstructorLastParen      DontDelete|ReadOnly|DontEnum
    leftContext     regExpConstructorLeftContext    DontDelete|ReadOnly
    $`              regExpConstructorLeftContext    DontDelete|ReadOnly|DontEnum
    rightContext    regExpConstructorRightContext   DontDelete|ReadOnly
    $'              regExpConstructorRightContext   DontDelete|ReadOnly|DontEnum
    $1              regExpConstructorDollar1        DontDelete|ReadOnly
    $2              regExpConstructorDollar2        DontDelete|ReadOnly
    $3              regExpConstructorDollar3        DontDelete|ReadOnly
    $4              regExpConstructorDollar4        DontDelete|ReadOnly
    $5              regExpConstructorDollar5        DontDelete|ReadOnly
    $6              regExpConstructorDollar6        DontDelete|ReadOnly
    $7              regExpConstructorDollar7        DontDelete|ReadOnly
    $8              regExpConstructorDollar8        DontDelete|ReadOnly
    $9              regExpConstructorDollar9        DontDelete|ReadOnly
@end
*/

RegExpConstructor::RegExpConstructor(JSGlobalObject* globalObject, Structure* structure, RegExpPrototype* regExpPrototype)
    : InternalFunction(globalObject, structure)
    , m_cachedResult(globalObject->globalData(), this, regExpPrototype->regExp())
    , m_multiline(false)
{
}

void RegExpConstructor::finishCreation(ExecState* exec, RegExpPrototype* regExpPrototype)
{
    Base::finishCreation(exec->globalData(), Identifier(exec, "RegExp").string());
    ASSERT(inherits(&s_info));

    // ECMA 15.10.5.1 RegExp.prototype
    putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, regExpPrototype, DontEnum | DontDelete | ReadOnly);

    // no. of arguments for constructor
    putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
}

void RegExpConstructor::destroy(JSCell* cell)
{
    static_cast<RegExpConstructor*>(cell)->RegExpConstructor::~RegExpConstructor();
}

void RegExpConstructor::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
    RegExpConstructor* thisObject = jsCast<RegExpConstructor*>(cell);
    ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());

    Base::visitChildren(thisObject, visitor);
    thisObject->m_cachedResult.visitChildren(visitor);
}

JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i)
{
    RegExpMatchesArray* array = m_cachedResult.lastResult(exec, this);

    if (i < array->length()) {
        JSValue result = JSValue(array).get(exec, i);
        ASSERT(result.isString() || result.isUndefined());
        if (!result.isUndefined())
            return result;
    }
    return jsEmptyString(exec);
}

JSValue RegExpConstructor::getLastParen(ExecState* exec)
{
    RegExpMatchesArray* array = m_cachedResult.lastResult(exec, this);
    unsigned length = array->length();
    if (length > 1) {
        JSValue result = JSValue(array).get(exec, length - 1);
        ASSERT(result.isString() || result.isUndefined());
        if (!result.isUndefined())
            return result;
    }
    return jsEmptyString(exec);
}

JSValue RegExpConstructor::getLeftContext(ExecState* exec)
{
    return m_cachedResult.lastResult(exec, this)->leftContext(exec);
}

JSValue RegExpConstructor::getRightContext(ExecState* exec)
{
    return m_cachedResult.lastResult(exec, this)->rightContext(exec);
}
    
bool RegExpConstructor::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), jsCast<RegExpConstructor*>(cell), propertyName, slot);
}

bool RegExpConstructor::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), jsCast<RegExpConstructor*>(object), propertyName, descriptor);
}

JSValue regExpConstructorDollar1(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getBackref(exec, 1);
}

JSValue regExpConstructorDollar2(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getBackref(exec, 2);
}

JSValue regExpConstructorDollar3(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getBackref(exec, 3);
}

JSValue regExpConstructorDollar4(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getBackref(exec, 4);
}

JSValue regExpConstructorDollar5(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getBackref(exec, 5);
}

JSValue regExpConstructorDollar6(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getBackref(exec, 6);
}

JSValue regExpConstructorDollar7(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getBackref(exec, 7);
}

JSValue regExpConstructorDollar8(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getBackref(exec, 8);
}

JSValue regExpConstructorDollar9(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getBackref(exec, 9);
}

JSValue regExpConstructorInput(ExecState*, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->input();
}

JSValue regExpConstructorMultiline(ExecState*, JSValue slotBase, PropertyName)
{
    return jsBoolean(asRegExpConstructor(slotBase)->multiline());
}

JSValue regExpConstructorLastMatch(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getBackref(exec, 0);
}

JSValue regExpConstructorLastParen(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getLastParen(exec);
}

JSValue regExpConstructorLeftContext(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getLeftContext(exec);
}

JSValue regExpConstructorRightContext(ExecState* exec, JSValue slotBase, PropertyName)
{
    return asRegExpConstructor(slotBase)->getRightContext(exec);
}

void RegExpConstructor::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
{
    lookupPut<RegExpConstructor, InternalFunction>(exec, propertyName, value, ExecState::regExpConstructorTable(exec), jsCast<RegExpConstructor*>(cell), slot);
}

void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValue value)
{
    asRegExpConstructor(baseObject)->setInput(exec, value.toString(exec));
}

void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValue value)
{
    asRegExpConstructor(baseObject)->setMultiline(value.toBoolean(exec));
}

// ECMA 15.10.4
JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, bool callAsConstructor)
{
    JSValue arg0 = args.at(0);
    JSValue arg1 = args.at(1);

    if (arg0.inherits(RegExpObject::s_classinfo())) {
        if (!arg1.isUndefined())
            return throwError(exec, createTypeError(exec, ASCIILiteral("Cannot supply flags when constructing one RegExp from another.")));
        // If called as a function, this just returns the first argument (see 15.10.3.1).
        if (callAsConstructor) {
            RegExp* regExp = static_cast<RegExpObject*>(asObject(arg0))->regExp();
            return RegExpObject::create(exec, globalObject, globalObject->regExpStructure(), regExp);
        }
        return asObject(arg0);
    }

    String pattern = arg0.isUndefined() ? String("") : arg0.toString(exec)->value(exec);
    if (exec->hadException())
        return 0;

    RegExpFlags flags = NoFlags;
    if (!arg1.isUndefined()) {
        flags = regExpFlags(arg1.toString(exec)->value(exec));
        if (exec->hadException())
            return 0;
        if (flags == InvalidFlags)
            return throwError(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor.")));
    }

    RegExp* regExp = RegExp::create(exec->globalData(), pattern, flags);
    if (!regExp->isValid())
        return throwError(exec, createSyntaxError(exec, regExp->errorMessage()));
    return RegExpObject::create(exec, exec->lexicalGlobalObject(), globalObject->regExpStructure(), regExp);
}

static EncodedJSValue JSC_HOST_CALL constructWithRegExpConstructor(ExecState* exec)
{
    ArgList args(exec);
    return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args, true));
}

ConstructType RegExpConstructor::getConstructData(JSCell*, ConstructData& constructData)
{
    constructData.native.function = constructWithRegExpConstructor;
    return ConstructTypeHost;
}

// ECMA 15.10.3
static EncodedJSValue JSC_HOST_CALL callRegExpConstructor(ExecState* exec)
{
    ArgList args(exec);
    return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args));
}

CallType RegExpConstructor::getCallData(JSCell*, CallData& callData)
{
    callData.native.function = callRegExpConstructor;
    return CallTypeHost;
}

} // namespace JSC
