<|start_filename|>helpstack/src/com/tenmiles/helpstack/logic/HSUtils.java<|end_filename|>
//  HSUtils
//
//Copyright (c) 2014 HelpStack (http://helpstack.io)
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

package com.tenmiles.helpstack.logic;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;

import com.google.gson.Gson;

import java.lang.reflect.Type;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class HSUtils {
	
	private static final long TIME_MILLIS = 1000;
	private static final long TIME_MINUTE = 60 * TIME_MILLIS;
	private static final long TIME_HOUR = 60 * TIME_MINUTE;
	private static final long TIME_DAY = 24 * TIME_HOUR;
	
	public static final String DATE_PATTERN_SHORT = "yyyy-MM-dd";
	public static final String DATE_PATTERN_MEDIUM = "yyyy-MM-dd HH:mm:ss";
	public static final String DATE_PATTERN_USER_DISPLAY_SHORT = "dd-MMM, yyyy";
	
	public HSUtils() {
	}

	//TODO: optimize this function
	public static String convertToHumanReadableTime(Date givenDate, long currentTimeLong) {

		Calendar currentTime = Calendar.getInstance();
		currentTime.setTimeZone(TimeZone.getTimeZone("UTC"));
		currentTime.setTimeInMillis(currentTimeLong);

		Calendar givenTime = Calendar.getInstance();
		givenTime.setTimeZone(TimeZone.getTimeZone("UTC"));
		givenTime.setTime(givenDate);

		// Step 1: To see if time difference is less than 24 hours of not
		long timeDiff = currentTime.getTimeInMillis() - givenTime.getTimeInMillis();
		if(timeDiff<=0) {
			return "Now";
		}
		
		String humanString = null;
		// Checking if timeDiff is less than 24 or not
		if((timeDiff/TIME_DAY)>=1) {
			// days
			int days = (int) (timeDiff/TIME_DAY);
			humanString = String.format(Locale.getDefault(), "%dd", days);
		}
		else {
			// checking if greater than hour
			if((timeDiff/TIME_HOUR)>=1) {
				humanString = String.format(Locale.getDefault(),"%dh", (timeDiff/TIME_HOUR));
			}
			else if((timeDiff/TIME_MINUTE)>=1){
				humanString = String.format(Locale.getDefault(),"%dm", (timeDiff/TIME_MINUTE));
			}
			else {
				humanString = String.format(Locale.getDefault(),"%ds", (timeDiff/TIME_MILLIS));
			}
		}

		return humanString;
	}
	
	public static void showAlertDialog (Context context, String title, String message) {
		AlertDialog dialog = new AlertDialog.Builder(context).create();  
		dialog.setCancelable(true); 
		dialog.setMessage(message);
		dialog.setTitle(title);
		dialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.cancel();
			}
		});
		dialog.show();  
	}

	public static <T> T getObjectFromJson(String json, Type type) {
		Gson gson = new Gson();
		if ((json != null) && (json.isEmpty())) {
				return null;
		}
		return gson.fromJson(json, type);
	}

	public static <T> String convertObjectToStringJson(T object, Type type) {
		Gson gson = new Gson();
		return gson.toJson(object, type);
	}
}


<|start_filename|>helpstack/src/com/tenmiles/helpstack/widget/DrawingView.java<|end_filename|>
package com.tenmiles.helpstack.theme.widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import static java.lang.StrictMath.min;

public class DrawingView extends View {

    private Path mPath;
    private Paint mPaint;
    private Canvas mCanvas;

    private Paint canvasPaint;
    private Bitmap canvasBitmap;

    private Bitmap cachedBitmap;

    private int paintColor = 0xFFF44336;
    private int brushSize = 20;
    private int resizedWidth;
    private int resizedHeight;
    private boolean isEdited;

    private ObserverInterface mObserver;

    public DrawingView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mPath = new Path();
        mPaint = new Paint();

