/// <summary>
 /// Draws this instance
 /// </summary>
 /// <param name="tr">The active transaction.</param>
 protected override ObjectIdCollection DrawContent(Transaction tr)
 {
     try
     {
         ObjectIdCollection ids       = new ObjectIdCollection();
         Boolean            is2DBlock = !App.Riviera.Is3DEnabled;
         ObjectId           first     = this.Ids.OfType <ObjectId>().FirstOrDefault();
         RivieraLBlock      block     = this.Block as RivieraLBlock;
         var            doc           = Application.DocumentManager.MdiActiveDocument;
         BlockReference blkRef;
         LBlockType     blockType = this.GetBlockType();
         //Si ya se dibujo, el elemento tiene un id válido, solo se debe actualizar
         //el contenido.
         if (first.IsValid)
         {
             block.SetContent(blockType, is2DBlock, doc, tr);
             blkRef = first.GetObject(OpenMode.ForWrite) as BlockReference;
         }
         else
         {
             blkRef = block.Insert(doc, tr, blockType, this.Start.ToPoint3d(), this.Direction.Angle);
             if (!is2DBlock)
             {
                 UpdateBlockPosition(tr, blkRef);
             }
         }
         ids.Add(blkRef.Id);
         return(ids);
     }
     catch (Exception exc)
     {
         throw exc;
     }
 }
        /// <summary>
        /// Gets the name of the instance.
        /// </summary>
        /// <param name="block">The block direction.</param>
        /// <returns>The Instance name</returns>
        public string GetInstanceName(LBlockType blockDirection)
        {
            string code    = this.BlockName.Substring(0, 6);
            int    frente1 = int.Parse(this.BlockName.Substring(6, 2)),
                   frente2 = int.Parse(this.BlockName.Substring(8, 2)),
                   alto    = int.Parse(this.BlockName.Substring(10, 2));

            if (blockDirection == LBlockType.LEFT_START_MAX_SIZE || blockDirection == LBlockType.RIGHT_START_MAX_SIZE)
            {
                int max = frente1 > frente2 ? frente1 : frente2,
                    min = frente1 < frente2 ? frente1 : frente2;
                frente1 = max;
                frente2 = min;
            }
            else
            {
                int max = frente1 > frente2 ? frente1 : frente2,
                    min = frente1 < frente2 ? frente1 : frente2;
                frente1 = min;
                frente2 = max;
            }

            code = String.Format("{0}{1}{2}{3}T", code, frente1, frente2, alto);
            string dir = new LBlockType[] { LBlockType.RIGHT_SAME_SIZE, LBlockType.RIGHT_START_MAX_SIZE, LBlockType.RIGHT_START_MIN_SIZE }.Contains(blockDirection) ? BLOCK_DIR_RGT : BLOCK_DIR_LFT;

            return(String.Format(PREFIX_BLOCK_INST, code, dir));
        }
        /// <summary>
        /// Inserts this instance block as a BlockReference.
        /// </summary>
        /// <param name="doc">The active document.</param>
        /// <param name="tr">The active transaction.</param>
        /// <param name="insPt">The insertion point.</param>
        /// <param name="angle">The block rotation.</param>
        /// <param name="scale">The block scale.</param>
        /// <returns>
        /// The Block Reference
        /// </returns>
        /// <exception cref="RivieraException">Si existe un error al insertar el bloque</exception>
        public BlockReference Insert(Document doc, Transaction tr, LBlockType blockDir, Point3d insPt, double angle = 0, double scale = 1)
        {
            BlockTable   blockTable = doc.Database.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
            AutoCADBlock instance;
            Boolean      is2DBlock    = !App.Riviera.Is3DEnabled;
            String       instanceName = this.GetInstanceName(blockDir);

            if (!blockTable.Has(instanceName))
            {
                instance = this.SetContent(blockDir, is2DBlock, doc, tr);
            }
            else
            {
                Dictionary <LBlockType, AutoCADBlock> blocks2d, blocks3d;
                this.LoadBlocks(doc, tr, out blocks2d, out blocks3d);
                instance = new AutoCADBlock(instanceName, tr);
            }
            //Se realizá la inserción de la instancia
            if (instance != null)
            {
                BlockReference   blkRef     = instance.CreateReference(insPt, angle, scale);
                BlockTableRecord modelSpace = tr.GetModelSpace();
                blkRef.Draw(modelSpace, tr);
                AutoCADLayer lay = new AutoCADLayer(LAYER_RIVIERA_GEOMETRY, tr);
                lay.SetStatus(LayerStatus.EnableStatus, tr);
                blkRef.UpgradeOpen();
                blkRef.Layer = lay.Layername;
                return(blkRef);
            }
            else
            {
                throw new RivieraException(String.Format(ERR_LOADING_BLOCK, this.BlockName));
            }
        }
        /// <summary>
        /// Sets the instance content, depending on the if the application view
        /// is on 2D or 3D
        /// </summary>
        /// <param name="is2DBlock">if set to <c>true</c> [is a 2D block] otherwise a 3D block.</param>
        /// <param name="doc">The active document.</param>
        /// <param name="tr">The active transaction.</param>
        public AutoCADBlock SetContent(LBlockType block, Boolean is2DBlock, Document doc, Transaction tr)
        {
            Dictionary <LBlockType, AutoCADBlock> blocks2d, blocks3d;
            AutoCADBlock   instance = null;
            BlockReference blkRef;

            if (LoadBlocks(doc, tr, out blocks2d, out blocks3d))
            {
                instance = new AutoCADBlock(this.GetInstanceName(block), tr);
                instance.Clear(tr);
                if (is2DBlock)
                {
                    blkRef = blocks2d[block].CreateReference(new Point3d(), 0, 1);
                }
                else
                {
                    blkRef = blocks3d[block].CreateReference(new Point3d(), 0, 1);
                }
                instance.Draw(tr, blkRef);
            }
            return(instance);
        }
        /// <summary>
        /// Gets the type of the block to insert.
        /// </summary>
        /// <returns>The block to insert</returns>
        private LBlockType GetBlockType()
        {
            LPanelMeasure size      = this.PanelSize;
            LBlockType    blockType = LBlockType.NONE;

            if (this.Rotation == SweepDirection.Clockwise)
            {
                if (size.FrenteStart == size.FrenteEnd)
                {
                    blockType = LBlockType.RIGHT_SAME_SIZE;
                }
                else if (size.FrenteStart > size.FrenteEnd)
                {
                    blockType = LBlockType.RIGHT_START_MAX_SIZE;
                }
                else
                {
                    blockType = LBlockType.RIGHT_START_MIN_SIZE;
                }
            }
            else
            {
                if (size.FrenteStart == size.FrenteEnd)
                {
                    blockType = LBlockType.LEFT_SAME_SIZE;
                }
                else if (size.FrenteStart > size.FrenteEnd)
                {
                    blockType = LBlockType.LEFT_START_MAX_SIZE;
                }
                else
                {
                    blockType = LBlockType.LEFT_START_MIN_SIZE;
                }
            }
            return(blockType);
        }