content: package hundredthirtythree.boxca;
  
  import android.Manifest;
  import android.animation.Animator;
  import android.animation.AnimatorListenerAdapter;
  import android.animation.ArgbEvaluator;
  import android.animation.ValueAnimator;
  import android.content.ClipData;
  import android.content.ClipboardManager;
  import android.content.Context;
  import android.content.Intent;
  import android.content.pm.PackageManager;
  import android.net.Uri;
  import android.os.Build;
  import android.os.Handler;
  import android.support.v4.app.ActivityCompat;
  import android.support.v4.content.ContextCompat;
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.util.Log;
  import java.io.BufferedInputStream;
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
  import android.app.Activity;
  import android.app.ProgressDialog;
  import android.view.View;
  import android.view.Window;
  import android.view.WindowManager;
  import android.view.animation.LinearInterpolator;
  import android.widget.AdapterView;
  import android.widget.ArrayAdapter;
  import android.widget.Button;
  import android.widget.ImageView;
  import android.widget.RelativeLayout;
  import android.widget.Spinner;
  import android.widget.TextView;
  import android.widget.Toast;
  import com.github.florent37.viewanimator.AnimationListener;
  import com.github.florent37.viewanimator.ViewAnimator;
  import org.json.JSONException;
  import org.json.JSONObject;
  import java.io.DataOutputStream;
  import java.io.FileNotFoundException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.net.HttpURLConnection;
  import java.net.MalformedURLException;
  import java.net.URL;
  
  public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  
      private static final int PICK_FILE_REQUEST = 1;
      private static final String TAG = MainActivity.class.getSimpleName();
      private String selectedFilePath;
      private String SERVER_URL = "https://file.io/?expires=1d";
      ImageView ivAttachment;
      Button bUpload;
      static ProgressDialog dialog;
      RelativeLayout uploadToServer, uploadPopup, successWindow;
      Window window;
      Button uploadBtn, cancelBtn;
      ImageView closeSuccess, shareSuccess;
      int statusBarColor;
      TextView tvfileName, fileNamePopup, textSuccess, link, termOfService;
      Spinner spinner;
      Handler mainHandler;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_upload_to_server);
          mainHandler = new Handler(getApplicationContext().getMainLooper());
          findViews();
          requestPermission();
          ViewAnimator
                  .animate(ivAttachment)
                  .duration(1000)
                  .bounce().interpolator(new LinearInterpolator())
                  .accelerate()
                  .repeatCount(2)
                  .start();
      }
  
      void findViews() {
          window = this.getWindow();
          statusBarColor = this.getResources().getColor(R.color.colorAccent);
          ivAttachment = (ImageView) findViewById(R.id.ivAttachment);
          tvfileName = (TextView) findViewById(R.id.textView5);
          closeSuccess = (ImageView) findViewById(R.id.closeSuccessPopup);
          textSuccess = (TextView) findViewById(R.id.textSuccess);
          termOfService = (TextView) findViewById(R.id.textView);
          link = (TextView) findViewById(R.id.link);
          spinner = (Spinner) findViewById(R.id.spinner);
          uploadBtn = (Button) findViewById(R.id.uploadButton);
          cancelBtn = (Button) findViewById(R.id.cancel_action);
          bUpload = (Button) findViewById(R.id.b_upload);
          fileNamePopup = (TextView) findViewById(R.id.fileName);
          uploadToServer = (RelativeLayout) findViewById(R.id.uploadToServer);
          uploadPopup = (RelativeLayout) findViewById(R.id.uploadPopup);
          successWindow = (RelativeLayout) findViewById(R.id.success);
          shareSuccess = (ImageView) findViewById(R.id.shareSuccessPopup);
          ivAttachment.setOnClickListener(this);
          bUpload.setOnClickListener(this);
          tvfileName.setOnClickListener(this);
          cancelBtn.setOnClickListener(this);
          uploadBtn.setOnClickListener(this);
          link.setOnClickListener(this);
          closeSuccess.setOnClickListener(this);
          termOfService.setOnClickListener(this);
          shareSuccess.setOnClickListener(this);
          ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                  R.array.days_array, android.R.layout.simple_spinner_item);
          adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
          spinner.setAdapter(adapter);
  
          spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
              @Override
              public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                  switch (i) {
                      case 0:
                          SERVER_URL = "https://file.io/?expires=1d";
                          return;
                      case 1:
                          SERVER_URL = "https://file.io/?expires=3d";
                          return;
                      case 2:
                          SERVER_URL = "https://file.io/?expires=5d";
                          return;
                      case 3:
                          SERVER_URL = "https://file.io/?expires=1w";
                          return;
                      case 4:
                          SERVER_URL = "https://file.io/?expires=1m";
                          return;
                      case 5:
                          SERVER_URL = "https://file.io/?expires=1y";
                          return;
                      default:
                          SERVER_URL = "https://file.io/?expires=1d";
                  }
              }
  
              @Override
              public void onNothingSelected(AdapterView<?> adapterView) {
                  SERVER_URL = "https://file.io/?expires=1d";
              }
          });
      }
  
      @Override
      public void onRequestPermissionsResult(int requestCode,
                                             String permissions[], int[] grantResults) {
          if (grantResults.length > 0) {
              if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                  //Do the stuff that requires permission...
                  tvfileName.setText(R.string.choose_file);
              } else if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                  // Should we show an explanation?
                  if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                      //Show permission explanation dialog...
                  } else {
                      tvfileName.setText(R.string.permission_required);
                      changeBackgroundColor(uploadToServer, R.color.backgroundColor, R.color.errorColor);
                      changeStatusBarColor(R.color.errorColor);
                      //Never ask again selected, or device policy prohibits the app from having that permission.
                      //So, disable that feature, or fall back to another situation...
                  }
              }
          }
      }
  
      void requestPermission() {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
              if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                  ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
              } else {
                  //Do the stuff that requires permission...
              }
          }
      }
  
      @Override
      public void onClick(View v) {
          if (v == ivAttachment || v == tvfileName) {
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                  if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                      requestPermission();
                  } else {
                      showFileChooser();
                      Log.e(TAG, "onClick: not given");
                  }
              } else {
                  showFileChooser();
              }
          }
  
          if (v == uploadBtn) {
              //on upload button Click
              if (selectedFilePath != null) {
                  dialog = ProgressDialog.show(MainActivity.this, "", getString(R.string.uploading_file), true);
                  new Thread(new Runnable() {
                      @Override
                      public void run() {
                          //creating new thread to handle Http Operations
                          uploadFile(selectedFilePath);
                      }
                  }).start();
              } else {
                  Toast.makeText(MainActivity.this, R.string.choose_file_first, Toast.LENGTH_SHORT).show();
              }
          }
  
          if (v == cancelBtn) {
              uploadPopup.animate()
                      .translationY(uploadPopup.getHeight())
                      .alpha(0.0f)
                      .setDuration(300)
                      .setListener(new AnimatorListenerAdapter() {
                          @Override
                          public void onAnimationEnd(Animator animation) {
                              super.onAnimationEnd(animation);
                              uploadPopup.setVisibility(View.GONE);
                          }
                      });
              changeBackgroundColor(uploadToServer, R.color.steadyColor, R.color.backgroundColor);
              changeStatusBarColor(R.color.backgroundColor);
              termOfService.setVisibility(View.VISIBLE);
          }
  
          if (v == closeSuccess) {
              uploadPopup.animate()
                      .translationY(successWindow.getHeight())
                      .alpha(0.0f)
                      .setDuration(300)
                      .setListener(new AnimatorListenerAdapter() {
                          @Override
                          public void onAnimationEnd(Animator animation) {
                              super.onAnimationEnd(animation);
                              successWindow.setVisibility(View.GONE);
                              uploadToServer.setVisibility(View.VISIBLE);
                              changeBackgroundColor(uploadToServer, R.color.successColor, R.color.backgroundColor);
                              changeStatusBarColor(R.color.backgroundColor);
                          }
                      });
              termOfService.setVisibility(View.VISIBLE);
          }
  
          if (v == shareSuccess) {
              Intent shareIntent = new Intent(Intent.ACTION_SEND);
              shareIntent.putExtra(Intent.EXTRA_TEXT, link.getText());
              shareIntent.setType("text/plain");
              startActivity(shareIntent);
          }
  
          if (v == link) {
              ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
              ClipData clip = ClipData.newPlainText(link.getText().toString(), link.getText().toString());
              clipboard.setPrimaryClip(clip);
              Toast.makeText(this, R.string.link_copied, Toast.LENGTH_SHORT).show();
          }
  
          if (v == termOfService) {
              Intent i = new Intent(Intent.ACTION_VIEW);
              i.setData(Uri.parse("https://www.file.io/tos.html"));
              startActivity(i);
          }
      }
  
      void changeMessage(int progre) {
              //Log.v(TAG, strCharacters);
  //            dialog.setMessage(getString(R.string.uploading_file)+" "+progre+"%");
      }
  
      private void showFileChooser() {
          Intent intent = new Intent();
          //sets the select file to all types of files
          intent.setType("*/*");
          //allows to select data and return it
          intent.setAction(Intent.ACTION_GET_CONTENT);
          //starts new activity to select file and return data
          startActivityForResult(Intent.createChooser(intent, getString(R.string.choose_file_to_upload)), PICK_FILE_REQUEST);
      }
  
      public void changeBackgroundColor(final View view, int from, int to) {
          int colorFrom = ContextCompat.getColor(this, from);
          int colorTo = ContextCompat.getColor(this, to);
          ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
          colorAnimation.setDuration(250); // milliseconds
          colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  
              @Override
              public void onAnimationUpdate(ValueAnimator animator) {
                  view.setBackgroundColor((int) animator.getAnimatedValue());
              }
  
          });
          colorAnimation.start();
      }
  
      public void changeStatusBarColor(int color) {
          int a = this.getResources().getColor(color);
          if (android.os.Build.VERSION.SDK_INT >= 21) {
              window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
              window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
              window.setStatusBarColor(a);
          }
      }
  
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          if (resultCode == Activity.RESULT_OK) {
              if (requestCode == PICK_FILE_REQUEST) {
                  if (data == null) {
                      //no data present
                      return;
                  }
                  Uri selectedFileUri = data.getData();
                  selectedFilePath = FilePath.getPath(this, selectedFileUri);
                  Log.i(TAG, "Selected File Path:" + selectedFilePath);
  
                  if (selectedFilePath != null && !selectedFilePath.equals("")) {
  //                    tvfileName.setText(selectedFilePath);
                      fileNamePopup.setText(selectedFilePath);
                      termOfService.setVisibility(View.GONE);
                      changeBackgroundColor(uploadToServer, R.color.backgroundColor, R.color.steadyColor);
                      changeStatusBarColor(R.color.steadyColor);
                      ViewAnimator
                              .animate(uploadPopup)
                              .onStart(new AnimationListener.Start() {
                                  @Override
                                  public void onStart() {
                                      uploadPopup.setVisibility(View.VISIBLE);
                                  }
                              })
                              .translationY(1000, 0)
                              .alpha(0, 1)
                              .accelerate()
                              .duration(700)
                              .start();
                  } else {
                      Toast.makeText(this, R.string.cannot_upload_to_server, Toast.LENGTH_SHORT).show();
                  }
              }
          }
      }
  
      //android upload file to server
      public int uploadFile(final String selectedFilePath) {
  
          int serverResponseCode = 0;
  
          HttpURLConnection connection;
          DataOutputStream dataOutputStream;
          String lineEnd = "\r\n";
          String twoHyphens = "--";
          String boundary = "*****";
  
  
          int bytesRead, bytesAvailable, bufferSize;
          byte[] buffer;
          int maxBufferSize = 1 * 1024 * 1024;
          final File selectedFile = new File(selectedFilePath);
          final StringBuilder result = new StringBuilder();
  
          String[] parts = selectedFilePath.split("/");
          final String fileName = parts[parts.length - 1];
  
          if (!selectedFile.isFile()) {
              dialog.dismiss();
  
              runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
  //                    tvfileName.setText("Source File Doesn't Exist: " + selectedFilePath);
                  }
              });
              return 0;
          } else {
              try {
                  FileInputStream fileInputStream = new FileInputStream(selectedFile);
                  URL url = new URL(SERVER_URL);
                  connection = (HttpURLConnection) url.openConnection();
                  connection.setDoInput(true);//Allow Inputs
                  connection.setDoOutput(true);//Allow Outputs
                  connection.setUseCaches(false);//Don't use a cached Copy
                  connection.setRequestMethod("POST");
                  connection.setRequestProperty("Connection", "Keep-Alive");
                  connection.setRequestProperty("ENCTYPE", "multipart/form-data");
                  connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                  connection.setRequestProperty("file", selectedFilePath);
  
                  //creating new dataoutputstream
                  dataOutputStream = new DataOutputStream(connection.getOutputStream());
  
                  //writing bytes to data outputstream
                  dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
  //                dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""
  //                        + selectedFilePath + "\"" + lineEnd);
  
                  dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\""
                          + selectedFilePath + "\"" + lineEnd);
  
                  dataOutputStream.writeBytes(lineEnd);
  
                  //returns no. of bytes present in fileInputStream
                  bytesAvailable = fileInputStream.available();
                  //selecting the buffer size as minimum of available bytes or 1 MB
                  bufferSize = Math.min(bytesAvailable, maxBufferSize);
                  //setting the buffer as byte array of size of bufferSize
                  buffer = new byte[bufferSize];
                  //reads bytes from FileInputStream(from 0th index of buffer to buffersize)
                  bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                  //loop repeats till bytesRead = -1, i.e., no bytes are left to read
  
                  int progress=0;
  
                  while (bytesRead > 0) {
                      //write the bytes read from inputstream
                      progress+=bytesRead;
                      dataOutputStream.write(buffer, 0, bufferSize);
                      bytesAvailable = fileInputStream.available();
  //                    changeMessage((int)((progress*100)/(selectedFile.length())));
                      final int finalProgress = progress;
                      mainHandler.post(new Runnable() {
                          @Override
                          public void run() {
                              dialog.setMessage(getString(R.string.uploading_file)+" "+((int)((finalProgress *100)/(selectedFile.length()))) +"%");
                          }
                      });
                      Log.e(TAG, "uploadFile: "+(int)((finalProgress *100)/(selectedFile.length())) );
  //                    dialog.setMessage(getString(R.string.uploading_file)+" "+((int)((progress*100)/(selectedFile.length()))) +"%");
                      bufferSize = Math.min(bytesAvailable, maxBufferSize);
                      bytesRead = fileInputStream.read(buffer, 0, bufferSize);
                  }
  
                  dataOutputStream.writeBytes(lineEnd);
                  dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
  
                  serverResponseCode = connection.getResponseCode();
                  final String serverResponseMessage = connection.getResponseMessage();
  
                  InputStream in = new BufferedInputStream(connection.getInputStream());
  
                  BufferedReader reader = new BufferedReader(new InputStreamReader(in));
  
                  String line;
                  while ((line = reader.readLine()) != null) {
                      result.append(line);
                  }
  
                  Log.i(TAG, "Server Response is: " + serverResponseMessage + ": " + serverResponseCode + ": " + result);
  
                  //response code of 200 indicates the server status OK
                  if (serverResponseCode == 200) {
                      runOnUiThread(new Runnable() {
                          @Override
                          public void run() {
  //                            tvfileName.setText("File Upload completed.\n\n You can see the uploaded file here: \n\n" + serverResponseMessage);
                              try {
                                  JSONObject jsonObject = new JSONObject(result.toString());
                                  if (jsonObject.getBoolean("success")) {
                                      ViewAnimator
                                              .animate(successWindow)
                                              .onStart(new AnimationListener.Start() {
                                                  @Override
                                                  public void onStart() {
                                                      successWindow.setVisibility(View.VISIBLE);
                                                      uploadToServer.setVisibility(View.GONE);
                                                  }
                                              })
                                              .translationY(1000, 0)
                                              .alpha(0, 1)
                                              .accelerate()
                                              .duration(500)
                                              .start()
                                              .onStop(new AnimationListener.Stop() {
                                                  @Override
                                                  public void onStop() {
                                                      changeStatusBarColor(R.color.successColor);
                                                  }
                                              });
                                      link.setText(jsonObject.getString("link"));
                                      textSuccess.setText(String.format(textSuccess.getText().toString(), jsonObject.getString("expiry")));
                                  }
                              } catch (JSONException e) {
                                  e.printStackTrace();
                              }
                          }
                      });
                  }
  
                  //closing the input and output streams
                  fileInputStream.close();
                  dataOutputStream.flush();
                  dataOutputStream.close();
  
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
                  runOnUiThread(new Runnable() {
                      @Override
                      public void run() {
                          Toast.makeText(MainActivity.this, R.string.cannot_reach_to_file, Toast.LENGTH_SHORT).show();
                      }
                  });
              } catch (MalformedURLException e) {
                  e.printStackTrace();
                  Toast.makeText(MainActivity.this, R.string.url_error, Toast.LENGTH_SHORT).show();
  
              } catch (IOException e) {
                  e.printStackTrace();
                  Toast.makeText(MainActivity.this, R.string.cannot_read_write, Toast.LENGTH_SHORT).show();
              }
              dialog.dismiss();
              return serverResponseCode;
          }
  
      }
  }