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

#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
    }
}
