/*
 * ImageEntry.cs
 * Copyright (c) 2007-2009 kbinani
 *
 * This file is part of LipSync.
 *
 * LipSync is free software; you can redistribute it and/or
 * modify it under the terms of the BSD License.
 *
 * LipSync 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.
 */
using System;
using System.Drawing;
using System.Runtime.Serialization;
using System.Xml.Serialization;

namespace LipSync {

    [Serializable]
    public class ImageEntry : IComparable<ImageEntry>, ICloneable {
        [XmlElement("Title")]
        public string title;
        [XmlIgnore]
        Image image;
        [XmlElement("Tag")]
        public string tag;
        [OptionalField]
        bool is_default;
        [OptionalField, XmlIgnore]
        int xoffset;
        [OptionalField, XmlIgnore]
        int yoffset;
        [OptionalField]
        int m_zorder;

        public ImageEntry( string title, Image image, string tag, bool is_default ) {
            this.title = title;
            if ( image != null ) {
                this.image = (Image)image.Clone();
            } else {
                this.image = null;
            }
            this.tag = tag;
            this.IsDefault = is_default;
            m_zorder = 0;
        }
        
        public ImageEntry( string title, Image image, string tag, bool is_default, int zorder )
            : this( title, image, tag, is_default ) {
            m_zorder = zorder;
        }

        private ImageEntry() {
            title = "";
            image = null;
            tag = "";
            is_default = false;
            xoffset = 0;
            yoffset = 0;
            m_zorder = 0;
        }

        public Image Image {
            get {
                return image;
            }
        }

        public override string ToString() {
            if ( image != null ) {
                return "title=" + title + ";tag=" + tag + ";image.width=" + image.Width + ";image.height=" + image.Height + ";xoffset=" + xoffset + ";yoffset=" + yoffset + ";z=" + m_zorder;
            } else {
                return "title=" + title + ";tag=" + tag + ";image=null;xoffset=" + xoffset + ";yoffset=" + yoffset + ";z=" + m_zorder;
            }
        }

        public int XOffset {
            get {
                return xoffset;
            }
        }

        public int YOffset {
            get {
                return yoffset;
            }
        }

        public void ResetImage() {
            if ( image != null ) {
                image = null;
                xoffset = 0;
                yoffset = 0;
            }
        }

        public Bitmap GetImage() {
            if ( image != null ) {
                int width = xoffset + image.Width;
                int height = yoffset + image.Height;
                return GetImage( width, height );
            } else {
                return null;
            }
        }

        public Bitmap GetImage( Size size ) {
            return GetImage( size.Width, size.Height );
        }

        public Bitmap GetImage( int width, int height ) {
            Bitmap res = new Bitmap( width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb );
            using ( Graphics g = Graphics.FromImage( res ) ) {
                this.DrawTo( g );
            }
            return res;
        }

        public void DrawTo( Graphics g ) {
            if ( image != null ) {
                g.DrawImage( image, xoffset, yoffset, image.Width, image.Height );
            }
        }

        public void SetImage( Image img ) {
            if ( img == null ) {
                return;
            }
            Bitmap t = new Bitmap( img );
            Rectangle rc = Common.GetNonTransparentRegion( t );
#if DEBUG
            Common.DebugWriteLine( "ImageEntry.SetImage; rc=" + rc );
#endif
            if ( image != null ) {
                image = null;
            }
            image = new Bitmap( rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb );
            using ( Graphics g = Graphics.FromImage( image ) ) {
                g.DrawImage( img, 0, 0, rc, GraphicsUnit.Pixel );
            }
            xoffset = rc.X;
            yoffset = rc.Y;
        }

        public int CompareTo( ImageEntry item ) {
            if ( this.Z > item.Z ) {
                return 1;
            } else if ( this.Z < item.Z ) {
                return -1;
            } else {
                return 0;
            }
        }

        [XmlElement("FileId")]
        public int Z {
            get {
                return m_zorder;
            }
            set {
                m_zorder = value;
            }
        }

        public bool IsDefault {
            get {
                return is_default;
            }
            set {
                is_default = value;
            }
        }

        [OnDeserializing]
        private void onDeserializing( StreamingContext sc ) {
            IsDefault = false;
            xoffset = 0;
            yoffset = 0;
        }

        [OnDeserialized]
        private void onDeserialized( StreamingContext sc ) {
        }

        public object Clone() {
            ImageEntry result = new ImageEntry( title, image, tag, is_default );
            result.xoffset = this.xoffset;
            result.yoffset = this.yoffset;
            result.m_zorder = this.m_zorder;
            return result;
        }
    }

}
