
namespace pdinklag.CPW.Common
{
    /// <summary>
    /// Provides extra information about body POIs.
    /// </summary>
    public static class BodyPOIExtensions
    {
        /// <summary>
        /// Tells whether the POI belongs strictly to the left half of the body.
        /// 
        /// This is false for centered POIs that do not belong to any particular half.
        /// </summary>
        /// <param name="poi">the POI in question</param>
        public static bool BelongsToLeftHalf(this BodyPOI poi)
        {
            switch (poi)
            {
                case BodyPOI.LeftParietal:
                case BodyPOI.LeftEarBehind:
                case BodyPOI.LeftEarCenter:
                case BodyPOI.LeftEarlobe:
                case BodyPOI.LeftEye:
                case BodyPOI.LeftEyebrow:
                case BodyPOI.LeftCheekbone:
                case BodyPOI.LeftTemple:
                case BodyPOI.LeftMouthCorner:
                case BodyPOI.LeftJawAngle:
                case BodyPOI.LeftNeckSide:
                case BodyPOI.LeftTrapezius:
                case BodyPOI.LeftShoulderFront:
                case BodyPOI.LeftShoulderBack:
                case BodyPOI.LeftShoulderLateral:
                case BodyPOI.LeftLateral:
                case BodyPOI.LeftPectorial:
                case BodyPOI.LeftNipple:
                case BodyPOI.LeftAbdomen:
                case BodyPOI.LeftWaist:
                case BodyPOI.LeftPelvisLateral:
                case BodyPOI.LeftArmpit:
                case BodyPOI.LeftUpperArmFront:
                case BodyPOI.LeftUpperArmBack:
                case BodyPOI.LeftUpperArmMedial:
                case BodyPOI.LeftUpperArmLateral:
                case BodyPOI.LeftElbow:
                case BodyPOI.LeftInnerElbow:
                case BodyPOI.LeftElbowMedial:
                case BodyPOI.LeftElbowLateral:
                case BodyPOI.LeftLowerArmFront:
                case BodyPOI.LeftLowerArmBack:
                case BodyPOI.LeftLowerArmMedial:
                case BodyPOI.LeftLowerArmLateral:
                case BodyPOI.LeftWristMedial:
                case BodyPOI.LeftWristLateral:
                case BodyPOI.LeftWristFront:
                case BodyPOI.LeftWristBack:
                case BodyPOI.LeftHandPalm:
                case BodyPOI.LeftHandBack:
                case BodyPOI.LeftHandSide:
                case BodyPOI.LeftKnuckle:
                case BodyPOI.LeftIndexTip:
                case BodyPOI.LeftThumbTip:
                case BodyPOI.LeftThighFront:
                case BodyPOI.LeftThighBack:
                case BodyPOI.LeftThighMedial:
                case BodyPOI.LeftThighLateral:
                case BodyPOI.LeftKnee:
                case BodyPOI.LeftBackKnee:
                case BodyPOI.LeftKneeMedial:
                case BodyPOI.LeftKneeLateral:
                case BodyPOI.LeftCalfMedial:
                case BodyPOI.LeftCalfLateral:
                case BodyPOI.LeftCalf:
                case BodyPOI.LeftShin:
                case BodyPOI.LeftAchillesHeel:
                case BodyPOI.LeftAnkleFront:
                case BodyPOI.LeftAnkleMedial:
                case BodyPOI.LeftAnkleLateral:
                case BodyPOI.LeftInstep:
                case BodyPOI.LeftHeelBack:
                case BodyPOI.LeftHeelBottom:
                case BodyPOI.LeftFootBottom:
                case BodyPOI.LeftFootMedial:
                case BodyPOI.LeftFootLateral:
                case BodyPOI.LeftFootBall:
                case BodyPOI.LeftToesTop:
                case BodyPOI.LeftToesMedial:
                case BodyPOI.LeftToesLateral:
                case BodyPOI.LeftFootTip:
                    return true;
                default:
                    return false;
            }
        }

