package com.atlassian.uwc.converters;

import java.util.Properties;

import org.apache.log4j.Logger;

import com.atlassian.uwc.converters.twiki.JavaRegexAndTokenizerConverter;
import com.atlassian.uwc.ui.ConverterErrors;
import com.atlassian.uwc.ui.Page;
import com.atlassian.uwc.ui.listeners.FeedbackHandler;

/**
 * An abstract base class to hold the key and value fields.
 * This gets rid of some duplicated code.
 * The key and value fields are usually not used by the converters.
 *
 * To create a new converter type extend this class. If the class
 * is a new type of regular expression engine then add the appropriate
 * code to instantiate it in ConverterEngine.getConverterFromString()
 *
 * @author Rex (Rolf Staflin)
 * @version $Id$
 */
public abstract class BaseConverter implements Converter, FeedbackHandler {

    /**
     * converter string key as defined in converter properties file
     */
    String key;
    /**
     * converter string value as defined in converter properties file
     */
    String value;
    /**
     * attachment directory as provided by user in Attachments textfield of gui.
     */
    String attachmentDirectory;
    /**
     * object containing errors encountered by converter that will be
     * communicated back to the user via the Feedback Framework
     */
    ConverterErrors errors = new ConverterErrors();
    /**
     * logging object - sends logs to console and uwc.log
     */
    Logger log = Logger.getLogger("BaseConverter");
    /**
     * contains miscellaneous properties passed in by the ConverterEngine when
     * the converter is created
     */
    Properties properties = new Properties();
    
    
    /**
     * @return gets the attachment directory setting the user provides via the 
     * Attachments textfield in the GUI
     */
    protected String getAttachmentDirectory() {
    	return this.attachmentDirectory;
    }
	public void setAttachmentDirectory(String attachmentDirectory) {
		this.attachmentDirectory = attachmentDirectory;
	}

	public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String toString() {
        return "[" + this.getClass().getSimpleName() + ": " + key + "=" + value + "]";
    }
    
    /** 
     * Get the errors generated by the conversion
     * @see com.atlassian.uwc.converters.Converter#getErrors()
     */
    public ConverterErrors getErrors() {
    	return this.errors;
    }
    
    /**
     * adds an error to the error list.
     * @param type type of feedback. Usually an error. 
     * If OK, will not count as an error, but will be considered a status message.
     * @param note description of feedback. This is where you explain what actually happened. 
     * @param isFeedbackWindowMessage if true, will be displayed in the feedback window.
     * This should usually be true.
     */
    public void addError(Feedback type, String note, boolean isFeedbackWindowMessage) {
    	this.errors.addError(type, note, isFeedbackWindowMessage);
    }

    public Properties getProperties() {
    	return this.properties;
    }
    
    public void setProperties(Properties properties) {
    	this.properties = properties;
    }
    
    /**
     * convenience method for tokenizing content within a converter
     * @param input content to be search/replaced 
     * @param value tokenization property value, same as in properties file. Looks like: 
     * (<math>.*?<\\/math>){replace-multiline-with}$1
     * @param type text describing the type of token, used in debug log messages
     * @return tokenized content
     */
    public String tokenize(String input, String value, String type) {
		Converter converter = JavaRegexAndTokenizerConverter.getConverter(value);
		Page page = new Page(null);
		page.setOriginalText(input);
		converter.convert(page);
		if (input != null && !input.equals(page.getConvertedText())) {
			log.debug("Tokenized " + type + " content");
		}
		return page.getConvertedText();
	}
}
