static public Dictionary <string, double> GetWidthandHeight(EPObj.MemorySafe_Surface epsurface, surfaceTypeEnum surftype)
        {
            Dictionary <string, double>       WH     = new Dictionary <string, double>();
            List <EPObj.MemorySafe_CartCoord> coords = epsurface.SurfaceCoords;
            //we use a very simple algorithm where we find the area and the max height
            //we divide the area by the max height, and this is our width.
            //this helps us cover the case of non-vertical surfaces, and polygons that
            //are not rectangles

            double width  = 0;
            double height = 0;

            for (int i = 0; i < (coords.Count() - 1); i++)
            {
                double dx = Math.Abs(coords[i].X - coords[i + 1].X);
                double dy = Math.Abs(coords[i].Y - coords[i + 1].Y);
                double dz = Math.Abs(coords[i].Z - coords[i + 1].Z);
                //get the height
                if (surftype == surfaceTypeEnum.ExteriorWall || surftype == surfaceTypeEnum.InteriorWall || surftype == surfaceTypeEnum.UndergroundWall)
                {
                    if (dz == 0)
                    {
                        continue;
                    }
                    else
                    {
                        if (dx == 0 && dy == 0)
                        {
                            if (dz > height)
                            {
                                height = dz;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            //can you prove this somehow?
                            double dist = Math.Sqrt(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)) + Math.Pow(dz, 2));
                            if (dist > height)
                            {
                                height = dist;
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                }
                else
                {
                    if (dz == 0)
                    {
                        double dist = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
                        if (dist > height)
                        {
                            height = dist;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else //it is tilted
                    {
                        double dist = Math.Sqrt(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)) + Math.Pow(dz, 2));
                        if (dist > height)
                        {
                            height = dist;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
                //this simplifies the definition of width and area greatly
                double area = EPObj.GetAreaofSurface(epsurface);
                if (height != 0)
                {
                    width = area / height;
                }
            }
            WH.Add("width", width);
            WH.Add("height", height);
            return(WH);
        }
        static public Surface SetUpSurfaceFromIDF(EPObj.MemorySafe_Surface epsurface, PlanarGeometry pg)
        {
            Surface retsurface = new Surface();

            retsurface.PlanarGeometry = pg;
            if (epsurface._sunExposureVar == "SunExposed")
            {
                retsurface.AdjacentSpaceId = new AdjacentSpaceId[1];
                if (epsurface.tilt > 45 && epsurface.tilt < 135)
                {
                    Dictionary <string, double> WH = new Dictionary <string, double>();
                    //it can be considered an exterior wall
                    retsurface.surfaceType       = surfaceTypeEnum.ExteriorWall;
                    retsurface.constructionIdRef = "something";
                    retsurface.Name = epsurface.name;
                    AdjacentSpaceId adj = new AdjacentSpaceId();
                    adj.spaceIdRef = epsurface.zoneName;
                    retsurface.AdjacentSpaceId[0] = adj;

                    RectangularGeometry rg = new RectangularGeometry();
                    rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth);
                    //find lower left hand corner of exterior wall
                    //for now, we will just arbitrarily choose a point
                    rg.CartesianPoint = pg.PolyLoop.Points[0];
                    rg.Tilt           = gb.FormatDoubleToString(epsurface.tilt);
                    //get width and height
                    WH        = GetWidthandHeight(epsurface, retsurface.surfaceType);
                    rg.Width  = gb.FormatDoubleToString(WH["width"]);
                    rg.Height = gb.FormatDoubleToString(WH["height"]);
                    retsurface.RectangularGeometry = rg;

                    retsurface.PlanarGeometry    = pg;
                    retsurface.exposedToSunField = true;
                }
                //it can be a roof
                else if (epsurface.tilt >= 0 && epsurface.tilt <= 45)
                {
                    Dictionary <string, double> WH = new Dictionary <string, double>();
                    //it can be considered an exterior wall
                    retsurface.surfaceType       = surfaceTypeEnum.Roof;
                    retsurface.constructionIdRef = "something";
                    retsurface.Name = epsurface.name;
                    AdjacentSpaceId adj = new AdjacentSpaceId();
                    adj.spaceIdRef = epsurface.zoneName;
                    retsurface.AdjacentSpaceId[0] = adj;

                    RectangularGeometry rg = new RectangularGeometry();
                    rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth);
                    //find lower left hand corner of exterior wall
                    //for now, we will just arbitrarily choose a point
                    rg.CartesianPoint = pg.PolyLoop.Points[0];
                    rg.Tilt           = gb.FormatDoubleToString(epsurface.tilt);
                    //get width and height
                    WH        = GetWidthandHeight(epsurface, retsurface.surfaceType);
                    rg.Width  = gb.FormatDoubleToString(WH["width"]);
                    rg.Height = gb.FormatDoubleToString(WH["height"]);
                    retsurface.RectangularGeometry = rg;

                    retsurface.PlanarGeometry    = pg;
                    retsurface.exposedToSunField = true;
                }
                //it can be an exposed floor
                else
                {
                    Dictionary <string, double> WH = new Dictionary <string, double>();
                    //it can be considered an exterior wall
                    retsurface.surfaceType       = surfaceTypeEnum.UndergroundSlab;
                    retsurface.constructionIdRef = "something";
                    retsurface.Name = epsurface.name;
                    AdjacentSpaceId adj = new AdjacentSpaceId();
                    adj.spaceIdRef = epsurface.zoneName;
                    retsurface.AdjacentSpaceId[0] = adj;

                    RectangularGeometry rg = new RectangularGeometry();
                    rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth);
                    //find lower left hand corner of exterior wall
                    //for now, we will just arbitrarily choose a point
                    rg.CartesianPoint = pg.PolyLoop.Points[0];
                    rg.Tilt           = gb.FormatDoubleToString(epsurface.tilt);
                    //get width and height
                    WH        = GetWidthandHeight(epsurface, retsurface.surfaceType);
                    rg.Width  = gb.FormatDoubleToString(WH["width"]);
                    rg.Height = gb.FormatDoubleToString(WH["height"]);
                    retsurface.RectangularGeometry = rg;

                    retsurface.PlanarGeometry    = pg;
                    retsurface.exposedToSunField = true;
                }
            }
            else if (epsurface._sunExposureVar == "NoSun" && epsurface._outsideBoundaryCondition == "Ground")
            {
                if (epsurface.tilt > 45 && epsurface.tilt < 135)
                {
                    Dictionary <string, double> WH = new Dictionary <string, double>();
                    //it can be considered an underground wall
                    retsurface.surfaceType       = surfaceTypeEnum.UndergroundWall;
                    retsurface.constructionIdRef = "something";
                    retsurface.Name = epsurface.name;
                    AdjacentSpaceId adj1 = new AdjacentSpaceId();
                    adj1.spaceIdRef = epsurface.zoneName;
                    AdjacentSpaceId adj2 = new AdjacentSpaceId();
                    adj2.spaceIdRef = epsurface.zoneName;
                    retsurface.AdjacentSpaceId[0] = adj1;
                    retsurface.AdjacentSpaceId[1] = adj2;

                    RectangularGeometry rg = new RectangularGeometry();
                    rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth);
                    //find lower left hand corner of exterior wall
                    //for now, we will just arbitrarily choose a point
                    rg.CartesianPoint = pg.PolyLoop.Points[0];
                    rg.Tilt           = gb.FormatDoubleToString(epsurface.tilt);
                    //get width and height
                    WH        = GetWidthandHeight(epsurface, retsurface.surfaceType);
                    rg.Width  = gb.FormatDoubleToString(WH["width"]);
                    rg.Height = gb.FormatDoubleToString(WH["height"]);
                    retsurface.RectangularGeometry = rg;

                    retsurface.PlanarGeometry    = pg;
                    retsurface.exposedToSunField = false;
                }
                else if (epsurface.tilt >= 0 && epsurface.tilt <= 45)
                {
                    Dictionary <string, double> WH = new Dictionary <string, double>();
                    //it can be considered an underground ceiling
                    retsurface.surfaceType       = surfaceTypeEnum.UndergroundCeiling;
                    retsurface.constructionIdRef = "something";
                    retsurface.Name = epsurface.name;
                    AdjacentSpaceId adj1 = new AdjacentSpaceId();
                    adj1.spaceIdRef = epsurface.zoneName;
                    AdjacentSpaceId adj2 = new AdjacentSpaceId();
                    adj2.spaceIdRef = epsurface.zoneName;
                    retsurface.AdjacentSpaceId[0] = adj1;
                    retsurface.AdjacentSpaceId[1] = adj2;

                    RectangularGeometry rg = new RectangularGeometry();
                    rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth);
                    //find lower left hand corner of exterior wall
                    //for now, we will just arbitrarily choose a point
                    rg.CartesianPoint = pg.PolyLoop.Points[0];
                    rg.Tilt           = gb.FormatDoubleToString(epsurface.tilt);
                    //get width and height
                    WH        = GetWidthandHeight(epsurface, retsurface.surfaceType);
                    rg.Width  = gb.FormatDoubleToString(WH["width"]);
                    rg.Height = gb.FormatDoubleToString(WH["height"]);
                    retsurface.RectangularGeometry = rg;

                    retsurface.PlanarGeometry    = pg;
                    retsurface.exposedToSunField = false;
                }
                else
                {
                    Dictionary <string, double> WH = new Dictionary <string, double>();
                    //it can be considered an underground slab or slab on grade

                    retsurface.surfaceType       = surfaceTypeEnum.UndergroundSlab;
                    retsurface.constructionIdRef = "something";
                    retsurface.Name = epsurface.name;
                    AdjacentSpaceId adj1 = new AdjacentSpaceId();
                    adj1.spaceIdRef = epsurface.zoneName;
                    AdjacentSpaceId adj2 = new AdjacentSpaceId();
                    adj2.spaceIdRef = epsurface.zoneName;
                    retsurface.AdjacentSpaceId[0] = adj1;
                    retsurface.AdjacentSpaceId[1] = adj2;

                    RectangularGeometry rg = new RectangularGeometry();
                    rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth);
                    //find lower left hand corner of exterior wall
                    //for now, we will just arbitrarily choose a point
                    rg.CartesianPoint = pg.PolyLoop.Points[0];
                    rg.Tilt           = gb.FormatDoubleToString(epsurface.tilt);
                    //get width and height
                    WH        = GetWidthandHeight(epsurface, retsurface.surfaceType);
                    rg.Width  = gb.FormatDoubleToString(WH["width"]);
                    rg.Height = gb.FormatDoubleToString(WH["height"]);
                    retsurface.RectangularGeometry = rg;

                    retsurface.PlanarGeometry    = pg;
                    retsurface.exposedToSunField = false;
                }
            }
            else
            {
                retsurface.AdjacentSpaceId = new AdjacentSpaceId[2];
                //some new code associated with finding the order of the two spaces
                if (epsurface.tilt > 45 && epsurface.tilt < 135)
                {
                    Dictionary <string, double> WH = new Dictionary <string, double>();
                    //it can be considered an underground wall
                    retsurface.surfaceType       = surfaceTypeEnum.UndergroundWall;
                    retsurface.constructionIdRef = "something";
                    retsurface.Name = epsurface.name;
                    //this is wrong
                    AdjacentSpaceId adj1 = new AdjacentSpaceId();
                    adj1.spaceIdRef = epsurface.zoneName;
                    AdjacentSpaceId adj2 = new AdjacentSpaceId();
                    adj2.spaceIdRef = epsurface.zoneName;
                    retsurface.AdjacentSpaceId[0] = adj1;
                    retsurface.AdjacentSpaceId[1] = adj2;

                    RectangularGeometry rg = new RectangularGeometry();
                    rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth);
                    //find lower left hand corner of exterior wall
                    //for now, we will just arbitrarily choose a point
                    rg.CartesianPoint = pg.PolyLoop.Points[0];
                    rg.Tilt           = gb.FormatDoubleToString(epsurface.tilt);
                    //get width and height
                    WH        = GetWidthandHeight(epsurface, retsurface.surfaceType);
                    rg.Width  = gb.FormatDoubleToString(WH["width"]);
                    rg.Height = gb.FormatDoubleToString(WH["height"]);
                    retsurface.RectangularGeometry = rg;

                    retsurface.PlanarGeometry    = pg;
                    retsurface.exposedToSunField = false;
                }
                else if (epsurface.tilt >= 0 && epsurface.tilt <= 45)
                {
                    Dictionary <string, double> WH = new Dictionary <string, double>();
                    //it can be considered an underground ceiling
                    retsurface.surfaceType       = surfaceTypeEnum.UndergroundCeiling;
                    retsurface.constructionIdRef = "something";
                    retsurface.Name = epsurface.name;
                    //this is wrong
                    AdjacentSpaceId adj1 = new AdjacentSpaceId();
                    adj1.spaceIdRef = epsurface.zoneName;
                    AdjacentSpaceId adj2 = new AdjacentSpaceId();
                    adj2.spaceIdRef = epsurface.zoneName;
                    retsurface.AdjacentSpaceId[0] = adj1;
                    retsurface.AdjacentSpaceId[1] = adj2;

                    RectangularGeometry rg = new RectangularGeometry();
                    rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth);
                    //find lower left hand corner of exterior wall
                    //for now, we will just arbitrarily choose a point
                    rg.CartesianPoint = pg.PolyLoop.Points[0];
                    rg.Tilt           = gb.FormatDoubleToString(epsurface.tilt);
                    //get width and height
                    WH        = GetWidthandHeight(epsurface, retsurface.surfaceType);
                    rg.Width  = gb.FormatDoubleToString(WH["width"]);
                    rg.Height = gb.FormatDoubleToString(WH["height"]);
                    retsurface.RectangularGeometry = rg;

                    retsurface.PlanarGeometry    = pg;
                    retsurface.exposedToSunField = false;
                }
                else
                {
                    Dictionary <string, double> WH = new Dictionary <string, double>();
                    //it can be considered an underground slab or slab on grade

                    retsurface.surfaceType       = surfaceTypeEnum.UndergroundSlab;
                    retsurface.constructionIdRef = "something";
                    retsurface.Name = epsurface.name;
                    //this is wrong
                    AdjacentSpaceId adj1 = new AdjacentSpaceId();
                    adj1.spaceIdRef = epsurface.zoneName;
                    AdjacentSpaceId adj2 = new AdjacentSpaceId();
                    adj2.spaceIdRef = epsurface.zoneName;
                    retsurface.AdjacentSpaceId[0] = adj1;
                    retsurface.AdjacentSpaceId[1] = adj2;

                    RectangularGeometry rg = new RectangularGeometry();
                    rg.Azimuth = gb.FormatDoubleToString(epsurface.azimuth);
                    //find lower left hand corner of exterior wall
                    //for now, we will just arbitrarily choose a point
                    rg.CartesianPoint = pg.PolyLoop.Points[0];
                    rg.Tilt           = gb.FormatDoubleToString(epsurface.tilt);
                    //get width and height
                    WH        = GetWidthandHeight(epsurface, retsurface.surfaceType);
                    rg.Width  = gb.FormatDoubleToString(WH["width"]);
                    rg.Height = gb.FormatDoubleToString(WH["height"]);
                    retsurface.RectangularGeometry = rg;

                    retsurface.PlanarGeometry    = pg;
                    retsurface.exposedToSunField = false;
                }
            }
            return(retsurface);
        }