/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */

package com.queplix.core.modules.mail;

import com.queplix.core.modules.jeo.gen.AttachmentObject;
import com.queplix.core.modules.jeo.gen.AttachmentTempObject;
import com.queplix.core.utils.FileHelper;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;

/**
 * E-mail attachment value object.
 *
 * @author [ONZ] Oleg N. Zhovtanyuk
 * @author [ALB] Baranov Andrey
 * @version $Revision: 1.4 $ $Date: 2006/01/27 17:58:31 $
 */

public class Attachment
        implements Serializable {

    // ================================================================== Fields

    private final String filename;
    private final File file;
    private byte[] data;
    private String filetype; // content type

    private boolean loaded = false;

    // ========================================================== Initialization

    /**
     * Constructor-copy.
     *
     * @param obj AttachmentObject
     */
    public Attachment(AttachmentObject obj) {
        this(obj.getFilename(), obj.getData());
        setFiletype(obj.getFiletype());
    }

    /**
     * Constructor-copy.
     *
     * @param obj AttachmentTempObject
     */
    public Attachment(AttachmentTempObject obj) {
        this(obj.getFilename(), obj.getData());
        setFiletype(obj.getFiletype());
    }

    /**
     * Creates a new atachment VO.
     *
     * @param filename file name
     * @param data     binary data
     */
    public Attachment(String filename, byte[] data) {
        this.filename = filename;
        this.file = null;
        this.data = data;
        this.loaded = true;
    }

    /**
     * Creates a new atachment VO from file.
     *
     * @param file file to make attachment from
     * @throws IOException
     */
    public Attachment(File file)
            throws IOException {
        this(file, null);
    }

    /**
     * Creates a new atachment VO from file.
     *
     * @param file     file to make attachment from
     * @param filename attachment name (if differ from the file name)
     * @throws IOException
     */
    public Attachment(File file, String filename)
            throws IOException {

        // Check file size.
        long length = file.length();
        if(length > Integer.MAX_VALUE) {
            throw new IOException(
                    "File '" + file + "' is too large to attach.");
        }

        // Set file name and file.
        this.filename = (filename != null) ? filename:file.getName();
        this.file = file;
    }

    // ========================================================== Access methods

    /**
     * Get file data.
     *
     * @return byte[]
     * @throws IOException
     */
    public byte[] getData()
            throws IOException {

        if(data == null && file != null) {
            // Read data - lazy loading
            data = FileHelper.loadFile(file);
        }

        // Set 'loaded' flag to true
        loaded = true;

        return data;
    }

    /**
     * 'Data Loaded' flag getter.
     *
     * @return boolean
     */
    public boolean isLoaded() {
        return loaded;
    }

    /**
     * Get file name.
     *
     * @return String
     */
    public String getFilename() {
        return filename;
    }

    /**
     * Get file.
     *
     * @return File
     */
    public File getFile() {
        return file;
    }

    /**
     * Get file type.
     *
     * @return String
     */
    public String getFiletype() {
        return filetype;
    }

    /**
     * Set file type.
     *
     * @param filetype String
     */
    public void setFiletype(String filetype) {
        this.filetype = filetype;
    }
}
