// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';
import 'dart:ffi';

class SeismicRecord {
  const SeismicRecord({
    required this.ffid,
    required this.gpsDateTime,
    required this.gpsTimeInMicroseconds,
    required this.imageUrl,
    required this.maxReceiverPointFduNumber,
    required this.minReceiverPointFduNumber,
    required this.minReceiverPointNumber,
    required this.maxReceiverPointNumber,
    required this.sourceLine,
    required this.sourcePoint,
  });

  final int ffid;
  final DateTime gpsDateTime;
  final int gpsTimeInMicroseconds;
  final String imageUrl;
  final int maxReceiverPointFduNumber;
  final int minReceiverPointFduNumber;
  final int minReceiverPointNumber;
  final int maxReceiverPointNumber;
  final double sourceLine;
  final double sourcePoint;

  SeismicRecord copyWith({
    int? ffid,
    DateTime? gpsDateTime,
    int? gpsTimeInMicroseconds,
    String? imageUrl,
    int? maxReceiverPointFduNumber,
    int? minReceiverPointFduNumber,
    int? minReceiverPointNumber,
    int? maxReceiverPointNumber,
    double? sourceLine,
    double? sourcePoint,
  }) {
    return SeismicRecord(
      ffid: ffid ?? this.ffid,
      gpsDateTime: gpsDateTime ?? this.gpsDateTime,
      gpsTimeInMicroseconds:
          gpsTimeInMicroseconds ?? this.gpsTimeInMicroseconds,
      imageUrl: imageUrl ?? this.imageUrl,
      maxReceiverPointFduNumber:
          maxReceiverPointFduNumber ?? this.maxReceiverPointFduNumber,
      minReceiverPointFduNumber:
          minReceiverPointFduNumber ?? this.minReceiverPointFduNumber,
      minReceiverPointNumber:
          minReceiverPointNumber ?? this.minReceiverPointNumber,
      maxReceiverPointNumber:
          maxReceiverPointNumber ?? this.maxReceiverPointNumber,
      sourceLine: sourceLine ?? this.sourceLine,
      sourcePoint: sourcePoint ?? this.sourcePoint,
    );
  }

  Map<String, dynamic> toMap() {
    return <String, dynamic>{
      'ffid': ffid,
      'gpsDateTime': gpsDateTime.millisecondsSinceEpoch,
      'gpsTimeInMicroseconds': gpsTimeInMicroseconds,
      'imageUrl': imageUrl,
      'maxReceiverPointFduNumber': maxReceiverPointFduNumber,
      'minReceiverPointFduNumber': minReceiverPointFduNumber,
      'minReceiverPointNumber': minReceiverPointNumber,
      'maxReceiverPointNumber': maxReceiverPointNumber,
      'sourceLine': sourceLine,
      'sourcePoint': sourcePoint,
    };
  }

  factory SeismicRecord.fromMap(Map<String, dynamic> map) {
    return SeismicRecord(
      ffid: map['ffid'] as int,
      gpsDateTime:
          DateTime.fromMillisecondsSinceEpoch(map['gpsDateTime'] as int),
      gpsTimeInMicroseconds: map['gpsTimeInMicroseconds'] as int,
      imageUrl: map['imageUrl'] as String,
      maxReceiverPointFduNumber: map['maxReceiverPointFduNumber'] as int,
      minReceiverPointFduNumber: map['minReceiverPointFduNumber'] as int,
      minReceiverPointNumber: map['minReceiverPointNumber'] as int,
      maxReceiverPointNumber: map['maxReceiverPointNumber'] as int,
      sourceLine: map['sourceLine'] as double,
      sourcePoint: map['sourcePoint'] as double,
    );
  }

  String toJson() => json.encode(toMap());

  factory SeismicRecord.fromJson(String source) =>
      SeismicRecord.fromMap(json.decode(source) as Map<String, dynamic>);

  @override
  String toString() {
    return 'SeismicRecord(ffid: $ffid, gpsDateTime: $gpsDateTime, gpsTimeInMicroseconds: $gpsTimeInMicroseconds, imageUrl: $imageUrl, maxReceiverPointFduNumber: $maxReceiverPointFduNumber, minReceiverPointFduNumber: $minReceiverPointFduNumber, minReceiverPointNumber: $minReceiverPointNumber, maxReceiverPointNumber: $maxReceiverPointNumber, sourceLine: $sourceLine, sourcePoint: $sourcePoint)';
  }

  @override
  bool operator ==(covariant SeismicRecord other) {
    if (identical(this, other)) return true;

    return other.ffid == ffid &&
        other.gpsDateTime == gpsDateTime &&
        other.gpsTimeInMicroseconds == gpsTimeInMicroseconds &&
        other.imageUrl == imageUrl &&
        other.maxReceiverPointFduNumber == maxReceiverPointFduNumber &&
        other.minReceiverPointFduNumber == minReceiverPointFduNumber &&
        other.minReceiverPointNumber == minReceiverPointNumber &&
        other.maxReceiverPointNumber == maxReceiverPointNumber &&
        other.sourceLine == sourceLine &&
        other.sourcePoint == sourcePoint;
  }

  @override
  int get hashCode {
    return ffid.hashCode ^
        gpsDateTime.hashCode ^
        gpsTimeInMicroseconds.hashCode ^
        imageUrl.hashCode ^
        maxReceiverPointFduNumber.hashCode ^
        minReceiverPointFduNumber.hashCode ^
        minReceiverPointNumber.hashCode ^
        maxReceiverPointNumber.hashCode ^
        sourceLine.hashCode ^
        sourcePoint.hashCode;
  }
}
