using System;

namespace StudentAssignment
{
    // Student structure with private data members and public methods
    public struct Student
    {
        // Private data members
        private string name;
        private bool gender;    // true for Male, false for Female
        private int age;
        private int std;        // standard/class
        private char div;       // division
        private double marks;

        // Default constructor (parameterless)
        // Note: In C#, structs always have an implicit parameterless constructor
        // that initializes all fields to their default values
        public Student()
        {
            name = "";
            gender = true;  // default to male
            age = 0;
            std = 0;
            div = 'A';
            marks = 0.0;
        }

        // Parameterized constructor
        public Student(string name, bool gender, int age, int std, char div, double marks)
        {
            this.name = name;
            this.gender = gender;
            this.age = age;
            this.std = std;
            this.div = div;
            this.marks = marks;
        }

        // Get and Set methods for Name
        public string GetName()
        {
            return name;
        }

        public void SetName(string name)
        {
            this.name = name;
        }

        // Get and Set methods for Gender
        public bool GetGender()
        {
            return gender;
        }

        public void SetGender(bool gender)
        {
            this.gender = gender;
        }

        // Get and Set methods for Age
        public int GetAge()
        {
            return age;
        }

        public void SetAge(int age)
        {
            if (age > 0)
                this.age = age;
            else
                Console.WriteLine("Age must be positive!");
        }

        // Get and Set methods for Standard
        public int GetStd()
        {
            return std;
        }

        public void SetStd(int std)
        {
            if (std > 0)
                this.std = std;
            else
                Console.WriteLine("Standard must be positive!");
        }

        // Get and Set methods for Division
        public char GetDiv()
        {
            return div;
        }

        public void SetDiv(char div)
        {
            this.div = char.ToUpper(div);
        }

        // Get and Set methods for Marks
        public double GetMarks()
        {
            return marks;
        }

        public void SetMarks(double marks)
        {
            if (marks >= 0 && marks <= 100)
                this.marks = marks;
            else
                Console.WriteLine("Marks must be between 0 and 100!");
        }

        // AcceptDetails method to accept data from console
        public void AcceptDetails()
        {
            Console.WriteLine("\\n=== Enter Student Details ===");
            
            Console.Write("Enter Name: ");
            name = Console.ReadLine();

            Console.Write("Enter Gender (M/F): ");
            char genderInput = char.ToUpper(Console.ReadKey().KeyChar);
            gender = (genderInput == 'M');
            Console.WriteLine(); // New line after ReadKey

            Console.Write("Enter Age: ");
            try
            {
                age = Convert.ToInt32(Console.ReadLine());
            }
            catch (FormatException)
            {
                Console.WriteLine("Invalid age format. Setting to 0.");
                age = 0;
            }

            Console.Write("Enter Standard/Class: ");
            try
            {
                std = Convert.ToInt32(Console.ReadLine());
            }
            catch (FormatException)
            {
                Console.WriteLine("Invalid standard format. Setting to 0.");
                std = 0;
            }

            Console.Write("Enter Division: ");
            div = char.ToUpper(Console.ReadKey().KeyChar);
            Console.WriteLine(); // New line after ReadKey

            Console.Write("Enter Marks (0-100): ");
            try
            {
                marks = Convert.ToDouble(Console.ReadLine());
                if (marks < 0 || marks > 100)
                {
                    Console.WriteLine("Marks should be between 0-100. Setting to 0.");
                    marks = 0;
                }
            }
            catch (FormatException)
            {
                Console.WriteLine("Invalid marks format. Setting to 0.");
                marks = 0;
            }
        }

        // PrintDetails method to print data to console
        public void PrintDetails()
        {
            Console.WriteLine("\\n=== Student Details ===");
            Console.WriteLine($"Name: {name}");
            Console.WriteLine($"Gender: {(gender ? "Male" : "Female")}");
            Console.WriteLine($"Age: {age}");
            Console.WriteLine($"Standard: {std}");
            Console.WriteLine($"Division: {div}");
            Console.WriteLine($"Marks: {marks:F2}");
            
            // Additional info based on marks
            string grade = GetGrade();
            Console.WriteLine($"Grade: {grade}");
            Console.WriteLine(new string('-', 25));
        }

        // Helper method to calculate grade based on marks
        private string GetGrade()
        {
            if (marks >= 90) return "A+";
            else if (marks >= 80) return "A";
            else if (marks >= 70) return "B+";
            else if (marks >= 60) return "B";
            else if (marks >= 50) return "C";
            else if (marks >= 40) return "D";
            else return "F";
        }
    }

    // Main program to demonstrate the Student structure
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("=== Student Structure Assignment ===");
            Console.WriteLine("\\nDefault Access Specifier Information:");
            Console.WriteLine("- In C# structs, members are PRIVATE by default");
            Console.WriteLine("- In C# classes, members are PRIVATE by default");
            Console.WriteLine("- We explicitly made data members private and methods public\\n");

            // Demonstrate default constructor
            Console.WriteLine("1. Testing Default Constructor:");
            Student student1 = new Student();
            student1.PrintDetails();

            // Demonstrate parameterized constructor
            Console.WriteLine("\\n2. Testing Parameterized Constructor:");
            Student student2 = new Student("John Doe", true, 16, 10, 'A', 85.5);
            student2.PrintDetails();

            // Demonstrate Get/Set methods
            Console.WriteLine("\\n3. Testing Get/Set Methods:");
            student2.SetName("Jane Smith");
            student2.SetGender(false);
            student2.SetAge(15);
            student2.SetMarks(92.0);
            
            Console.WriteLine($"Updated Name: {student2.GetName()}");
            Console.WriteLine($"Updated Gender: {(student2.GetGender() ? "Male" : "Female")}");
            Console.WriteLine($"Updated Age: {student2.GetAge()}");
            Console.WriteLine($"Updated Marks: {student2.GetMarks()}");

            // Demonstrate AcceptDetails and PrintDetails
            Console.WriteLine("\\n4. Testing AcceptDetails Method:");
            Student student3 = new Student();
            student3.AcceptDetails();
            student3.PrintDetails();

            // Test validation in Set methods
            Console.WriteLine("\\n5. Testing Validation:");
            student3.SetAge(-5);     // Should show error
            student3.SetMarks(150);  // Should show error
            student3.SetStd(-2);     // Should show error

            Console.WriteLine("\\nProgram completed successfully!");
        }
    }
}

/*
OUTPUT EXPLANATION:

Default Access Specifier in C# Structures:
- By default, all members in a C# struct are PRIVATE
- This is the same as in C# classes
- We explicitly declared data members as private and methods as public
- This follows good encapsulation practices

Key Points about the Implementation:
1. All data members are private
2. All methods are public
3. Parameterized constructor initializes all fields
4. Get/Set methods provide controlled access to private data
5. AcceptDetails() handles user input with error checking
6. PrintDetails() displays formatted output
7. Additional validation ensures data integrity
8. Helper method GetGrade() demonstrates additional functionality

The structure follows object-oriented principles:
- Encapsulation: Private data, public methods
- Data validation in setter methods
- User-friendly input/output methods
- Error handling for invalid inputs
*/