/*
* 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.Collections;
using System.IO;

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

using Apache.NMS.ActiveMQ.OpenWire;
using Apache.NMS.ActiveMQ.Commands;
using Apache.NMS;

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)
                {
                    body = Formatter.Deserialize(new MemoryStream(Content));
                }
                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 stream = new MemoryStream();
                Formatter.Serialize(stream, body);
                Content = stream.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
    }
}
