package com.android.gallery3d.data;

import android.content.Context;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.mtp.MtpObjectInfo;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.android.gallery3d.R;
import com.android.gallery3d.util.BucketNames;
import com.android.gallery3d.util.GalleryUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class MtpContext implements MtpClient.Listener {
    private static final String TAG = "MtpContext";

    private ScannerClient mScannerClient;
    private Context mContext;
    private MtpClient mClient;

    private static final class ScannerClient implements MediaScannerConnectionClient {
        ArrayList<String> mPaths = new ArrayList<String>();
        MediaScannerConnection mScannerConnection;
        boolean mConnected;
        Object mLock = new Object();

        public ScannerClient(Context context) {
            mScannerConnection = new MediaScannerConnection(context, this);
        }

        public void scanPath(String path) {
            synchronized (mLock) {
                if (mConnected) {
                    mScannerConnection.scanFile(path, null);
                } else {
                    mPaths.add(path);
                    mScannerConnection.connect();
                }
            }
        }

        @Override
        public void onMediaScannerConnected() {
            synchronized (mLock) {
                mConnected = true;
                if (!mPaths.isEmpty()) {
                    for (String path : mPaths) {
                        mScannerConnection.scanFile(path, null);
                    }
                    mPaths.clear();
                }
            }
        }

        @Override
        public void onScanCompleted(String path, Uri uri) {
        }
    }

    public MtpContext(Context context) {
        mContext = context;
        mScannerClient = new ScannerClient(context);
        mClient = new MtpClient(mContext);
    }

    public void pause() {
        mClient.removeListener(this);
    }

    public void resume() {
        mClient.addListener(this);
        notifyDirty();
    }

    public void deviceAdded(android.mtp.MtpDevice device) {
        notifyDirty();
        showToast(R.string.camera_connected);
    }

    public void deviceRemoved(android.mtp.MtpDevice device) {
        notifyDirty();
        showToast(R.string.camera_disconnected);
    }

    private void notifyDirty() {
        mContext.getContentResolver().notifyChange(Uri.parse("mtp://"), null);
    }

    private void showToast(final int msg) {
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
    }

    public MtpClient getMtpClient() {
        return mClient;
    }

    public boolean copyFile(String deviceName, MtpObjectInfo objInfo) {
        if (GalleryUtils.hasSpaceForSize(objInfo.getCompressedSize())) {
            File dest = Environment.getExternalStorageDirectory();
            dest = new File(dest, BucketNames.IMPORTED);
            dest.mkdirs();
            String destPath = new File(dest, objInfo.getName()).getAbsolutePath();
            int objectId = objInfo.getObjectHandle();
            if (mClient.importFile(deviceName, objectId, destPath)) {
                mScannerClient.scanPath(destPath);
                return true;
            }
        } else {
            Log.w(TAG, "No space to import " + objInfo.getName() +
                    " whose size = " + objInfo.getCompressedSize());
        }
        return false;
    }

    public boolean copyAlbum(String deviceName, String albumName,
            List<MtpObjectInfo> children) {
        File dest = Environment.getExternalStorageDirectory();
        dest = new File(dest, albumName);
        dest.mkdirs();
        int success = 0;
        for (MtpObjectInfo child : children) {
            if (!GalleryUtils.hasSpaceForSize(child.getCompressedSize())) continue;

            File importedFile = new File(dest, child.getName());
            String path = importedFile.getAbsolutePath();
            if (mClient.importFile(deviceName, child.getObjectHandle(), path)) {
                mScannerClient.scanPath(path);
                success++;
            }
        }
        return success == children.size();
    }
}
