// Copyright (c) 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.xwalk.app;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import org.xwalk.app.runtime.extension.XWalkRuntimeExtensionManager;
import org.xwalk.app.runtime.XWalkRuntimeView;
import org.xwalk.core.XWalkActivity;
import org.xwalk.core.XWalkPreferences;

public abstract class XWalkRuntimeActivityBase extends XWalkActivity {
    private static final String TAG = "XWalkRuntimeActivityBase";

    private XWalkRuntimeView mRuntimeView;

    private boolean mRemoteDebugging = false;

    private boolean mUseAnimatableView = false;

    private XWalkRuntimeExtensionManager mExtensionManager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tryLoadRuntimeView();
    }

    @Override
    public void onXWalkReady() {
        // XWalkPreferences.ENABLE_EXTENSIONS
        if (XWalkPreferences.getValue("enable-extensions")) {
                // Enable xwalk extension mechanism and start load extensions here.
                // Note that it has to be after above initialization.
            mExtensionManager = new XWalkRuntimeExtensionManager(getApplicationContext(), this);
            mExtensionManager.loadExtensions();
        }
        didTryLoadRuntimeView(mRuntimeView);
        // TODO(sunlin): In shared mode, mRuntimeView.onCreate() will be
        // called after onResume(). Currently, there is no impact because
        // both of onCreate and onResume in XWalkRuntimeView is empty.
        if (mRuntimeView != null) mRuntimeView.onCreate();
    }

    @Override
    public void onStart() {
        super.onStart();
        if (mExtensionManager != null) mExtensionManager.onStart();
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mRuntimeView != null) mRuntimeView.onPause();
        if (mExtensionManager != null) mExtensionManager.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mRuntimeView != null) mRuntimeView.onResume();
        if (mExtensionManager != null) mExtensionManager.onResume();
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mExtensionManager != null) mExtensionManager.onStop();
    }

    @Override
    public void onDestroy() {
        if (mExtensionManager != null) mExtensionManager.onDestroy();
        super.onDestroy();
    }

    @Override
    public void onNewIntent(Intent intent) {
        if (mRuntimeView == null || !mRuntimeView.onNewIntent(intent)) super.onNewIntent(intent);
        if (mExtensionManager != null) mExtensionManager.onNewIntent(intent);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (mRuntimeView != null) mRuntimeView.onActivityResult(requestCode, resultCode, data);
        if (mExtensionManager != null) mExtensionManager.onActivityResult(requestCode, resultCode, data);
    }

    private void tryLoadRuntimeView() {
        try {
            if (mUseAnimatableView) {
                XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, true);
            } else {
                XWalkPreferences.setValue(XWalkPreferences.ANIMATABLE_XWALK_VIEW, false);
            }
            mRuntimeView = new XWalkRuntimeView(this, this, null);
            if (mRemoteDebugging) {
                XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
            } else {
                XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
            }
            setContentView(mRuntimeView);
        } catch (Exception e) {
            handleException(e);
        }
    }

    public XWalkRuntimeView getRuntimeView() {
        return mRuntimeView;
    }

    public void handleException(Throwable e) {
        if (e == null) return;
        if (e instanceof RuntimeException && e.getCause() != null) {
            handleException(e.getCause());
            return;
        }
        Log.e(TAG, Log.getStackTraceString(e));
    }

    /*
     * Called each time trying to load runtime view from library apk.
     * Descendant should handle both succeeded and failed to load
     * library apk.
     *
     * @param, The RuntimeView loaded, it can be null for failed to load RuntimeView.
     */
    abstract protected void didTryLoadRuntimeView(View runtimeView);

    public void setRemoteDebugging(boolean value) {
        mRemoteDebugging = value;
    }

    public void setUseAnimatableView(boolean value) {
        mUseAnimatableView = value;
    }

    @Override
    public boolean isXWalkReady() {
        return super.isXWalkReady();
    }
}

@@ -352,16 +352,45 @@
 ew.View;
+%0Aimport android.widget.Toast;
 %0A%0Aimport
@@ -526,32 +526,40 @@
 re.XWalkActivity
+Delegate
 ;%0Aimport org.xwa
@@ -640,21 +640,16 @@
 extends 
-XWalk
 Activity
@@ -760,16 +760,69 @@
 imeView;
+%0A    private XWalkActivityDelegate mActivityDelegate;
 %0A%0A    pr
@@ -1080,24 +1080,698 @@
 anceState);%0A
+%0A        Runnable cancelCommand = new Runnable() %7B%0A            @Override%0A            public void run() %7B%0A                if (mActivityDelegate.isDownloadMode()) %7B%0A                    Toast.makeText(XWalkRuntimeActivityBase.this,%0A                            %22Crosswalk Runtime Update Failed!%22,%0A                            Toast.LENGTH_LONG).show();%0A                %7D%0A                finish();%0A            %7D%0A        %7D;%0A        Runnable completeCommand = new Runnable() %7B%0A            @Override%0A            public void run() %7B%0A                onXWalkReady();%0A            %7D%0A        %7D;%0A        mActivityDelegate = new XWalkActivityDelegate(this, cancelCommand, completeCommand);%0A%0A
         tryL
@@ -1791,38 +1791,24 @@
 w();%0A    %7D%0A%0A
-    @Override%0A
     public v
@@ -2977,32 +2977,70 @@
 per.onResume();%0A
+        mActivityDelegate.onResume();%0A
         if (mRun
@@ -5668,38 +5668,24 @@
 lue;%0A    %7D%0A%0A
-    @Override%0A
     public b
@@ -5723,21 +5723,33 @@
  return 
-super
+mActivityDelegate
 .isXWalk

Refactor XWalkRuntimeActivityBase and make it support download mode