        /// <summary>
        /// Tells whether the POI belongs strictly to the right half of the body.
        /// 
        /// This is false for central POIs that do not belong to any particular half.
        /// To this end, this function is NOT the inverse of BelongsToLeftHalf
        /// </summary>
        /// <param name="poi">the POI in question</param>
        public static bool BelongsToRightHalf(this BodyPOI poi)
        {
            switch (poi)
            {
                case BodyPOI.RightParietal:
                case BodyPOI.RightEarBehind:
                case BodyPOI.RightEarCenter:
                case BodyPOI.RightEarlobe:
                case BodyPOI.RightEye:
                case BodyPOI.RightEyebrow:
                case BodyPOI.RightCheekbone:
                case BodyPOI.RightTemple:
                case BodyPOI.RightMouthCorner:
                case BodyPOI.RightJawAngle:
                case BodyPOI.RightNeckSide:
                case BodyPOI.RightTrapezius:
                case BodyPOI.RightShoulderFront:
                case BodyPOI.RightShoulderBack:
                case BodyPOI.RightShoulderLateral:
                case BodyPOI.RightLateral:
                case BodyPOI.RightPectorial:
                case BodyPOI.RightNipple:
                case BodyPOI.RightAbdomen:
                case BodyPOI.RightWaist:
                case BodyPOI.RightPelvisLateral:
                case BodyPOI.RightArmpit:
                case BodyPOI.RightUpperArmFront:
                case BodyPOI.RightUpperArmBack:
                case BodyPOI.RightUpperArmMedial:
                case BodyPOI.RightUpperArmLateral:
                case BodyPOI.RightElbow:
                case BodyPOI.RightInnerElbow:
                case BodyPOI.RightElbowMedial:
                case BodyPOI.RightElbowLateral:
                case BodyPOI.RightLowerArmFront:
                case BodyPOI.RightLowerArmBack:
                case BodyPOI.RightLowerArmMedial:
                case BodyPOI.RightLowerArmLateral:
                case BodyPOI.RightWristMedial:
                case BodyPOI.RightWristLateral:
                case BodyPOI.RightWristFront:
                case BodyPOI.RightWristBack:
                case BodyPOI.RightHandPalm:
                case BodyPOI.RightHandBack:
                case BodyPOI.RightHandSide:
                case BodyPOI.RightKnuckle:
                case BodyPOI.RightIndexTip:
                case BodyPOI.RightThumbTip:
                case BodyPOI.RightThighFront:
                case BodyPOI.RightThighBack:
                case BodyPOI.RightThighMedial:
                case BodyPOI.RightThighLateral:
                case BodyPOI.RightKnee:
                case BodyPOI.RightBackKnee:
                case BodyPOI.RightKneeMedial:
                case BodyPOI.RightKneeLateral:
                case BodyPOI.RightCalfMedial:
                case BodyPOI.RightCalfLateral:
                case BodyPOI.RightCalf:
                case BodyPOI.RightShin:
                case BodyPOI.RightAchillesHeel:
                case BodyPOI.RightAnkleFront:
                case BodyPOI.RightAnkleMedial:
                case BodyPOI.RightAnkleLateral:
                case BodyPOI.RightInstep:
                case BodyPOI.RightHeelBack:
                case BodyPOI.RightHeelBottom:
                case BodyPOI.RightFootBottom:
                case BodyPOI.RightFootMedial:
                case BodyPOI.RightFootLateral:
                case BodyPOI.RightFootBall:
                case BodyPOI.RightToesTop:
                case BodyPOI.RightToesMedial:
                case BodyPOI.RightToesLateral:
                case BodyPOI.RightFootTip:
                    return true;
                default:
                    return false;
            }
        }