        mPaint.setColor(paintColor);

        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(brushSize);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);

        canvasPaint = new Paint(Paint.DITHER_FLAG);
    }

    public void setCanvasBitmap(Bitmap bitmap) {
        cachedBitmap = bitmap;
        mCanvas.drawColor(Color.BLACK);
        Bitmap mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);

        calculateResizeRatio(bitmap, mCanvas);
        Bitmap resizedBitmap = Bitmap.createScaledBitmap(mutableBitmap, resizedWidth, resizedHeight, false);

        int leftStart = getLeftStart(resizedWidth);
        int topStart = getTopStart(resizedHeight);

        mCanvas.drawBitmap(resizedBitmap, leftStart, topStart, mPaint);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(canvasBitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
        canvas.drawPath(mPath, mPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float touchX = event.getX();
        float touchY = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mPath.moveTo(touchX, touchY);
                break;
            case MotionEvent.ACTION_MOVE:
                mPath.lineTo(touchX, touchY);
                break;
            case MotionEvent.ACTION_UP:
                mCanvas.drawPath(mPath, mPaint);
                setIsEdited(true);
                mPath.reset();
                activateClearOptionInActivity(true);
                break;
            default:
                return false;
        }

        invalidate();
        return true;
    }

    public void setColor(String newColor) {
        invalidate();

        paintColor = Color.parseColor(newColor);
        mPaint.setColor(paintColor);
    }

    public void clearChanges() {
        mPath.reset();
        setCanvasBitmap(cachedBitmap);
        setIsEdited(false);
        activateClearOptionInActivity(false);
        invalidate();
    }

    private void setIsEdited(boolean value) {
        isEdited = value;
    }

    public boolean hasBeenEdited() {
        return isEdited;
    }

    private void calculateResizeRatio(Bitmap bitmap, Canvas drawCanvas) {
        double resizeRatio = min((double)drawCanvas.getWidth()/bitmap.getWidth(), (double)drawCanvas.getHeight()/bitmap.getHeight());
        resizedWidth = (int) (resizeRatio * bitmap.getWidth());
        resizedHeight = (int) (resizeRatio * bitmap.getHeight());
    }

    private int getTopStart(int resizedHeight) {
        int topStart = (this.getTop() + this.getBottom() - resizedHeight) >> 1;
        return topStart;
    }

    private int getLeftStart(int resizedWidth) {
        int leftStart = (this.getLeft() + this.getRight() - resizedWidth) >> 1;
        return leftStart;
    }

    public void setObserver(ObserverInterface observer){
        mObserver = observer;
    }

    private void activateClearOptionInActivity(boolean isEdited){
        if( mObserver != null ){
            mObserver.activateClearOption(isEdited);
        }
    }

    public interface ObserverInterface {
        void activateClearOption(boolean isEdited);
    }
}


<|start_filename|>helpstack/src/com/tenmiles/helpstack/activities/HomeActivity.java<|end_filename|>
package com.tenmiles.helpstack.activities;

import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;

import com.tenmiles.helpstack.R;
import com.tenmiles.helpstack.fragments.HSFragmentManager;
import com.tenmiles.helpstack.fragments.HomeFragment;

public class HomeActivity extends HSActivityParent {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.hs_activity_home, savedInstanceState, R.string.hs_help_title);

        if (savedInstanceState == null) { // Activity started first time
            HomeFragment homeFragment = HSFragmentManager.getHomeFragment();
            HSFragmentManager.putFragmentInActivity(this, R.id.container, homeFragment, "Home");
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.search) {
            return true;
        } else if (id == android.R.id.home) {
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onActivityResult(int arg0, int arg1, Intent arg2) {
        super.onActivityResult(arg0, arg1, arg2);
    }
}


<|start_filename|>helpstack/src/com/tenmiles/helpstack/model/HSKBItem.java<|end_filename|>
//  HSKBItem
//
//Copyright (c) 2014 HelpStack (http://helpstack.io)
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

package com.tenmiles.helpstack.model;

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

public class HSKBItem implements Serializable{
	
	transient public static final int TYPE_ARTICLE = 0;
	transient public static final int TYPE_SECTION = 1;

	@SerializedName("subject")
	private String subject;
	
	@SerializedName("text")
	private String body;
	
	@SerializedName("id")
	private String id;
	
	@SerializedName("article_type")
	private int articleType; // 0 - article, 1 - section
	
	public HSKBItem() {
	}
	
	public HSKBItem(String id, String subject, String body) {
		this.id = id;
		this.subject = subject;
		this.body = body;
	}
	
	public static HSKBItem createForSection(String id, String subject) {
		HSKBItem item = new HSKBItem();
		item.id = id;
		item.subject = subject;
		item.articleType = TYPE_SECTION;
		
		return item;
	}
	
	public static HSKBItem createForArticle(String id, String subject, String text) {
		HSKBItem item = new HSKBItem();
		item.id = id;
		item.subject = subject;
		item.body = text;
		item.articleType = TYPE_ARTICLE;
		return item;
	}

	public String getSubject() {
		return subject;
	}
	
	public String getId() {
		return id;
	}
	
	public void setBody(String body) {
		this.body = body;
	}
	
	public String getBody() {
		return this.body;
	}
	
	public int getArticleType() {
		return articleType;
	}
	
	public void setArticleType(int type) {
		articleType = type;
	}
}


