/*
* 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.
*/

using System;
using System.IO;

#if !(PocketPC||NETCF||NETCF_2_0)
using Apache.NMS.Util;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
#endif

using Apache.NMS.ActiveMQ.OpenWire;

namespace Apache.NMS.ActiveMQ.Commands
{
    //
    //  Marshalling code for Open Wire Format for ActiveMQObjectMessage
    //
    //
    //  NOTE!: This file is autogenerated - do not modify!
    //         if you need to make a change, please see the Groovy scripts in the
    //         activemq-core module
    //
    public class ActiveMQObjectMessage : ActiveMQMessage, IObjectMessage
    {
        public const byte ID_ACTIVEMQOBJECTMESSAGE = 26;

#if !(PocketPC||NETCF||NETCF_2_0)
        private object body;
        private IFormatter formatter;
#endif

        public override string ToString() {
            return GetType().Name + "["
                + " ]";
        }

        public override byte GetDataStructureType() {
            return ID_ACTIVEMQOBJECTMESSAGE;
        }


        // Properties

        public object Body
        {
            get
            {
#if !(PocketPC||NETCF||NETCF_2_0)
                if (body == null)
                {                
                    if(base.Content == null)
                    {
                        return null;
                    }

                    byte[] data = base.Content;
                    Stream target = new MemoryStream(data, false);
                
                    if(this.Connection != null && this.Compressed == true)
                    {
                        target = this.Connection.CompressionPolicy.CreateDecompressionStream(target);
                    }

                    body = Formatter.Deserialize(target);
                }
                return body;
#else
                throw new NotImplementedException();
#endif
            }

            set
            {
#if !(PocketPC||NETCF||NETCF_2_0)
                body = value;
#else
                throw new NotImplementedException();
#endif
            }
        }

        public override bool IsBodyAssignableTo(Type type)
        {
            return Content != null && type.IsInstanceOfType(Body);
        }

        protected override T GetBody<T>()
        {
            return (T)Body;
        }


#if !(PocketPC||NETCF||NETCF_2_0)
        public override void BeforeMarshall(OpenWireFormat wireFormat)
        {
            if (body == null)
            {
                Content = null;
            }
            else
            {
                MemoryStream result = new MemoryStream();
                Stream target = result;
                if(this.Connection != null && this.Connection.UseCompression)
                {
                    this.Compressed = true;
                    target = this.Connection.CompressionPolicy.CreateCompressionStream(target);                    
                }

                Formatter.Serialize(target, body);
                target.Close();
                Content = result.ToArray();
            }

            //Console.WriteLine("BeforeMarshalling, content is: " + Content);

            base.BeforeMarshall(wireFormat);
        }

        public IFormatter Formatter
        {
            get
            {
                if (formatter == null)
                {
                    formatter = new BinaryFormatter();
                }
                return formatter;
            }

            set
            {
                formatter = value;
            }
        }
#endif
    }
}
