//------------------------------------------------------------------------------//
        // Movement Bitmap Constructor
        //------------------------------------------------------------------------------//
        public CBitmapSpeMovement(Rectangle BitmapRec)
            : base(BitmapRec)
        {
            int i;
            int numHashMarkRegionsX = BMPCONSTS.NUM_MOVMENT_X_HASHMARKS - 1;
            int numHashMarkRegionsY = BMPCONSTS.NUM_MOVMENT_Y_HASHMARKS - 1;

            // Allocate the hashmarks
            m_hashMarkArrayYLeft = new HASHMARK[BMPCONSTS.NUM_MOVMENT_Y_HASHMARKS];
            m_hashMarkArrayXBottom = new HASHMARK[BMPCONSTS.NUM_MOVMENT_X_HASHMARKS];

            //--------------------------------------------------------------------------//
            // Override default rect settings set in the base constructor
            //-----------------------------------------------------------//
            m_dataRect = m_windowRect;

            m_displayRect.X = m_dataRect.X - BMPCONSTS.HASH_REGION_VERT_WIDTH_MARK;
            m_displayRect.Y = m_dataRect.Y - BMPCONSTS.HASH_REGION_HORZ_HEIGHT_NOMARK;
            m_displayRect.Width = m_dataRect.Width + BMPCONSTS.HASH_REGION_VERT_WIDTH_MARK + BMPCONSTS.HASH_REGION_VERT_WIDTH_NOMARK;
            m_displayRect.Height = m_dataRect.Height + BMPCONSTS.HASH_REGION_HORZ_HEIGHT_NOMARK + BMPCONSTS.HASH_REGION_HORZ_HEIGHT_MARK;

            m_windowRect = m_displayRect;
            m_windowRect.X -= BMPCONSTS.BOARDER_THICKNESS;
            m_windowRect.Y -= BMPCONSTS.BOARDER_THICKNESS;
            m_windowRect.Width += 2 * BMPCONSTS.BOARDER_THICKNESS;
            m_windowRect.Height += 2 * BMPCONSTS.BOARDER_THICKNESS;
            //--------------------------------------------------------------------------//

            m_bitmap = new Bitmap(m_dataRect.Width, m_dataRect.Height);


            // Determine the placement of the hashmarks on the X-axis
            m_pixelsPerHashmarkRegionY = m_dataRect.Height / numHashMarkRegionsY; // calculates pixels per hashmark.
            for(i = 0; i < m_hashMarkArrayYLeft.Length; i++)
            {
                m_hashMarkArrayYLeft[i].point.X = m_displayRect.X + BMPCONSTS.HASH_REGION_VERT_WIDTH_MARK;
                m_hashMarkArrayYLeft[i].point.Y = m_dataRect.Y + i * m_pixelsPerHashmarkRegionY;
            }

            // Determine the placement of the hashmarks on the Y-axis
            m_pixelsPerHashmarkRegionX = m_dataRect.Width / numHashMarkRegionsX; // calculates pixels per hashmark.
            for(i = 0; i < m_hashMarkArrayXBottom.Length; i++)
            {
                m_hashMarkArrayXBottom[i].point.X = m_dataRect.X + i * m_pixelsPerHashmarkRegionX;
                m_hashMarkArrayXBottom[i].point.Y = m_displayRect.Y + m_displayRect.Height - BMPCONSTS.HASH_REGION_HORZ_HEIGHT_MARK;
            }

            // Create text brush
            m_textBrush = new SolidBrush(Color.Black);
            m_textFont = new Font("Tahoma", 7.25F, FontStyle.Regular, GraphicsUnit.Point, 0);

        }
        //------------------------------------------------------------------------------//
        // Behavior Transition Over Time Bitmap RedrawBitmap()
        //------------------------------------------------------------------------------//
        // Called when the bitmap needs to be updated because data has changed or desired
        // characteristics of how the data is displayed has changed.
        private void RedrawBitmap()
        {
            int i,j;
            int numHasmarkRegionsY;
            int numHasmarkRegionsX;

            double minutesPerHashmarkRegionY = 60; // just a safe value
            double transitionsPerHashmarkRegionY = 60; // just a safe value

            double pixelsPerMinuteY;
            double pixelsPerBehCntY;

            SINGLEBEHTRANSSTATS stats = GetSingleBehaviorTransitionStats(m_data);
            TRANSPERIOD period;

            // Redundant variables placed to make code easier to understand.

            m_bitmap = new Bitmap(m_dataRect.Width, m_dataRect.Height);

            m_hashMarkTimeText.point.X = m_dataRect.X - 70;
            m_hashMarkTimeText.point.Y = m_dataRect.Y + m_dataRect.Height/2;
            m_hashMarkTimeText.sz = "Time (min)";

            m_hashMarkCountText.point.X = m_dataRect.X + m_dataRect.Width + 20;
            m_hashMarkCountText.point.Y = m_dataRect.Y + m_dataRect.Height/2;
            m_hashMarkCountText.sz = "Counts";

            m_hashMarkTransitionLabel.point.X = m_dataRect.X + m_dataRect.Width/2;// -50;
            m_hashMarkTransitionLabel.point.Y = m_dataRect.Y +m_dataRect.Height;// -50;
            m_hashMarkTransitionLabel.sz = "Transition Periods";

            //--------------------------------------------------------------------------//
            // Hashmarks
            //----------//

            numHasmarkRegionsY = BMPCONSTS.NUM_BEHAVIORTRANS_Y_HASHMARKS - 1;
            numHasmarkRegionsX = m_data.timePeriodArray.Length;
            transitionsPerHashmarkRegionY = (float)stats.maxBehaviorCount/(float)numHasmarkRegionsY;

            // Allocate hashmarks in the for the x and y dimensions.
            if(m_displayType == MBSDEFAULTS.BITMAPDISPLAYTYPE.BEHAVIOR_TRANSITION)
            {
                m_hashMarkArrayYLeft = new HASHMARK[numHasmarkRegionsY + 1];
                minutesPerHashmarkRegionY = (int)(((double)stats.maxPeriodDuration/60.0)/(double)numHasmarkRegionsY);
            }

            m_hashMarkArrayYRight = new HASHMARK[numHasmarkRegionsY + 1];

            // Two hashmarks for each transition region... one on each side.
            m_hashMarkArrayXBottom = new HASHMARK[numHasmarkRegionsX*2];

            // Calculate pixels per hashmark in for the x and y dimensions.
            m_pixelsPerHashmarkRegionY = m_dataRect.Height / numHasmarkRegionsY;
            m_pixelsPerHashmarkRegionX = m_dataRect.Width / numHasmarkRegionsX;

            // Set hashmark placement for the y dimension and set hashmark strings.
            for(i=0; m_hashMarkArrayYLeft != null && i < m_hashMarkArrayYLeft.Length; i++)
            {
                m_hashMarkArrayYLeft[i].point.X = m_displayRect.X + BMPCONSTS.TRANS_HASH_REGION_VERT_WIDTH_MARK;
                m_hashMarkArrayYLeft[i].point.Y = m_dataRect.Y + m_dataRect.Height - i * m_pixelsPerHashmarkRegionY;
                m_hashMarkArrayYLeft[i].sz = String.Format("{0,2}", minutesPerHashmarkRegionY*i);
            }

            for(i=0; m_hashMarkArrayYRight != null && i < m_hashMarkArrayYRight.Length; i++)
            {
                m_hashMarkArrayYRight[i].point.X = m_dataRect.X + m_dataRect.Width + BMPCONSTS.SHELL_REGION_VERT_WIDTH;
                m_hashMarkArrayYRight[i].point.Y = m_dataRect.Y + m_dataRect.Height - i * m_pixelsPerHashmarkRegionY;
                m_hashMarkArrayYRight[i].sz = String.Format("{0:0.0}", transitionsPerHashmarkRegionY*i);
            }
            //--------------------------------------------------------------------------//


            //--------------------------------------------------------------------------//
            // Determine Dynamic Rect Placements
            //------------------------------------//
            
            // The total number of pixels available for all the transition periods to be
            // displayed is equal to the total number of pixels minus the percentage to be
            // reserved for space in-between each transition period.
            int pixPerTransPeriod = (m_dataRect.Width - 
                (int)(m_dataRect.Width*(BMPCONSTS.TRANS_SPACE_INBETWEEN_PRCNT_MIN/100.0)))/stats.periodCnt;
            int pixIncPerTransPeriod = (m_dataRect.Width)/(stats.periodCnt);  // Number of pixels to increment the placement of succussive transition periods.
            int pixCenterTransPeriod;
            int pixPerBehavior;
            int pixIncPerBehavior;
            int pixCenterBehavior;


            if(pixPerTransPeriod > BMPCONSTS.TRANS_TRIAL_WIDTH_MAX_PIXEL)
                pixPerTransPeriod = BMPCONSTS.TRANS_TRIAL_WIDTH_MAX_PIXEL;

            
            pixPerBehavior = (pixPerTransPeriod - 
                (int)(pixPerTransPeriod*(BMPCONSTS.BEH_SPACE_INBETWEEN_PRCNT_MIN/100.0)))/m_numBehaviors;


            pixelsPerMinuteY = 60; // a safe number
            if(stats.maxPeriodDuration > 0)
                pixelsPerMinuteY = (double)m_dataRect.Height/((double)stats.maxPeriodDuration/60.0);

            pixelsPerBehCntY = 60; // a safe number
            if(stats.maxBehaviorCount > 0)
                pixelsPerBehCntY = (double)m_dataRect.Height/(double)stats.maxBehaviorCount;

            m_dynamicDataRectArray = new DYNAMICDATARECTCONTAINER[stats.periodCnt];

            
            pixCenterTransPeriod = m_dataRect.X + pixIncPerTransPeriod/2;

            // i represents transition period index.
            // j represents behavior index of transition period i.
            for(i = 0; i < stats.periodCnt; i++)
            {
                period = stats.periodArray[i];

                //----------------------//
                // Transition Rectangles
                //----------------------//
                // Min value
                m_dynamicDataRectArray[i].rectMin.X =  pixCenterTransPeriod - pixPerTransPeriod/2;
                m_dynamicDataRectArray[i].rectMin.Width = pixPerTransPeriod;
                m_dynamicDataRectArray[i].rectMin.Y = m_dataRect.Y + m_dataRect.Height - (int)(pixelsPerMinuteY * (period.minDuration/60.0));
                m_dynamicDataRectArray[i].rectMin.Height = (int)(pixelsPerMinuteY *period.minDuration/60.0);
                // Max value
                m_dynamicDataRectArray[i].rectMax.X =  pixCenterTransPeriod - pixPerTransPeriod/2;
                m_dynamicDataRectArray[i].rectMax.Width = pixPerTransPeriod;
                m_dynamicDataRectArray[i].rectMax.Y = m_dataRect.Y + m_dataRect.Height - (int)(pixelsPerMinuteY * (period.maxDuration/60.0));
                m_dynamicDataRectArray[i].rectMax.Height = (int)(pixelsPerMinuteY *period.maxDuration/60.0);
                // Average value
                m_dynamicDataRectArray[i].rectAve.X =  pixCenterTransPeriod - pixPerTransPeriod/2;
                m_dynamicDataRectArray[i].rectAve.Width = pixPerTransPeriod;
                m_dynamicDataRectArray[i].rectAve.Y = m_dataRect.Y + m_dataRect.Height - (int)(pixelsPerMinuteY * (period.aveDuration/60.0));
                m_dynamicDataRectArray[i].rectAve.Height = (int)(pixelsPerMinuteY *period.aveDuration/60.0);


                // Set hashmark placement and string for the lower hasmark for the time period.
                Debug.Assert(i*2 < m_hashMarkArrayXBottom.Length);
                m_hashMarkArrayXBottom[i*2].point.X = pixCenterTransPeriod - pixPerTransPeriod/2;
                m_hashMarkArrayXBottom[i*2].point.Y = m_displayRect.Y + m_displayRect.Height - BMPCONSTS.HASH_REGION_HORZ_HEIGHT_MARK - 10; // see calculation of shell height to fix this magic number 10
                m_hashMarkArrayXBottom[i*2].sz = "" + String.Format("{0:0.00}", m_data.timePeriodArray[i].start);

                // Set hashmark placement and string for the upper hasmark for the time period.
                Debug.Assert(i*2+1 < m_hashMarkArrayXBottom.Length);
                m_hashMarkArrayXBottom[i*2+1].point.X = pixCenterTransPeriod - pixPerTransPeriod/2 + pixPerTransPeriod;
                m_hashMarkArrayXBottom[i*2+1].point.Y = m_displayRect.Y + m_displayRect.Height - BMPCONSTS.HASH_REGION_HORZ_HEIGHT_MARK - 10; // see calculation of shell height to fix this magic number 10;
                m_hashMarkArrayXBottom[i*2+1].sz = "" + String.Format("{0:0.00}", m_data.timePeriodArray[i].end);

               
                m_dynamicDataRectArray[i].behavorRectArray = new Rectangle[m_numBehaviors];
                pixIncPerBehavior = m_dynamicDataRectArray[i].rectAve.Width/(m_numBehaviors);
                pixCenterBehavior = m_dynamicDataRectArray[i].rectAve.X + pixIncPerBehavior/2;
                for(j=0; j<m_dynamicDataRectArray[i].behavorRectArray.Length; j++)
                {
                    m_dynamicDataRectArray[i].behavorRectArray[j].X = pixCenterBehavior - pixPerBehavior/2;
                    m_dynamicDataRectArray[i].behavorRectArray[j].Width = pixPerBehavior;

                    m_dynamicDataRectArray[i].behavorRectArray[j].Y = m_dataRect.Y + m_dataRect.Height - (int)(pixelsPerBehCntY * period.toBehaviorCount[j]);
                    m_dynamicDataRectArray[i].behavorRectArray[j].Height = (int)(pixelsPerBehCntY * period.toBehaviorCount[j]);

                    pixCenterBehavior += pixIncPerBehavior;
                }
                pixCenterTransPeriod += pixIncPerTransPeriod;
            }
        }
        //------------------------------------------------------------------------------//
        // Dive Bitmap Constuctor
        //------------------------------------------------------------------------------//
        public CBitmapSpeDiveProfile(Rectangle BitmapRec)
            : base(BitmapRec) // CBitmapSpeciesParent() constructor
        {
            int i;

            //            m_bBathyUserSet = false;
            //          m_bLeftMouseDown = false;
            // m_displayRect is the remaining region after boarders have been taken away

            m_dataRect = new Rectangle();
            m_dataRect.X = m_displayRect.X + BMPCONSTS.HASH_REGION_VERT_WIDTH_MARK;
            m_dataRect.Y = m_displayRect.Y + BMPCONSTS.HASH_REGION_HORZ_HEIGHT_NOMARK;
            m_dataRect.Width = m_displayRect.Width - BMPCONSTS.HASH_REGION_VERT_WIDTH_MARK - BMPCONSTS.HASH_REGION_VERT_WIDTH_NOMARK;
            m_dataRect.Height = m_displayRect.Height - BMPCONSTS.HASH_REGION_HORZ_HEIGHT_NOMARK - BMPCONSTS.HASH_REGION_HORZ_HEIGHT_MARK;

            m_bitmap = new Bitmap(m_dataRect.Width, m_dataRect.Height);

            // Hashmarks
            m_hashMarkArrayYLeft = new HASHMARK[BMPCONSTS.NUM_DEPTH_HASHMARKS];
            m_hashMarkArrayXBottom = new HASHMARK[BMPCONSTS.NUM_TIME_HASHMARKS];

            m_pixelsPerHashmarkRegionY = m_dataRect.Height / (BMPCONSTS.NUM_DEPTH_HASHMARKS - 1); // calculates pixels per hashmark.
            for(i = 0; i < m_hashMarkArrayYLeft.Length; i++)
            {
                m_hashMarkArrayYLeft[i].point.X = m_displayRect.X + BMPCONSTS.HASH_REGION_VERT_WIDTH_MARK;
                m_hashMarkArrayYLeft[i].point.Y = m_dataRect.Y + i * m_pixelsPerHashmarkRegionY;
            }

            // calculates pixels per hashmark region.
            m_pixelsPerHashmarkRegionX = m_dataRect.Width / (BMPCONSTS.NUM_TIME_HASHMARKS - 1);


            for(i = 0; i < m_hashMarkArrayXBottom.Length; i++)
            {
                m_hashMarkArrayXBottom[i].point.X = m_dataRect.X + i * m_pixelsPerHashmarkRegionX;
                m_hashMarkArrayXBottom[i].point.Y = m_displayRect.Y + m_displayRect.Height - BMPCONSTS.HASH_REGION_HORZ_HEIGHT_MARK;
            }

            // Create text brush
            m_textBrush = new SolidBrush(Color.Black);
            m_textFont = new Font("Tahoma", 7.25F, FontStyle.Regular, GraphicsUnit.Point, 0);

        }