public bool CheckPrerequisites()
        {
            bool result = false;

            try
            {
                //Viewplan
                Autodesk.Revit.DB.View activeView = m_doc.ActiveView;
                viewPlan = activeView as ViewPlan;
                if (null != viewPlan)
                {
                    FilteredElementCollector collector    = new FilteredElementCollector(m_doc);
                    List <ViewFamilyType>    viewTypeList = collector.OfClass(typeof(ViewFamilyType)).ToElements().Cast <ViewFamilyType>().ToList();
                    var viewTypes = from vft in viewTypeList where vft.ViewFamily == ViewFamily.Elevation select vft;
                    if (viewTypes.Count() > 0)
                    {
                        viewFamilyTypes = viewTypes.ToList();
                        result          = true;
                    }
                    else
                    {
                        MessageBox.Show("A valid view family type for Elevation has not been loaded in this project.", "View Family Type Missing", MessageBoxButton.OK, MessageBoxImage.Information);
                        result = false;
                    }
                }
                else
                {
                    MessageBox.Show("Please open a plan view that elevation markers are visible.", "Open a Plan View", MessageBoxButton.OK, MessageBoxImage.Information);
                    result = false;
                }

                FilteredElementCollector linkCollector = new FilteredElementCollector(m_doc, viewPlan.Id);
                List <RevitLinkInstance> linkInstances = linkCollector.OfCategory(BuiltInCategory.OST_RvtLinks).WhereElementIsNotElementType().Cast <RevitLinkInstance>().ToList();
                foreach (RevitLinkInstance instance in linkInstances)
                {
                    LinkedInstanceProperties lip = new LinkedInstanceProperties(instance);
                    if (null != lip.LinkedDocument)
                    {
                        if (!linkedDocuments.ContainsKey(lip.InstanceId))
                        {
                            linkedDocuments.Add(lip.InstanceId, lip);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to check prereauisites.\n" + ex.Message, "Check Prerequisites", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            return(result);
        }
        public static Dictionary <int, RoomElevationProperties> GetRoomElevationProperties(Document doc, Dictionary <int, LinkedInstanceProperties> linkedDocs)
        {
            Dictionary <int, RoomElevationProperties> pDictionary = new Dictionary <int, RoomElevationProperties>();

            try
            {
                if (null == m_schema)
                {
                    m_schema = CreateSchema();
                }
                if (null != m_schema)
                {
                    IList <DataStorage> savedStorage = GetRoomElevationStorage(doc, m_schema);
                    if (savedStorage.Count > 0)
                    {
                        foreach (DataStorage storage in savedStorage)
                        {
                            Entity    entity                  = storage.GetEntity(m_schema);
                            string    roomNumber              = entity.Get <string>(m_schema.GetField(s_RoomNumber));
                            string    roomName                = entity.Get <string>(m_schema.GetField(s_RoomName));
                            ElementId roomId                  = entity.Get <ElementId>(m_schema.GetField(s_RoomId));
                            bool      isLinked                = entity.Get <bool>(m_schema.GetField(s_IsLinked));
                            ElementId rvtInstanceId           = entity.Get <ElementId>(m_schema.GetField(s_RvtInstanceId));
                            ElementId keyMarkId               = entity.Get <ElementId>(m_schema.GetField(s_KeyMarkId));
                            IDictionary <int, int> elevations = entity.Get <IDictionary <int, int> >(s_Elevations);

                            //ElementId elevationMarkId = entity.Get<ElementId>(m_schema.GetField(s_elevationMarkId));
                            //IList<ElementId> elevationIds = entity.Get<IList<ElementId>>(m_schema.GetField(s_ElevationIds));

                            if (roomId != ElementId.InvalidElementId)
                            {
                                Room room = null;
                                RoomElevationProperties rep = null;
                                if (isLinked && linkedDocs.ContainsKey(rvtInstanceId.IntegerValue))
                                {
                                    LinkedInstanceProperties lip = linkedDocs[rvtInstanceId.IntegerValue];
                                    room = lip.LinkedDocument.GetElement(roomId) as Room;
                                    if (null != room)
                                    {
                                        rep = new RoomElevationProperties(room, rvtInstanceId.IntegerValue);
                                    }
                                }
                                else
                                {
                                    room = doc.GetElement(roomId) as Room;
                                    if (null != room)
                                    {
                                        rep = new RoomElevationProperties(room);
                                    }
                                }

                                if (null != rep)
                                {
                                    rep.KeyMarkId = keyMarkId.IntegerValue;
                                    Dictionary <int, Dictionary <int, ElevationViewProperties> > elevationDictionary = new Dictionary <int, Dictionary <int, ElevationViewProperties> >();
                                    foreach (int viewId in elevations.Keys)
                                    {
                                        int elevationViewId = viewId;
                                        int markId          = elevations[elevationViewId];

                                        ViewSection viewSection = doc.GetElement(new ElementId(elevationViewId)) as ViewSection;
                                        if (null != viewSection)
                                        {
                                            ElevationViewProperties evp = new ElevationViewProperties(viewSection);
                                            if (!rep.ElevationViews.ContainsKey(markId))
                                            {
                                                Dictionary <int, ElevationViewProperties> elevationViews = new Dictionary <int, ElevationViewProperties>();
                                                elevationViews.Add(evp.ViewId, evp);
                                                rep.ElevationViews.Add(markId, elevationViews);
                                            }
                                            else
                                            {
                                                if (!rep.ElevationViews[markId].ContainsKey(elevationViewId))
                                                {
                                                    rep.ElevationViews[markId].Add(evp.ViewId, evp);
                                                }
                                            }
                                        }
                                    }

                                    if (!pDictionary.ContainsKey(rep.RoomId))
                                    {
                                        pDictionary.Add(rep.RoomId, rep);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to get room elevation properties from data storage.\n" + ex.Message, "Elevation Creator : GetRoomElevationProperties", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            return(pDictionary);
        }
        public bool CreateElevationByWall()
        {
            bool result = false;

            try
            {
                ElevationMarker marker         = null;
                XYZ             markerLocation = null;
                Dictionary <int, ElevationViewProperties> elevationViews = new Dictionary <int, ElevationViewProperties>();
                ApplyTemplateSettings();

                using (Transaction trans = new Transaction(m_doc, "Elevation Creator"))
                {
                    trans.Start();
                    try
                    {
                        BoundingBoxXYZ bbBox = m_room.get_BoundingBox(null);
                        markerLocation = new XYZ(pickPoint.X, pickPoint.Y, bbBox.Min.Z);
                        if (m_room.Document.IsLinked)
                        {
                            var documents = from doc in linkedDocuments.Values where doc.DocumentTitle == m_room.Document.Title select doc;
                            if (documents.Count() > 0)
                            {
                                LinkedInstanceProperties lip = documents.First();
                                roomLink       = lip;
                                markerLocation = lip.TransformValue.OfPoint(markerLocation);
                            }
                        }

                        marker = ElevationMarker.CreateElevationMarker(m_doc, m_viewFamilyTypeId, markerLocation, toolSettings.CustomScale);
                        trans.Commit();

                        if (null != marker)
                        {
                            string prefix           = toolSettings.PrefixText;
                            string intermediateText = GetRoomParameterValue(m_room, toolSettings.IntermediateText);
                            int    elevationIndex   = GetElevationMarkIndex();
                            string suffix           = GetRoomParameterValue(m_room, toolSettings.SuffixText);

                            int viewCount = marker.MaximumViewCount < suffix.Length ? marker.MaximumViewCount : suffix.Length;

                            double rotationalAngle = 0;
                            Dictionary <int, string> indexLabels = GetMarkerLabel(markerLocation, out rotationalAngle);
                            bool firstView = true;
                            foreach (int index in indexLabels.Keys)
                            {
                                if (index < marker.MaximumViewCount)
                                {
                                    trans.Start();
                                    ViewSection viewElevation = marker.CreateElevation(m_doc, m_viewPlan.Id, index);
                                    viewElevation.Name = GetViewName(prefix, intermediateText, elevationIndex, indexLabels[index], suffix);
                                    if (toolSettings.ViewTemplateId != -1)
                                    {
                                        viewElevation.ViewTemplateId = new ElementId(toolSettings.ViewTemplateId);
                                    }

                                    Parameter param = viewElevation.LookupParameter("Title on Sheet");
                                    if (null != param)
                                    {
                                        param.Set(m_room.Name);
                                    }

                                    trans.Commit();

                                    if (firstView && null != viewElevation)
                                    {
                                        trans.Start();
                                        try
                                        {
                                            bool rotated = RotateMarker(marker, markerLocation, rotationalAngle);
                                            firstView = false;
                                            trans.Commit();
                                        }
                                        catch (Exception ex)
                                        {
                                            trans.RollBack();
                                            MessageBox.Show("Failed to rotate the elevation marker.\n" + ex.Message, "Elevation Creator : RotateMarker", MessageBoxButton.OK, MessageBoxImage.Warning);
                                        }
                                    }

                                    ElevationViewProperties viewProperties = new ElevationViewProperties(viewElevation);
                                    viewProperties.WallId = m_wall.Id.IntegerValue;
                                    if (!elevationViews.ContainsKey(viewProperties.ViewId))
                                    {
                                        elevationViews.Add(viewProperties.ViewId, viewProperties);
                                    }
                                }
                            }

                            if (elevationViews.Count > 0 && !roomProperties.ElevationViews.ContainsKey(marker.Id.IntegerValue))
                            {
                                roomProperties.ElevationViews.Add(marker.Id.IntegerValue, elevationViews);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        trans.RollBack();
                        MessageBox.Show("Failed to create an elevation view.\n" + ex.Message, "Create Elevation View", MessageBoxButton.OK, MessageBoxImage.Warning);
                        return(false);
                    }
                }

                if (null != marker && null != markerLocation)
                {
                    if (ModifyCropBox(roomProperties, marker.Id.IntegerValue))
                    {
                        if (ElevationCreatorDataStorageUtil.StoreRoomElevationProperties(m_doc, roomProperties))
                        {
                            //update extensible storage
                            result = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to create an elevation view.\nRoom Name: " + m_room.Name + "\nWall Name: " + m_wall.Name + "\n" + ex.Message, "", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            return(result);
        }
        private Dictionary <int /*index*/, string /*labelText*/> GetMarkerLabel(XYZ markerPoint, out double rotationalAngle)
        {
            Dictionary <int, string> indexDictionary = new Dictionary <int, string>();

            rotationalAngle = 0;
            try
            {
                LocationCurve locationCurve = m_wall.Location as LocationCurve;
                Curve         curve         = locationCurve.Curve;
                if (m_wall.Document.IsLinked)
                {
                    var documents = from doc in linkedDocuments.Values where doc.DocumentTitle == m_wall.Document.Title select doc;
                    if (documents.Count() > 0)
                    {
                        LinkedInstanceProperties lip = documents.First();
                        wallLink = lip;
                        curve    = curve.CreateTransformed(wallLink.TransformValue);
                    }
                }

                IntersectionResult intersectionResult = curve.Project(markerPoint);
                XYZ intersectionPoint = intersectionResult.XYZPoint;
                if (null != intersectionPoint)
                {
                    XYZ    directionV = intersectionPoint - markerPoint;
                    double angle      = XYZ.BasisY.AngleTo(directionV);
                    rotationalAngle = angle % (0.5 * Math.PI);

                    bool counterClockwise = true;
                    if (XYZ.BasisY.CrossProduct(directionV).Z < 0)
                    {
                        rotationalAngle  = -rotationalAngle;
                        counterClockwise = false;
                    }

                    if (counterClockwise)
                    {
                        if (angle < (0.5 * Math.PI))
                        {
                            indexDictionary = new Dictionary <int, string>();
                            if (toolSettings.AIsSelected)
                            {
                                indexDictionary.Add(1, "A");
                            }
                            if (toolSettings.BIsSelected)
                            {
                                indexDictionary.Add(2, "B");
                            }
                            if (toolSettings.CIsSelected)
                            {
                                indexDictionary.Add(3, "C");
                            }
                            if (toolSettings.DIsSelected)
                            {
                                indexDictionary.Add(0, "D");
                            }
                        }
                        else if (angle >= (0.5 * Math.PI) || angle < Math.PI)
                        {
                            indexDictionary = new Dictionary <int, string>();
                            if (toolSettings.AIsSelected)
                            {
                                indexDictionary.Add(0, "A");
                            }
                            if (toolSettings.BIsSelected)
                            {
                                indexDictionary.Add(1, "B");
                            }
                            if (toolSettings.CIsSelected)
                            {
                                indexDictionary.Add(2, "C");
                            }
                            if (toolSettings.DIsSelected)
                            {
                                indexDictionary.Add(3, "D");
                            }
                        }
                    }
                    else
                    {
                        if (angle < (0.5 * Math.PI))
                        {
                            indexDictionary = new Dictionary <int, string>();
                            if (toolSettings.AIsSelected)
                            {
                                indexDictionary.Add(1, "A");
                            }
                            if (toolSettings.BIsSelected)
                            {
                                indexDictionary.Add(2, "B");
                            }
                            if (toolSettings.CIsSelected)
                            {
                                indexDictionary.Add(3, "C");
                            }
                            if (toolSettings.DIsSelected)
                            {
                                indexDictionary.Add(0, "D");
                            }
                        }
                        else if (angle >= (0.5 * Math.PI) || angle < Math.PI)
                        {
                            indexDictionary = new Dictionary <int, string>();
                            if (toolSettings.AIsSelected)
                            {
                                indexDictionary.Add(2, "A");
                            }
                            if (toolSettings.BIsSelected)
                            {
                                indexDictionary.Add(3, "B");
                            }
                            if (toolSettings.CIsSelected)
                            {
                                indexDictionary.Add(0, "C");
                            }
                            if (toolSettings.DIsSelected)
                            {
                                indexDictionary.Add(1, "D");
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to get the index for marker labels.\n" + ex.Message, "Elevation Creator: Get Marker Label", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            return(indexDictionary);
        }
        public bool CreateElevationByList()
        {
            bool result = false;

            try
            {
                ElevationMarker marker         = null;
                XYZ             markerLocation = null;


                ApplyTemplateSettings();

                using (Transaction trans = new Transaction(m_doc, "Create Elevation Marker"))
                {
                    trans.Start();
                    try
                    {
                        BoundingBoxXYZ bbBox = m_room.get_BoundingBox(null);
                        markerLocation = new XYZ((bbBox.Max.X + bbBox.Min.X) / 2, (bbBox.Max.Y + bbBox.Min.Y) / 2, bbBox.Min.Z);

                        //LocationPoint locationPoint = m_room.Location as LocationPoint;
                        //markerLocation = locationPoint.Point;
                        if (m_room.Document.IsLinked)
                        {
                            var documents = from doc in linkedDocuments.Values where doc.DocumentTitle == m_room.Document.Title select doc;
                            if (documents.Any())
                            {
                                LinkedInstanceProperties lip = documents.First();
                                roomLink       = lip;
                                markerLocation = lip.TransformValue.OfPoint(markerLocation);
                            }
                        }

                        marker = ElevationMarker.CreateElevationMarker(m_doc, m_viewFamilyTypeId, markerLocation, toolSettings.CustomScale);
                        trans.Commit();
                    }
                    catch (Exception ex)
                    {
                        trans.RollBack();
                        LogMessageBuilder.AddLogMessage(roomProperties.RoomNumber + " - " + roomProperties.RoomName + " : failed to create an elevation marker.");
                        LogMessageBuilder.AddLogMessage(ex.Message);
                        //MessageBox.Show("Failed to create an elevation marker.\n" + ex.Message, "Elevation Creator: Create Elevation Marker", MessageBoxButton.OK, MessageBoxImage.Warning);
                    }
                }

                if (null != marker)
                {
                    using (Transaction trans = new Transaction(m_doc, "Create Elevation Views"))
                    {
                        trans.Start();
                        try
                        {
                            string prefix           = toolSettings.PrefixText;
                            string intermediateText = GetRoomParameterValue(m_room, toolSettings.IntermediateText);
                            int    elevationIndex   = GetElevationMarkIndex();
                            string suffix           = GetRoomParameterValue(m_room, toolSettings.SuffixText);

                            int viewCount = marker.MaximumViewCount < 4 ? marker.MaximumViewCount : 4;

                            Dictionary <int, Dictionary <int, ElevationViewProperties> > elevationDictionary = new Dictionary <int, Dictionary <int, ElevationViewProperties> >();
                            Dictionary <int, ElevationViewProperties> elevationViews = new Dictionary <int, ElevationViewProperties>();

                            for (int i = 0; i < viewCount; i++)
                            {
                                string indexText = "";
                                if (i == 0 && toolSettings.DIsSelected)
                                {
                                    indexText = "D";
                                }
                                else if (i == 1 && toolSettings.AIsSelected)
                                {
                                    indexText = "A";
                                }
                                else if (i == 2 && toolSettings.BIsSelected)
                                {
                                    indexText = "B";
                                }
                                else if (i == 3 && toolSettings.CIsSelected)
                                {
                                    indexText = "C";
                                }
                                else
                                {
                                    continue;
                                }

                                ViewSection viewElevation = marker.CreateElevation(m_doc, m_viewPlan.Id, i);
                                viewElevation.Name = GetViewName(prefix, intermediateText, elevationIndex, indexText, suffix);
                                if (toolSettings.ViewTemplateId != -1)
                                {
                                    viewElevation.ViewTemplateId = new ElementId(toolSettings.ViewTemplateId);
                                }

                                Parameter param = viewElevation.LookupParameter("Title on Sheet");

                                if (null != param)
                                {
                                    param.Set(m_room.Name);
                                }

                                ElevationViewProperties viewProperties = new ElevationViewProperties(viewElevation);
                                if (!elevationViews.ContainsKey(viewProperties.ViewId))
                                {
                                    elevationViews.Add(viewProperties.ViewId, viewProperties);
                                }
                            }

                            if (elevationViews.Count > 0 && !roomProperties.ElevationViews.ContainsKey(marker.Id.IntegerValue))
                            {
                                roomProperties.KeyMarkId = marker.Id.IntegerValue;
                                roomProperties.ElevationViews.Add(marker.Id.IntegerValue, elevationViews);
                            }

                            trans.Commit();
                        }
                        catch (Exception ex)
                        {
                            trans.RollBack();
                            LogMessageBuilder.AddLogMessage(roomProperties.RoomNumber + " - " + roomProperties.RoomName + " : failed to create elevation views.");
                            LogMessageBuilder.AddLogMessage(ex.Message);
                            //MessageBox.Show("Failed to create elevation views.\n" + ex.Message, "Elevation Creator: Create Elevation Views", MessageBoxButton.OK, MessageBoxImage.Warning);
                        }
                    }
                }

                if (null != marker && null != markerLocation)
                {
                    if (ModifyCropBox(roomProperties, marker.Id.IntegerValue))
                    {
                        if (ElevationCreatorDataStorageUtil.StoreRoomElevationProperties(m_doc, roomProperties))
                        {
                            //update extensible storage
                            result = true;
                        }
                    }
                }
                result = true;
            }
            catch (Exception ex)
            {
                LogMessageBuilder.AddLogMessage(roomProperties.RoomNumber + " - " + roomProperties.RoomName + " : failed to create elevations by room lists.\n" + ex.Message);
                //MessageBox.Show("Failed to create elevation by room lists.\n"+ex.Message, "Elevation Creator: CreateElevationByList", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            return(result);
        }