#ifndef DISKIMAGE_H
#define DISKIMAGE_H
#include <QFile>
#include <QTemporaryFile>
#include "sioworker.h"
class AtariFileSystem;
class DiskEditDialog;
class DiskGeometry: public QObject
{
Q_OBJECT
private:
bool m_isDoubleSided;
quint8 m_tracksPerSide;
quint16 m_sectorsPerTrack;
quint16 m_bytesPerSector;
uint m_sectorCount;
uint m_totalSize;
public:
DiskGeometry(const DiskGeometry &other);
DiskGeometry();
void initialize(const DiskGeometry &other);
void initialize(bool aIsDoubleSided, quint8 aTracksPerSide, quint16 aSectorsPerTrack, quint16 aBytesPerSector);
void initialize(uint aTotalSize, quint16 aBytesPerSector);
void initialize(uint aTotalSize);
void initialize(const QByteArray &percom);
bool isEqual(const DiskGeometry &other);
bool isStandardSD() const;
bool isStandardED() const;
bool isStandardDD() const;
bool isStandardQD() const;
inline bool isDoubleSided() const {return m_isDoubleSided;}
inline quint8 tracksPerSide() const {return m_tracksPerSide;}
inline quint16 sectorsPerTrack() const {return m_sectorsPerTrack;}
inline quint16 bytesPerSector() const {return m_bytesPerSector;}
quint16 bytesPerSector(quint16 sector);
inline uint sectorCount() const {return m_sectorCount;}
inline uint totalSize() const {return m_totalSize;}
QByteArray toPercomBlock();
QString humanReadable() const;
};
class SimpleDiskImage: public SioDevice
{
Q_OBJECT
Q_ENUMS(ImageType)
public:
SimpleDiskImage(SioWorker *worker);
~SimpleDiskImage();
enum ImageType {Atr, Atz, Xfd, Xfz, Dcm, Scp, Di, Bin};
virtual bool open(const QString &fileName);
bool create(int untitledName);
void reopen();
virtual void close();
bool save();
bool saveAs(const QString &fileName);
inline bool isOpen() const {return file.isOpen();}
inline bool isReadOnly() const {return m_isReadOnly;}
inline void setReadOnly(bool readOnly) {m_isReadOnly = readOnly;}
inline bool isModified() const {return m_isModified;}
inline bool isUnmodifiable() const {return m_isUnmodifiable;}
inline bool isUnnamed() const {return m_isUnnamed;}
inline void setEditDialog(DiskEditDialog *aDialog) {m_editDialog = aDialog; emit statusChanged(m_deviceNo);}
inline DiskEditDialog* editDialog() {return m_editDialog;}
void handleCommand(quint8 command, quint16 aux);
virtual bool format(const DiskGeometry &geo);
virtual bool readSector(quint16 sector, QByteArray &data);
virtual bool writeSector(quint16 sector, const QByteArray &data);
inline DiskGeometry geometry() const {return m_geometry;}
inline QString originalFileName() const {return m_originalFileName;}
virtual QString description() const {return m_geometry.humanReadable();}
int defaultFileSystem();
protected:
DiskGeometry m_geometry, m_newGeometry;
QTemporaryFile file;
bool m_isReadOnly;
bool m_isModified;
bool m_isUnmodifiable;
bool m_isUnnamed;
QString m_originalFileName;
QByteArray m_originalAtrHeader;
ImageType m_originalImageType;
DiskEditDialog *m_editDialog;
bool seekToSector(quint16 sector);
void refreshNewGeometry();
bool openAtr(const QString &fileName);
bool openAtz(const QString &fileName);
bool openXfd(const QString &fileName);
bool openXfz(const QString &fileName);
bool openDcm(const QString &fileName);
bool openScp(const QString &fileName);
bool openDi(const QString &fileName);
bool openBin(const QString &fileName);
bool saveAtr(const QString &fileName);
bool saveAtz(const QString &fileName);
bool saveXfd(const QString &fileName);
bool saveXfz(const QString &fileName);
bool saveDcm(const QString &fileName);
bool saveScp(const QString &fileName);
bool saveDi(const QString &fileName);
bool saveBin(const QString &fileName);
};
#endif // DISKIMAGE_H