// $Id: LinkReference.java,v 1.6 2004/02/27 16:29:56 m31 Exp $
//
// This file is part of the program suite "Principia Mathematica II"
// which is a working prototype for the main project:
// "Hilbert II" - http://www.qedeq.org
//
// Copyright 2001-2004  Michael Meyling <mime@qedeq.org>.
//
// "Principia Mathematica II" 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.
//
// 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
// GNU General Public License for more details.

package com.meyling.principia.logic.rule;


import com.meyling.principia.argument.AbstractArgumentList;
import com.meyling.principia.argument.Argument;
import com.meyling.principia.argument.ArgumentException;
import com.meyling.principia.argument.Text;
import com.meyling.principia.module.ModuleConstants;


/**
 * A reference label.
 *
 * @version $Revision: 1.6 $
 * @author  Michael Meyling
 */
public class LinkReference extends AbstractArgumentList
        implements Argument {


    /** reference */
    private final String reference;


    /**
     * Constructs a reference label.
     *
     * @param   arguments    {@link Text} to be a label
     * @throws  ArgumentException    if there is not exactly one
     *          argument or the first argument is not an instance
     *          of {@link Text} or it isn't build of lowercase letters,
     *          digits and periods like in &quot;abc1.d2.efg&quot;.
     */
    public LinkReference(final Argument[] arguments)
            throws ArgumentException {
        super(arguments);

        if (arguments.length != 1) {
            throw new ArgumentException(
                ModuleConstants.CODE_CONSTRUCTOR_WRONG_ARGUMENT_NUMBER,
                RuleCreator.getName(this.getClass())
                + ModuleConstants.OPERATOR_WITH_ONE_ARGUMENT);
        }
        if (!(arguments[0] instanceof Text)) {
            throw new ArgumentException(
                ModuleConstants.CODE_CONSTRUCTOR_WRONG_ARGUMENT_TYPE,
                RuleCreator.getName(this.getClass())
                + ModuleConstants.FIRST_ARGUMENT_TYPE
                + ModuleConstants.QUOTED_STRING,
                arguments[0]);
        }
        reference = ((Text) arguments[0]).getText();
        if (reference.length() == 0) {
            throw new ArgumentException(
                ModuleConstants.CODE_CONSTRUCTOR_WRONG_ARGUMENT_TYPE,
                RuleCreator.getName(this.getClass())
                + ModuleConstants.NO_EMPTY_STRING,
                arguments[0]);
        }
        if (!reference.toLowerCase().equals(reference)) {
            throw new ArgumentException(
                ModuleConstants.CODE_CONSTRUCTOR_WRONG_ARGUMENT_TYPE,
                RuleCreator.getName(this.getClass())
                + ModuleConstants.ONLY_LOWER_CASE_CHARS,
                arguments[0]);
        }
        boolean begin = true;
        for (int i = 0; i < reference.length(); i++) {
            if (begin) {
                if (!Character.isLetter(reference.charAt(i))) {
                    throw new ArgumentException(
                        ModuleConstants.CODE_CONSTRUCTOR_WRONG_ARGUMENT_TYPE,
                        RuleCreator.getName(this.getClass())
                        + ModuleConstants.PART_MUST_START_WITH_LETTER,
                        arguments[0]);
                }
                begin = false;
            }
            if (!Character.isLetterOrDigit(reference.charAt(i))) {
                if (reference.charAt(i) != '.') {
                    throw new ArgumentException(
                        ModuleConstants.CODE_CONSTRUCTOR_WRONG_ARGUMENT_TYPE,
                        RuleCreator.getName(this.getClass())
                        + ModuleConstants.MUST_BE_LETTER_DIGIT_PERIOD_STRING,
                        arguments[0]);
                } else if (i + 1 < reference.length()) {
                    begin = true;   // new part begins
                    if (reference.charAt(i + 1) == '.') {
                        throw new ArgumentException(
                            ModuleConstants.CODE_CONSTRUCTOR_WRONG_ARGUMENT_TYPE,
                            RuleCreator.getName(this.getClass())
                            + ModuleConstants.NO_DIRECT_PERIODS,
                            arguments[0]);
                    }
                } else {
                    throw new ArgumentException(
                        ModuleConstants.CODE_CONSTRUCTOR_WRONG_ARGUMENT_TYPE,
                        RuleCreator.getName(this.getClass())
                        + ModuleConstants.MUST_NOT_END_WITH_PERIOD,
                        arguments[0]);
                }
            }
        }
    }


    /** @inherited */
    public final String getReference() {
        return reference;
    }


    /** @inherited */
    public final Argument create(final Argument[] arguments)
            throws ArgumentException {
        return new LinkReference(arguments);
    }


    /** @inherited */
    public final String toString() {
        return "Reference " + getArgument(0).toString();
    }


}
