/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (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.apache.org/licenses/LICENSE-2.0
 *
 * 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 org.apache.commons.sanselan.icc;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import org.apache.commons.sanselan.ImageReadException;

public class IccProfileInfo implements IccConstants
{

    public final byte data[];
    public final int ProfileSize;
    public final int CMMTypeSignature;
    public final int ProfileVersion;
    public final int ProfileDeviceClassSignature;
    public final int ColorSpace;
    public final int ProfileConnectionSpace;
    public final int ProfileFileSignature;
    public final int PrimaryPlatformSignature;
    public final int VariousFlags;
    public final int DeviceManufacturer;
    public final int DeviceModel;
    public final int RenderingIntent;
    public final int ProfileCreatorSignature;
    public final byte ProfileID[];
    public final IccTag tags[];

    public IccProfileInfo(byte data[], int ProfileSize, int CMMTypeSignature,
            int ProfileVersion, int ProfileDeviceClassSignature,
            int ColorSpace, int ProfileConnectionSpace,
            int ProfileFileSignature, int PrimaryPlatformSignature,
            int VariousFlags, int DeviceManufacturer, int DeviceModel,
            int RenderingIntent, int ProfileCreatorSignature, byte ProfileID[],
            IccTag tags[])
    {
        this.data = data;

        this.ProfileSize = ProfileSize;
        this.CMMTypeSignature = CMMTypeSignature;
        this.ProfileVersion = ProfileVersion;
        this.ProfileDeviceClassSignature = ProfileDeviceClassSignature;
        this.ColorSpace = ColorSpace;
        this.ProfileConnectionSpace = ProfileConnectionSpace;
        this.ProfileFileSignature = ProfileFileSignature;
        this.PrimaryPlatformSignature = PrimaryPlatformSignature;
        this.VariousFlags = VariousFlags;
        this.DeviceManufacturer = DeviceManufacturer;
        this.DeviceModel = DeviceModel;
        this.RenderingIntent = RenderingIntent;
        this.ProfileCreatorSignature = ProfileCreatorSignature;
        this.ProfileID = ProfileID;

        this.tags = tags;
    }

    public boolean issRGB()
    {
        boolean result = ((DeviceManufacturer == IEC) && (DeviceModel == sRGB));
        return result;
    }

    private void printCharQuad(PrintWriter pw, String msg, int i)
    {
        pw.println(msg + ": '" + (char) (0xff & (i >> 24))
                + (char) (0xff & (i >> 16)) + (char) (0xff & (i >> 8))
                + (char) (0xff & (i >> 0)) + "'");
    }

    public void dump(String prefix)
    {
        System.out.print(toString());
    }

    @Override
    public String toString()
    {
        try
        {
            return toString("");
        }
        catch (Exception e)
        {
            return "IccProfileInfo: Error";
        }
    }

    public String toString(String prefix) throws ImageReadException,
            IOException
    {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);

        //        StringBuffer result = new StringBuffer();
        pw.println(prefix + ": " + "data length: " + data.length);

        printCharQuad(pw, prefix + ": " + "ProfileDeviceClassSignature",
                ProfileDeviceClassSignature);

        printCharQuad(pw, prefix + ": " + "CMMTypeSignature", CMMTypeSignature);

        printCharQuad(pw, prefix + ": " + "ProfileDeviceClassSignature",
                ProfileDeviceClassSignature);
        printCharQuad(pw, prefix + ": " + "ColorSpace", ColorSpace);
        printCharQuad(pw, prefix + ": " + "ProfileConnectionSpace",
                ProfileConnectionSpace);

        printCharQuad(pw, prefix + ": " + "ProfileFileSignature",
                ProfileFileSignature);

        printCharQuad(pw, prefix + ": " + "PrimaryPlatformSignature",
                PrimaryPlatformSignature);

        printCharQuad(pw, prefix + ": " + "ProfileFileSignature",
                ProfileFileSignature);

        printCharQuad(pw, prefix + ": " + "DeviceManufacturer",
                DeviceManufacturer);

        printCharQuad(pw, prefix + ": " + "DeviceModel", DeviceModel);

        printCharQuad(pw, prefix + ": " + "RenderingIntent", RenderingIntent);

        printCharQuad(pw, prefix + ": " + "ProfileCreatorSignature",
                ProfileCreatorSignature);

        for (int i = 0; i < tags.length; i++)
        {
            IccTag tag = tags[i];
            tag.dump(pw, "\t" + i + ": ");
        }

        pw.println(prefix + ": " + "issRGB: " + issRGB());
        pw.flush();

        return sw.getBuffer().toString();
    }

}