<|start_filename|>helpstack/src/com/tenmiles/helpstack/model/HSUser.java<|end_filename|>
//  HSUser
//
//Copyright (c) 2014 HelpStack (http://helpstack.io)
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

package com.tenmiles.helpstack.model;

import java.io.Serializable;

import com.google.gson.annotations.SerializedName;

/**
 * 
 * @author <NAME>
 *
 */
public class HSUser implements Serializable {

	@SerializedName("first_name")
	private String firstName;
	
	@SerializedName("last_name")
	private String lastName;
	
	@SerializedName("email")
	private String emailAddress;
	
	@SerializedName("access_token")
	private String token;
	
	@SerializedName("user_id")
	private String userId;

    @SerializedName("user_api_href")
    private String userApiHref;
	
	public HSUser() {
	}
	
	public static HSUser createNewUserWithDetails(String firstName, String lastName, String email) {
		HSUser user = new HSUser();
		user.firstName = firstName;
		user.lastName = lastName;
		user.emailAddress = email;
		return user;
	}

    public static HSUser createNewUserWithDetails(String firstName, String lastName, String email, String userLink) {
        HSUser user = createNewUserWithDetails(firstName, lastName, email);
        user.userApiHref = userLink;
        return user;
    }
	
	public String getFirstName() {
		return firstName;
	}
	
	public String getLastName() {
		return lastName;
	}
	
	public String getFullName() {
		return ""+ firstName +" "+ lastName;
	}
	
	public String getEmail() {
		return emailAddress;
	}
	
	public String getUserId() {
		return userId;
	}

    public String getApiHref() {
        return userApiHref;
    }

	public static HSUser appendCredentialOnUserDetail(HSUser user, String userId, String access_token) {
		user.userId = userId;
		return user;
	}
}


<|start_filename|>helpstack/src/com/tenmiles/helpstack/model/HSDraft.java<|end_filename|>
package com.tenmiles.helpstack.model;

import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

/**
 * Created by Anirudh on 19/11/14.
 */
public class HSDraft implements Serializable {

    @SerializedName("draft_subject")
    private String draftSubject;

    @SerializedName("draft_message")
    private String draftMessage;

    @SerializedName("draft_attachments")
    private HSAttachment[] draftAttachments;

    @SerializedName("draft_user")
    private HSUser draftUser;

    @SerializedName("draft_reply_message")
    private String draftReplyMessage;

    @SerializedName("draft_reply_attachments")
    private HSAttachment[] draftReplyAttachments;

    public HSDraft() {

    }

    public String getSubject() {
        return draftSubject;
    }

    public String getMessage() {
        return draftMessage;
    }

    public HSAttachment[] getAttachments() {
        return draftAttachments;
    }

    public void setDraftSubject(String subject){
        this.draftSubject = subject;
    }

    public void setDraftMessage(String message) {
        this.draftMessage = message;
    }

    public HSUser getDraftUser() {
        return draftUser;
    }

    public String getDraftReplyMessage() {
        return draftReplyMessage;
    }

    public HSAttachment[] getDraftReplyAttachments() {
        return draftReplyAttachments;
    }

    public void setDraftAttachments(HSAttachment[] attachmentsArray) {
        this.draftAttachments = attachmentsArray;
    }

    public void setDraftUser(HSUser user) {
        this.draftUser = user;
    }

    public void setDraftReplyMessage(String message) {
        this.draftReplyMessage = message;
    }

    public void setDraftReplyAttachments(HSAttachment[] attachments) {
        this.draftReplyAttachments = attachments;
    }
}


<|start_filename|>helpstack/src/com/tenmiles/helpstack/model/HSError.java<|end_filename|>
package com.tenmiles.helpstack.model;

/**
 * Created by muthukumarkrishnan on 10/15/15.
 */
public class HSError implements Cloneable {
    private enum ErrorCode {
        AppError,
        HttpError,
        NetworkError
    }

    public String message;
    public int httpResponseCode;
    public ErrorCode errorCode;

    public void initWithAppError(String msg) {
        message = msg;
        errorCode = ErrorCode.AppError;
    }

    public void initWithHttpError(int responseCode, String msg) {
        errorCode = ErrorCode.HttpError;
        httpResponseCode = responseCode;
        message = msg;
    }

    public void initWithNetworkError(String msg) {
        errorCode = ErrorCode.NetworkError;
        message = msg;
    }

    public boolean isAppError() {
        return (errorCode == ErrorCode.AppError);
    }

    public boolean isNetworkError() {
        return (errorCode == ErrorCode.NetworkError);
    }

    public boolean isHttpError() {
        return (errorCode == ErrorCode.HttpError);
    }
}