        /// <summary>
        /// Mirrors a POI.
        /// 
        /// If the POI belongs to a particular half of the body, this will return the corresponding POI on the other half.
        /// Otherwise, the input POI is returned.
        /// </summary>
        /// <param name="poi">the POI in question</param>
        public static BodyPOI Mirror(this BodyPOI poi)
        {
            return poi switch
            {
                BodyPOI.LeftParietal => BodyPOI.RightParietal,
                BodyPOI.LeftEarBehind => BodyPOI.RightEarBehind,
                BodyPOI.LeftEarCenter => BodyPOI.RightEarCenter,
                BodyPOI.LeftEarlobe => BodyPOI.RightEarlobe,
                BodyPOI.LeftEye => BodyPOI.RightEye,
                BodyPOI.LeftEyebrow => BodyPOI.RightEyebrow,
                BodyPOI.LeftCheekbone => BodyPOI.RightCheekbone,
                BodyPOI.LeftTemple => BodyPOI.RightTemple,
                BodyPOI.LeftMouthCorner => BodyPOI.RightMouthCorner,
                BodyPOI.LeftJawAngle => BodyPOI.RightJawAngle,
                BodyPOI.LeftNeckSide => BodyPOI.RightNeckSide,
                BodyPOI.LeftTrapezius => BodyPOI.RightTrapezius,
                BodyPOI.LeftShoulderFront => BodyPOI.RightShoulderFront,
                BodyPOI.LeftShoulderBack => BodyPOI.RightShoulderBack,
                BodyPOI.LeftShoulderLateral => BodyPOI.RightShoulderLateral,
                BodyPOI.LeftLateral => BodyPOI.RightLateral,
                BodyPOI.LeftPectorial => BodyPOI.RightPectorial,
                BodyPOI.LeftNipple => BodyPOI.RightNipple,
                BodyPOI.LeftAbdomen => BodyPOI.RightAbdomen,
                BodyPOI.LeftWaist => BodyPOI.RightWaist,
                BodyPOI.LeftPelvisLateral => BodyPOI.RightPelvisLateral,
                BodyPOI.LeftArmpit => BodyPOI.RightArmpit,
                BodyPOI.LeftUpperArmFront => BodyPOI.RightUpperArmFront,
                BodyPOI.LeftUpperArmBack => BodyPOI.RightUpperArmBack,
                BodyPOI.LeftUpperArmMedial => BodyPOI.RightUpperArmMedial,
                BodyPOI.LeftUpperArmLateral => BodyPOI.RightUpperArmLateral,
                BodyPOI.LeftElbow => BodyPOI.RightElbow,
                BodyPOI.LeftInnerElbow => BodyPOI.RightInnerElbow,
                BodyPOI.LeftElbowMedial => BodyPOI.RightElbowMedial,
                BodyPOI.LeftElbowLateral => BodyPOI.RightElbowLateral,
                BodyPOI.LeftLowerArmFront => BodyPOI.RightLowerArmFront,
                BodyPOI.LeftLowerArmBack => BodyPOI.RightLowerArmBack,
                BodyPOI.LeftLowerArmMedial => BodyPOI.RightLowerArmMedial,
                BodyPOI.LeftLowerArmLateral => BodyPOI.RightLowerArmLateral,
                BodyPOI.LeftWristMedial => BodyPOI.RightWristMedial,
                BodyPOI.LeftWristLateral => BodyPOI.RightWristLateral,
                BodyPOI.LeftWristFront => BodyPOI.RightWristFront,
                BodyPOI.LeftWristBack => BodyPOI.RightWristBack,
                BodyPOI.LeftHandPalm => BodyPOI.RightHandPalm,
                BodyPOI.LeftHandBack => BodyPOI.RightHandBack,
                BodyPOI.LeftHandSide => BodyPOI.RightHandSide,
                BodyPOI.LeftKnuckle => BodyPOI.RightKnuckle,
                BodyPOI.LeftIndexTip => BodyPOI.RightIndexTip,
                BodyPOI.LeftThumbTip => BodyPOI.RightThumbTip,
                BodyPOI.LeftThighFront => BodyPOI.RightThighFront,
                BodyPOI.LeftThighBack => BodyPOI.RightThighBack,
                BodyPOI.LeftThighMedial => BodyPOI.RightThighMedial,
                BodyPOI.LeftThighLateral => BodyPOI.RightThighLateral,
                BodyPOI.LeftKnee => BodyPOI.RightKnee,
                BodyPOI.LeftBackKnee => BodyPOI.RightBackKnee,
                BodyPOI.LeftKneeMedial => BodyPOI.RightKneeMedial,
                BodyPOI.LeftKneeLateral => BodyPOI.RightKneeLateral,
                BodyPOI.LeftCalfMedial => BodyPOI.RightCalfMedial,
                BodyPOI.LeftCalfLateral => BodyPOI.RightCalfLateral,
                BodyPOI.LeftCalf => BodyPOI.RightCalf,
                BodyPOI.LeftShin => BodyPOI.RightShin,
                BodyPOI.LeftAchillesHeel => BodyPOI.RightAchillesHeel,
                BodyPOI.LeftAnkleFront => BodyPOI.RightAnkleFront,
                BodyPOI.LeftAnkleMedial => BodyPOI.RightAnkleMedial,
                BodyPOI.LeftAnkleLateral => BodyPOI.RightAnkleLateral,
                BodyPOI.LeftInstep => BodyPOI.RightInstep,
                BodyPOI.LeftHeelBack => BodyPOI.RightHeelBack,
                BodyPOI.LeftHeelBottom => BodyPOI.RightHeelBottom,
                BodyPOI.LeftFootBottom => BodyPOI.RightFootBottom,
                BodyPOI.LeftFootMedial => BodyPOI.RightFootMedial,
                BodyPOI.LeftFootLateral => BodyPOI.RightFootLateral,
                BodyPOI.LeftFootBall => BodyPOI.RightFootBall,
                BodyPOI.LeftToesTop => BodyPOI.RightToesTop,
                BodyPOI.LeftToesMedial => BodyPOI.RightToesMedial,
                BodyPOI.LeftToesLateral => BodyPOI.RightToesLateral,
                BodyPOI.LeftFootTip => BodyPOI.RightFootTip,
                BodyPOI.RightParietal => BodyPOI.LeftParietal,
                BodyPOI.RightEarBehind => BodyPOI.LeftEarBehind,
                BodyPOI.RightEarCenter => BodyPOI.LeftEarCenter,
                BodyPOI.RightEarlobe => BodyPOI.LeftEarlobe,
                BodyPOI.RightEye => BodyPOI.LeftEye,
                BodyPOI.RightEyebrow => BodyPOI.LeftEyebrow,
                BodyPOI.RightCheekbone => BodyPOI.LeftCheekbone,
                BodyPOI.RightTemple => BodyPOI.LeftTemple,
                BodyPOI.RightMouthCorner => BodyPOI.LeftMouthCorner,
                BodyPOI.RightJawAngle => BodyPOI.LeftJawAngle,
                BodyPOI.RightNeckSide => BodyPOI.LeftNeckSide,
                BodyPOI.RightTrapezius => BodyPOI.LeftTrapezius,
                BodyPOI.RightShoulderFront => BodyPOI.LeftShoulderFront,
                BodyPOI.RightShoulderBack => BodyPOI.LeftShoulderBack,
                BodyPOI.RightShoulderLateral => BodyPOI.LeftShoulderLateral,
                BodyPOI.RightLateral => BodyPOI.LeftLateral,
                BodyPOI.RightPectorial => BodyPOI.LeftPectorial,
                BodyPOI.RightNipple => BodyPOI.LeftNipple,
                BodyPOI.RightAbdomen => BodyPOI.LeftAbdomen,
                BodyPOI.RightWaist => BodyPOI.LeftWaist,
                BodyPOI.RightPelvisLateral => BodyPOI.LeftPelvisLateral,
                BodyPOI.RightArmpit => BodyPOI.LeftArmpit,
                BodyPOI.RightUpperArmFront => BodyPOI.LeftUpperArmFront,
                BodyPOI.RightUpperArmBack => BodyPOI.LeftUpperArmBack,
                BodyPOI.RightUpperArmMedial => BodyPOI.LeftUpperArmMedial,
                BodyPOI.RightUpperArmLateral => BodyPOI.LeftUpperArmLateral,
                BodyPOI.RightElbow => BodyPOI.LeftElbow,
                BodyPOI.RightInnerElbow => BodyPOI.LeftInnerElbow,
                BodyPOI.RightElbowMedial => BodyPOI.LeftElbowMedial,
                BodyPOI.RightElbowLateral => BodyPOI.LeftElbowLateral,
                BodyPOI.RightLowerArmFront => BodyPOI.LeftLowerArmFront,
                BodyPOI.RightLowerArmBack => BodyPOI.LeftLowerArmBack,
                BodyPOI.RightLowerArmMedial => BodyPOI.LeftLowerArmMedial,
                BodyPOI.RightLowerArmLateral => BodyPOI.LeftLowerArmLateral,
                BodyPOI.RightWristMedial => BodyPOI.LeftWristMedial,
                BodyPOI.RightWristLateral => BodyPOI.LeftWristLateral,
                BodyPOI.RightWristFront => BodyPOI.LeftWristFront,
                BodyPOI.RightWristBack => BodyPOI.LeftWristBack,
                BodyPOI.RightHandPalm => BodyPOI.LeftHandPalm,
                BodyPOI.RightHandBack => BodyPOI.LeftHandBack,
                BodyPOI.RightHandSide => BodyPOI.LeftHandSide,
                BodyPOI.RightKnuckle => BodyPOI.LeftKnuckle,
                BodyPOI.RightIndexTip => BodyPOI.LeftIndexTip,
                BodyPOI.RightThumbTip => BodyPOI.LeftThumbTip,
                BodyPOI.RightThighFront => BodyPOI.LeftThighFront,
                BodyPOI.RightThighBack => BodyPOI.LeftThighBack,
                BodyPOI.RightThighMedial => BodyPOI.LeftThighMedial,
                BodyPOI.RightThighLateral => BodyPOI.LeftThighLateral,
                BodyPOI.RightKnee => BodyPOI.LeftKnee,
                BodyPOI.RightBackKnee => BodyPOI.LeftBackKnee,
                BodyPOI.RightKneeMedial => BodyPOI.LeftKneeMedial,
                BodyPOI.RightKneeLateral => BodyPOI.LeftKneeLateral,
                BodyPOI.RightCalfMedial => BodyPOI.LeftCalfMedial,
                BodyPOI.RightCalfLateral => BodyPOI.LeftCalfLateral,
                BodyPOI.RightCalf => BodyPOI.LeftCalf,
                BodyPOI.RightShin => BodyPOI.LeftShin,
                BodyPOI.RightAchillesHeel => BodyPOI.LeftAchillesHeel,
                BodyPOI.RightAnkleFront => BodyPOI.LeftAnkleFront,
                BodyPOI.RightAnkleMedial => BodyPOI.LeftAnkleMedial,
                BodyPOI.RightAnkleLateral => BodyPOI.LeftAnkleLateral,
                BodyPOI.RightInstep => BodyPOI.LeftInstep,
                BodyPOI.RightHeelBack => BodyPOI.LeftHeelBack,
                BodyPOI.RightHeelBottom => BodyPOI.LeftHeelBottom,
                BodyPOI.RightFootBottom => BodyPOI.LeftFootBottom,
                BodyPOI.RightFootMedial => BodyPOI.LeftFootMedial,
                BodyPOI.RightFootLateral => BodyPOI.LeftFootLateral,
                BodyPOI.RightFootBall => BodyPOI.LeftFootBall,
                BodyPOI.RightToesTop => BodyPOI.LeftToesTop,
                BodyPOI.RightToesMedial => BodyPOI.LeftToesMedial,
                BodyPOI.RightToesLateral => BodyPOI.LeftToesLateral,
                BodyPOI.RightFootTip => BodyPOI.LeftFootTip,
                _ => poi,
            };
        }
    }
}