context: using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using UniversalEditor.DataFormats.Chunked;
  using UniversalEditor.ObjectModels.Chunked;
  using UniversalEditor.ObjectModels.Multimedia3D.Model;
  
  #if ZZYZX
  namespace UniversalEditor.DataFormats.Multimedia3D.Model.RIFFExtensibleModel
  {
  	public class RMDModelDataFormat : RIFFDataFormat
  	{
  		protected override bool IsObjectModelSupported(ObjectModel omb)
  		{
  			RIFFObjectModel riff = (omb as RIFFObjectModel);
  			if (riff != null)
  			{
  				if (riff.Chunks["MODL"] != null)
  				{
  					return true;
  				}
  			}
  			return false;
  		}
  		private DataFormatReference _dfr = null;
  		public override DataFormatReference MakeReference()
  		{
  			if (_dfr == null)
  			{
  				_dfr = base.MakeReference();
  				_dfr.Clear();
  				_dfr.Capabilities.Add(typeof(ModelObjectModel), DataFormatCapabilities.All);
  				_dfr.Filters.Add("RIFF extensible model data", new byte?[][] { new byte?[] { (byte)'R', (byte)'I', (byte)'F', (byte)'F', null, null, null, null, (byte)'M', (byte)'O', (byte)'D', (byte)'L' } }, new string[] { "*.rmd" });
  			}
  			return _dfr;
  		}
  		protected override void BeforeLoadInternal(Stack<ObjectModel> objectModels)
  		{
  			base.BeforeLoadInternal(objectModels);
  			objectModels.Push(new RIFFObjectModel());
  		}
  		protected override void BeforeSaveInternal(Stack<ObjectModel> objectModels)
  	    {
  	        ModelObjectModel model = (objectModels.Pop() as ModelObjectModel);
  	        string basePath = System.IO.Path.GetDirectoryName(model.FileName);
  
  	        RIFFObjectModel riff = new RIFFObjectModel();
  
  	        RIFFGroupChunk chunkRIFF = new RIFFGroupChunk();
  	        chunkRIFF.TypeID = "RIFF";
  	        chunkRIFF.ID = "MODL";
  
  	        // http://owl.phy.queensu.ca/~phil/exiftool/TagNames/RIFF.html
  
  #region Information
  	        {
  	            if (model.StringTable.ContainsKey(1033))
  	            {
  	                riff.Information.Add(CommonMetadataType.TitleINAM, model.StringTable[1033].Title);
  	                riff.Information.Add(CommonMetadataType.Artist, model.StringTable[1033].Author);
  	            }
  	            riff.Information.Add(CommonMetadataType.Software, "Mike Becker's Software - Universal Editor");
  	        }
  			#endregion
  #region Vertex Data
  	        {
  	            RIFFDataChunk chunkMVTX = new RIFFDataChunk();
  	            chunkMVTX.ID = "MVTX";
  	            System.IO.MemoryStream msMVTX = new System.IO.MemoryStream();
  	            IO.Writer bwMVTX = new IO.Writer(msMVTX);
  	            foreach (ModelSurface surf in model.Surfaces)
  	            {
  	                foreach (ModelVertex vtx in surf.Vertices)
  	                {
  	                    bwMVTX.Write(vtx.Position.X);
  	                    bwMVTX.Write(vtx.Position.Y);
  	                    bwMVTX.Write(vtx.Position.Z);
  	                    bwMVTX.Write(vtx.Normal.X);
  	                    bwMVTX.Write(vtx.Normal.Y);
  	                    bwMVTX.Write(vtx.Normal.Z);
  	                    bwMVTX.Write(vtx.Texture.U);
  	                    bwMVTX.Write(vtx.Texture.V);
  	                    bwMVTX.Write(vtx.Weight);
  	                    bwMVTX.Write(vtx.EdgeFlag);
  	                }
  	            }
  	            bwMVTX.Close();
  	            chunkMVTX.Data = msMVTX.ToArray();
  	            chunkRIFF.Chunks.Add(chunkMVTX);
  	        }
  #endregion
  #region Bone Data
  	        {
  	            RIFFDataChunk chunkMBON = new RIFFDataChunk();
  	            chunkMBON.ID = "MBON";
  
  	            System.IO.MemoryStream ms = new System.IO.MemoryStream();
  	            IO.Writer bw = new IO.Writer(ms);
  	            foreach (ModelBone bone in model.Bones)
  	            {
  	                bw.WriteNullTerminatedString(bone.Name);
  	                bw.Write(bone.Position.X);
  	                bw.Write(bone.Position.Y);
  	                bw.Write(bone.Position.Z);
  	                bw.Write(bone.Rotation.X);
  	                bw.Write(bone.Rotation.Y);
  	                bw.Write(bone.Rotation.Z);
  	                bw.Write(bone.Rotation.W);
  	                bw.Write((int)bone.BoneType);
  	                bw.Write(model.Bones.IndexOf(bone.ChildBone));
  	                bw.Write(bone.IKLimitAngle);
  	                bw.Write(bone.IKNumber);
  	            }
  	            bw.Close();
  
  	            chunkMBON.Data = ms.ToArray();
  	        }
  #endregion
  #region Material Data
  	        {
  	            RIFFDataChunk chunkMMAT = new RIFFDataChunk();
  	            chunkMMAT.ID = "MMAT";
  
  	            System.IO.MemoryStream ms = new System.IO.MemoryStream();
  	            IO.Writer bw = new IO.Writer(ms);
  	            foreach (ModelMaterial mat in model.Materials)
  	            {
  	                bw.WriteNullTerminatedString(mat.Name);
  	                bw.WriteNullTerminatedString(mat.Comment);
  
  	                bw.Write(mat.AlwaysLight);
  	                bw.Write(mat.EdgeFlag);
  	                bw.Write(mat.EdgeSize);
  	                bw.Write(mat.Shininess);
  	                bw.Write(mat.TextureIndex);
  
  	                bw.Write((byte)mat.AmbientColor.R);
  	                bw.Write((byte)mat.AmbientColor.G);
  	                bw.Write((byte)mat.AmbientColor.B);
  	                bw.Write((byte)mat.AmbientColor.A);
  
  	                bw.Write((byte)mat.DiffuseColor.R);
  	                bw.Write((byte)mat.DiffuseColor.G);
  	                bw.Write((byte)mat.DiffuseColor.B);
  	                bw.Write((byte)mat.DiffuseColor.A);
  
  	                bw.Write((byte)mat.EmissiveColor.R);
  	                bw.Write((byte)mat.EmissiveColor.G);
  	                bw.Write((byte)mat.EmissiveColor.B);
  	                bw.Write((byte)mat.EmissiveColor.A);
  
  	                bw.Write((byte)mat.SpecularColor.R);
  	                bw.Write((byte)mat.SpecularColor.G);
  	                bw.Write((byte)mat.SpecularColor.B);
  	                bw.Write((byte)mat.SpecularColor.A);
  
  	                bw.Write((byte)mat.EdgeColor.R);
  	                bw.Write((byte)mat.EdgeColor.G);
  	                bw.Write((byte)mat.EdgeColor.B);
  	                bw.Write((byte)mat.EdgeColor.A);
  
  	                // Number of triangles affected by this material
  	                bw.Write(mat.Triangles.Count);
  
  	                foreach (ModelTriangle tri in mat.Triangles)
  	                {
  	                    // Pointer to the triangle for this material
  	                    bw.Write(model.Triangles.IndexOf(tri));
  	                }
  	            }
  	            bw.Close();
  
  	            chunkMMAT.Data = ms.ToArray();
  	        }
  #endregion
  #region Texture Images
  	        {
  	            RIFFDataChunk chunkMTEX = new RIFFDataChunk();
  	            chunkMTEX.ID = "MTEX";
  
  	            System.IO.MemoryStream ms = new System.IO.MemoryStream();
  	            IO.Writer bw = new IO.Writer(ms);
  	            foreach (ModelMaterial mat in model.Materials)
  	            {
  	                bw.Write(model.Materials.IndexOf(mat));
  
  	                foreach (ModelTexture tex in mat.Textures)
  	                {
  	                    bw.Write((int)tex.Flags);
  
  	                    if (String.IsNullOrEmpty(tex.FileName))
  	                    {
  	                        bw.Write((int)0);
  	                        bw.Write((int)0);
  	                    }
  	                    else
  	                    {
  	                        string textureFileName = String.Empty;
  	                        string sphereFileName = String.Empty;
  
  	                        if (tex.FileName.Contains("*"))
  	                        {
  
gt: 	                            string[] texFileName = tex.FileName.Split(new char[] { '*' });