using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarManagerV3
{
///
/// Class Car represents a car with various attributes such as make, model, year, color, mileage, and price.
///
public class Car
{
private int id;
private string make;
private string model;
private int year;
private string color;
private int mileage;
private decimal price;
private int order;
public int Id { get => id;
set {
if (value < 0) throw new ArgumentException("Id cannot be negative.");
id = value;
}
}
public string Make { get => make;
set
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Make cannot be empty.");
make = value;
}
}
public string Model { get => model;
set
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Model cannot be empty.");
model = value;
}
}
public int Year { get => year;
set
{
if (value < 1886 || value > DateTime.Now.Year + 1) throw new ArgumentException("Year must be between 1886 and next year.");
year = value;
}
}
public string Color { get => color;
set
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Color cannot be empty.");
color = value;
}
}
public int Mileage { get => mileage;
set
{
if (value < 0) throw new ArgumentException("Mileage cannot be negative.");
mileage = value;
}
}
public decimal Price { get => price;
set
{
if (value < 0) throw new ArgumentException("Price cannot be negative.");
price = value;
}
}
public int Order { get => order; set => order = value; }
public int Age { get => DateTime.Now.Year - year; }
public string AgeString
{
get
{
int age = this.Age;
if (age == 0) return "New";
else if (age == 1) return "1 year";
else if (age < 0) return "From the future!";
else return $"{age} years";
}
}
//TODO: Make Id read-only CUID. Allows for better integrity, especially when merging.
//TODO: Add buying price and automatic calculation of profit/loss with selling price suggestion.
//TODO: Add Buying Date.
//TODO: Add sold boolean and Sold Date.
//TODO: Add "hidden" attribute for cars that are not for sale anymore but should be kept in the database for records.
///
/// Initializes a new instance of the class.
///
/// The unique identifier as an Integer.
/// The make / manufacturer of the car.
/// The model.
/// The year the car was built.
/// The color of the car.
/// The current mileage on the car.
/// The selling-price of the car.
/// The order.
public Car(int id, string make, string model, int year, string color, int mileage, decimal price, int order = 0)
{
// Sets the properties using the setters to ensure validation is applied.
this.Id = id;
this.Make = make;
this.Model = model;
this.Year = year;
this.Color = color;
this.Mileage = mileage;
this.Price = price;
this.Order = order;
}
///
/// Converts to string in a custom readable format.
///
/// For Example:
/// Skoda Fabia (2015)
///
///
///
/// A that represents this instance.
///
public override string ToString()
{
return $"{this.Make} {this.Model} ({this.Year})";
}
///
/// Converts to default CSV savable string.
///
///
public string ToCsvString()
{
return $"{this.Id};{this.Make};{this.Model};{this.Year};{this.Color};{this.Mileage};{this.Price}";
}
//TODO: Add error handling for malformed CSV strings and detection for missing fields.
//TODO: Add support for different CSV formats (e.g., different delimiters, quoted fields, etc.).
//TODO: Add support for nil or optional fields.
//TODO: Add detectin for invalid data / nonsensical values (e.g., negative mileage or year in the future). / Validate it actually is a car.
///
/// Creates a instance from a CSV string in the default format.
///
/// The CSV Line.
///
/// A new instance.
///
public static Car FromCsvString(string csv)
{
try
{
string[] parts = csv.Split(';');
Car temp = new Car(int.Parse(parts[0]), parts[1], parts[2], int.Parse(parts[3]), parts[4], int.Parse(parts[5]), decimal.Parse(parts[6]));
if (temp.Year < 1886 || temp.Year > DateTime.Now.Year + 1) throw new Exception($"Invalid year: {temp.Year}");
if (temp.Mileage < 0) throw new Exception($"Mileage cannot be negative: {temp.Mileage}");
if (temp.Price < 0) throw new Exception($"Price cannot be negative: {temp.Price}");
return temp;
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error parsing CSV Car string: {ex.Message}");
return null;
}
}
///
/// Determines whether this is any different from the provided .
///
/// The to check against
///
/// true if the specified other is changed; otherwise, false.
///
public bool IsChanged(Car other)
{
return this.Make != other.Make || this.Model != other.Model || this.Year != other.Year || this.Color != other.Color || this.Mileage != other.Mileage || this.Price != other.Price || this.Color != other.Color;
}
///
/// Clones this instance.
///
/// An identical but seperate
public Car Clone()
{
return new Car(this.Id, this.Make, this.Model, this.Year, this.Color, this.Mileage, this.Price);
}
}
}