package com.qiyou.mb.android.beans;

import java.util.ArrayList;
import java.util.HashMap;

import com.qiyou.mb.android.beans.basic.BStatistics;
import com.qiyou.mb.android.beans.basic.CItem;
import com.qiyou.mb.android.beans.basic.StatTrack;
import com.qiyou.mb.android.beans.basic.Statics_bean;
import com.qiyou.mb.android.beans.basic.Track_bean;
import com.qiyou.mb.android.beans.basic.TypeStatistics;
import com.qiyou.mb.android.utils.enums.TrackAvStatus;
import com.qiyou.mb.android.utils.enums.TrackType;
import com.qiyou.mb.android.utils.log.QLog;

public class Statistics extends BStatistics  {
	public static String TAG ="com.qiyou.beans.Statistics";
    public static String dTAG ="com.qiyou";
	  

	 
	
	public void mergeTrack(Track track){
		if(track.getTrackBean().getAvStatus()==TrackAvStatus.ACTIVE){
			trackPlus( track);
			return;
		}
		
		//trackMinus(track);  //when delete/inactive track,to reload the stats from db
		
	}
	
	
	private void minusType(Integer typeToRemove,int trackId){
		if(typeToRemove>-1 &&statisticsTracks.get(typeToRemove)!=null){ //to remove from the old type list
    		statisticsTracks.get(typeToRemove).getSbs().remove(Integer.valueOf(trackId));
    		cnt--; 
//    		 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack:  statisticsTracks.get(location).getSbs().size()==0?:" +(statisticsTracks.get(typeToRemove).getSbs().size()==0));
    		
    		 Integer position =positionInTypeUsedLst(typeToRemove);
    		 
    		if(statisticsTracks.get(typeToRemove).getSbs().size()==0){
    			
//    			 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: before del  getTypeUsedLst().size() ?:" +   getTypeUsedLst().size());
//	    		 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: before del  gStatisticsTracks.size() ?:" +   statisticsTracks.size());
//	    		 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: type to delete,position to delete?:" + typeToRemove +","+positionInTypeUsedLst(typeToRemove));

//    			 getTypeUsedLst().remove( new CItem(String.valueOf(typeToRemove),TrackType.valueOf(typeToRemove).toCHString()));
    			 getTypeUsedLst().remove(getTypeUsedLst().get(position));
//    			 statisticsTracks.get(location).setStatTrack(new StatTrack());
    			  statisticsTracks.remove(typeToRemove);
    			  
//    			  QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: after del  getTypeUsedLst().size() ?:" +   getTypeUsedLst().size());  
//    			  QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: after del  gStatisticsTracks.size() ?:" +   statisticsTracks.size());
    			  
    		}else if(position > 0 && getTypeUsedLst().get(position).getCnt()>1) { //sbs not blank
    			
    			getTypeUsedLst().get(position).setCnt(getTypeUsedLst().get(position).getCnt()-1);
    		}
    	}
	}
	
	public void trackMinus(Track track){
		
		Integer typeToRemove =track.getTrackBean().getType().toInt();
		int trackId=track.getTrackBean().getTrackId() ;		
		if(trackId<=0){
			return;
		}
		TypeStatistics stat =getStatisticsTracks().get(Integer.valueOf(typeToRemove));
		if(stat==null)return;
		
		minusType(typeToRemove,trackId);
		

	     //set last id
	     if(stat.getTrackIds().size()>0 && stat.getTrackIds().contains(Integer.valueOf(trackId)) && stat.getTrackIds().get(Integer.valueOf(trackId))!=null){ 
	    	 
	    	 int miner =stat.getTrackIds().get(Integer.valueOf(trackId));
	    	 int bigger =0;
	    	 for(int i:stat.getTrackIds().keySet()){
	    		 if(i>trackId && trackId==stat.getTrackIds().get(Integer.valueOf(i))){ 
	    			 bigger=i;	
	    			 stat.getTrackIds().put(bigger, miner);
	    			 if(track.getTrackBean().getEndTime() ==lastTime) 
	    				 lastTime=stat.getSbs().get(Integer.valueOf(bigger)).getEndTime();
	    			 
	    			 break;
	    		 } 
	    	 } 
	    	 
	    
	     }
	     
	     
			if(track.getTrackBean().getType()!=TrackType.GPX)
				mergeTrackValues(stat ,track); 

			stat.getSbs().remove(Integer.valueOf(trackId));
 
			
		
	}
 
	public void trackPlus(Track track){
		if(track ==null || track.getTrackBean().getTrackId()==0)return;
		int trackId=track.getTrackBean().getTrackId() ;
		int type =track.getTrackBean().getType().toInt();
		
		TypeStatistics stat =getStatisticsTracks().get(Integer.valueOf(type));
		QLog.getLogger().dLog(dTAG,  TAG+" mergeTrack type " + track.getTrackBean().getType().toCHString()); 
		QLog.getLogger().dLog(dTAG,  TAG+" mergeTrack Dist:trackId " + trackId); 
 		 QLog.getLogger().dLog(dTAG,  TAG+" mergeTrack Dist: stat==null " + (stat==null)); 
		if(stat==null){			
			 stat = new TypeStatistics(100,track.getTrackBean().getStartTime(),type);
			  
		} 
		
		 boolean isExist =stat.getSbs().get(Integer.valueOf(trackId))!=null;
		 
//		 QLog.getLogger().d(dTAG,  TAG+"  mergeTrack: isExist?" +isExist );
		 
		    if(!isExist){
		    	
		    	cnt++;
		    	
		    	Integer typeToRemove =-1;
		    	for(Integer i:statisticsTracks.keySet()){   
//		    		 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: type:" +TrackType.valueOf(i).toCHString() );
//		    		 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: track exist in type list?:" +statisticsTracks.get(i).getSbs().keySet().contains(Integer.valueOf(trackId)) );
		    		if(statisticsTracks.get(i).getSbs().keySet().contains(Integer.valueOf(trackId))){
		    			
		    			stat.getSbs().put(trackId, statisticsTracks.get(i).getSbs().get(Integer.valueOf(trackId)));
		    			
		    			typeToRemove =Integer.valueOf(i);
		    			break;
		    			
		    		}
		    		
		    	}
//		    	 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack:  statisticsTracks.get(location)!=null?,location is" +typeToRemove+","+ (statisticsTracks.get(typeToRemove)!=null ));
				   
		       //in case track type changed from one type to another.
		    	if(typeToRemove>-1 &&statisticsTracks.get(typeToRemove)!=null){ //to remove from the old type list
		    		/*statisticsTracks.get(typeToRemove).getSbs().remove(Integer.valueOf(trackId));
		    		cnt--; 
		    		 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack:  statisticsTracks.get(location).getSbs().size()==0?:" +(statisticsTracks.get(typeToRemove).getSbs().size()==0));
		    		
		    		 Integer position =positionInTypeUsedLst(typeToRemove);
		    		 
		    		if(statisticsTracks.get(typeToRemove).getSbs().size()==0){
		    			
		    			 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: before del  getTypeUsedLst().size() ?:" +   getTypeUsedLst().size());
			    		 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: before del  gStatisticsTracks.size() ?:" +   statisticsTracks.size());

			    		 QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: type to delete,position to delete?:" + typeToRemove +","+positionInTypeUsedLst(typeToRemove));
 
//		    			 getTypeUsedLst().remove( new CItem(String.valueOf(typeToRemove),TrackType.valueOf(typeToRemove).toCHString()));
		    			 getTypeUsedLst().remove(getTypeUsedLst().get(position));
//		    			 statisticsTracks.get(location).setStatTrack(new StatTrack());
		    			  statisticsTracks.remove(typeToRemove);
		    			  
		    			  QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: after del  getTypeUsedLst().size() ?:" +   getTypeUsedLst().size());  
		    			  QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: after del  gStatisticsTracks.size() ?:" +   statisticsTracks.size());
		    			  
		    		}else if(getTypeUsedLst().get(position).getCnt()>1) { //sbs not blank
		    			
		    			getTypeUsedLst().get(position).setCnt(getTypeUsedLst().get(position).getCnt()-1);
		    		}*/
		    		minusType(typeToRemove,trackId);
		    	}else{  //just a new one.
		    		
		    		
		    	}
		    	
		     if(type!=TrackType.GPX.toInt()) {
	    		  
				     if(!typeExitsInTypeUsedLst(type)){ 
						CItem c =new CItem(String.valueOf(track.getTrackBean().getType().toInt()),track.getTrackBean().getType().toCHString());
						c.setCnt(1);
			//			if(typeUsedLst==null || !typeExitsInTypeUsedLst(track.getTrackBean().getType().toInt())){
					    getTypeUsedLst().add(c);
			//			}
						
						if(firstTime==0 ||firstTime>0 && firstTime<track.getTrackBean().getStartTime())
							firstTime=track.getTrackBean().getStartTime();
						 QLog.getLogger().dLog(dTAG,  TAG+"   MergeTrack:  after add,getTypeUsedLst().size() ?:" +   getTypeUsedLst().size());  
					 }else{  //tracks cnt++ for the type.
						 
						 Integer position =positionInTypeUsedLst(type);
						 QLog.getLogger().dLog(dTAG,  TAG+"   before MergeTrack type cnt:" +   getTypeUsedLst().get(position).getCnt());  
		
						 getTypeUsedLst().get(position).setCnt(getTypeUsedLst().get(position).getCnt()+1);
						 QLog.getLogger().dLog(dTAG,  TAG+"   after MergeTrack type cnt:" +   getTypeUsedLst().get(position).getCnt());  
					 } 
		     }
		     //set last id
		     
		     if(stat.getTrackIds().size()>0 && !stat.getTrackIds().contains(Integer.valueOf(trackId))){ 
		    	 
		    	 int max=0;
		    	 for(int i:stat.getTrackIds().keySet()){
		    		 max=max<i?i:max;
		    	 } 
		    	 max=max< getLastTrackId()? getLastTrackId():max;
	    		 QLog.getLogger().dLog(dTAG,  TAG+" 1 current track id:" + trackId);	 
	    		 QLog.getLogger().dLog(dTAG,  TAG+" 1 last track id:" + max);
		    	 if(trackId>max){
		    		 stat.getTrackIds().put(trackId, max);
		    		 QLog.getLogger().dLog(dTAG,  TAG+" 1 set last id:   trackId>max:" +   (trackId>max));	 
		    	 }
		    	 
		    	   
		     }
		    	
		 }
		    
//	    if(stat.getSbs().get(Integer.valueOf(trackId))==null){

	    
	    
//		stat.getStatTrack().mergeTrack(track);
		if(track.getTrackBean().getType()!=TrackType.GPX)
			mergeTrackValues(stat ,track);
		
		if(!stat.getTrackIds().containsKey(Integer.valueOf(trackId))){
			 QLog.getLogger().dLog(dTAG,  TAG+"2 current track id:" + trackId);	 
    		 QLog.getLogger().dLog(dTAG,  TAG+"2 last track id:" + getLastTrackId());
			stat.getTrackIds().put(trackId, getLastTrackId());
			
		}
		
		this.setLastTrackId(trackId);
		
		stat.getSbs().put(trackId, new Statics_bean(track.getTrackBean()));
//		setMaxAvStat(stat.getStatTrack());		
		if(lastTime==0 ||lastTime>0 && lastTime<track.getTrackBean().getEndTime())
				lastTime=track.getTrackBean().getEndTime();
		
		stat.setEnd(lastTime);
		getStatisticsTracks().put(type, stat);
		
	}
	
	
	public boolean typeExitsInTypeUsedLst(int type){
		if(typeUsedLst!=null)		
		for(CItem c:typeUsedLst){
			if(c==null)continue;
			if(Integer.valueOf(c.getId())==type)return true;
		}
		return false;
		
		
	}
	
	public Integer positionInTypeUsedLst(int type){
		if(typeUsedLst!=null)		
		for(int i=0;i<typeUsedLst.size();i++ ){
			CItem c=typeUsedLst.get(Integer.valueOf(i));
			if(c==null)continue;
			if(Integer.valueOf(c.getId())==type) return Integer.valueOf(i);
		}
		 return Integer.valueOf(-1); 
		
	}
	
	
  void mergeTrackValues(TypeStatistics stt ,Track tr){	
		
	  StatTrack stat =stt.getStatTrack();
		QLog.getLogger().dLog(dTAG, TAG+"   MergeTrack: begin to merge track values........，track id is " +tr.getTrackBean().getTrackId());
		
		if(tr==null || tr.getTrackBean()==null) return;		
		
		stat.setIsAVcnt(false);
		Track_bean tb =tr.getTrackBean();
//		isAVcnt = !mergedTracks.contains(tb.getTrackId());
//		Track_bean tb0 =  mergedTracks.get(Integer.valueOf(tb.getTrackId()));
	    Statics_bean tb0 = stt.getSbs().get(Integer.valueOf(tb.getTrackId()));
	    
	
			 
		
		
		stat.setIsAVcnt( tb0==null);	
		
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack:    last track end time:" +  (tb0==null?null:tb0.getOLastdbTime()));
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: current track end time:" +  tb.getLastdbTime());
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: time since last db update:" + Utils.getTimeCnt(System.currentTimeMillis()- tb.getLastdbTime(),true));
		
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: track alread exist?" +!stat.isAVcnt() );
		
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack:    Last merge distance:?" + (tb0==null?null:tb0.getODistance()));
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: Current merge distance:?" + tb.getDistance());
//		
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack:    Last merge  offtime:?" + (tb0==null?null:tb0.getOOffTime()));
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: Current merge  offtime:?" + tb.getOffTime());
//		
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: Last   merge  totalTime:?" +  Utils.getTimeCnt(  tb0==null?0:(tb0.getOtotalTime() ) ));
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: Current merge totalTime:?" + Utils.getTimeCnt(tb.getTotalTime() ));
		
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: Current       sportTime:?" +  Utils.getTimeCnt((tb.getSportTime() )));
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: Current       pauseTime:?" +  Utils.getTimeCnt((tb.getPauseTime() )));
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: Current         offTime:?" +  Utils.getTimeCnt((tb.getOffTime() )));
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: last   merge    offTime:?" + ( tb0==null?0:Utils.getTimeCnt((tb0.getOOffTime() ))));
//		
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: Current         tb.getLastdbTime():" +  Utils.getFormatedTime( tb.getLastdbTime()  ));
//
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack: last   merge    tb.getLastdbTime():" + ( tb0==null?0:Utils.getFormatedTime(tb0.getOlastdbTime() )));

		
		long ttime= tb.getTotalTime()  - (tb0==null?0:(tb0.getTotalTime())) ;
		QLog.getLogger().dLog(dTAG, TAG+" mergeTrack total time:" +ttime);
//		if(tb.getDistance() -tb0.getODistance()<=0)return;
		
//		if(  tb.getLastdbTime()  - (tb0==null?0:(tb0.getOlastdbTime())) <=0)return;
		float dist=tb.getDistance()-(tb0==null?0:tb0.getDist());
		
		QLog.getLogger().dLog(dTAG,  TAG+" mergeTrack Dist: tb.getDistance(): " +tb.getDistance()+"--------------------------------------");
//		
//	    QLog.getLogger().d(dTAG,  TAG+" mergeTrack Dist:, tb0==null: " + (tb0==null));
//		QLog.getLogger().d(dTAG,  TAG+" mergeTrack Dist:, tb0==null?0:tb0.getOdist(): " + (tb0==null?0:tb0.getOdist()));
		QLog.getLogger().dLog(dTAG,  TAG+" mergeTrack Dist: delta dist=? " + dist);
		
		if(  ttime<=0 && dist<=0)return;
		
		float spd =tb.getAvs() - (tb0==null?0:tb0.getAvs());
		float tspd =tb.getTavs() - (tb0==null?0:tb0.getTavs());
		float edownDist=tb.geteDownDist()-(tb0==null?0:tb0.geteDownDist()); 
		float eupDist =tb.geteUpDist()-(tb0==null?0:tb0.geteUpDist());
		float maxr=tb.getMaxR() -(tb0==null?0:tb0.getMaxR()); 
		long off=tb.getOffTime() -(tb0==null?0:tb0.getOffTime());
		long pause=tb.getPauseTime() -(tb0==null?0:tb0.getPause()); 
		long sport=tb.getSportTime()-(tb0==null?0:tb0.getSportTime()); 
		float topspd=tb.getTopSpeed();// -(tb0==null?0:tb0.getOTopSpeed());  
//		long ttime=(tb.getSportTime()+tb.getPauseTime()) -(tb0==null?0: (tb0.getOsportTime()+tb0.getOpause()));  
		float burn=tr.getCalBurn()-(tb0==null?0:tb0.getBurn()); 
		float upDist=tb.getUpDist()-(tb0==null?0:tb0.getUpDist());
 		float downDist=tb.getDownDist()-(tb0==null?0:tb0.getDownDist());
 		float maxEle= tb.getMaxEle() ;
 		float minExe= tb.getMinEle();
		stat.setAvSpeed(spd);
		stat.setAvSpeed(tspd);
		
//		QLog.getLogger().d(dTAG,  TAG+" mergeTrack Dist:, stat.getSumDist() before merge:  " + stat.getSumDist());
		
		stat.setDist(dist);
//		QLog.getLogger().d(dTAG,  TAG+" mergeTrack Dist:, stat.getSumDist() after merge:  " + stat.getSumDist());
	 	
//		stat.seteDownDist(downDist);
//		stat.seteUpDist(upDist+downDist); 
		stat.setUpDistE(eupDist); 
		stat.setMaxR(maxr);
		stat.setOffTime(off);
		stat.setPause(pause);
		stat.setSportTime(sport);
		stat.setTopSpeed(topspd);
		stat.setTotalTime(ttime);
		stat.setBurn(burn);
		stat.setDownDist(downDist);
		stat.setUpDist(upDist);
		stat.setMaxEle(maxEle);
		stat.setMinEle(minExe);
//		mergedTracks.put(tb.getTrackId(),tb);
		stat.setIsAVcnt(true); 
		
//		QLog.getLogger().d(dTAG,  TAG+" MergeTrack  begin merage statisticType sum data.");
		
		  sumBurn +=burn;   //累积消耗卡路里
		  sumeUpDist +=eupDist;   //累积上升
		  sumeDownDist +=edownDist; //累积下降 
		  sumPause += pause;	 
		  sumSportTime +=sport;
		  sumOffTime +=off; //no gps time 
		  sumTotalTime +=ttime;
		  sumUpDist+=upDist;
		  sumDownDist+=downDist;
//		  QLog.getLogger().d(dTAG,  TAG+" MergeTrack to merge ttime: "+ttime);
//		  QLog.getLogger().d(dTAG,  TAG+" MergeTrack  statisticType sum ttime: "+sumTotalTime);
//		  QLog.getLogger().d(dTAG,  TAG+" MergeTrack  statisticType sum ttime: "+Utils.getTimeCnt( getSumTotalTime(),false));
		  
//			QLog.getLogger().d(dTAG,  TAG+" mergeTrack Dist:, sumDist before merge:  " + sumDist);
			
		  sumDist +=dist ; 
		
 			QLog.getLogger().dLog(dTAG,  TAG+" mergeTrack Dist: sumDist after merge:  " + sumDist);
 			QLog.getLogger().dLog(dTAG,  TAG+" recording track dist:" + tr.getTrackBean().getDistance());
		  
		  
//		QLog.getLogger().d(dTAG,  TAG+"   MergeTrack values: DONE............");
		lastStrack.getSbs().put(tb.getTrackId(), new Statics_bean(tb));
	}

 
public boolean mergeCates(HashMap<Integer,ArrayList<String>>changedCates,Boolean isNew){
	categoryList= getCategoryList();
	ArrayList<String> cates;
	boolean hasChg = false;
	for(Integer trackId: changedCates.keySet()){
		cates =changedCates.get(trackId);  
		if(cates==null)continue;
		if(trackId==0 && isNew){
			
		}
		
		
		for(String cate:categoryList.keySet()){
			if(!isNew &&cates.contains(cate)){ //del
//				 QLog.getLogger().d(dTAG, " .................removing cates trackId ?"+trackId);
				categoryList.get(cate).remove(Integer.valueOf(trackId));
				hasChg=true;
				continue;
			}
			if(isNew&&cates.contains(cate)){
				if(!categoryList.get(cate).contains(Integer.valueOf(trackId)) ||trackId==0){
					if(!categoryList.get(cate).contains(Integer.valueOf(trackId)))
						categoryList.get(cate).add(Integer.valueOf(trackId));
					hasChg=true;
//					 QLog.getLogger().d(dTAG, " .................adding cates trackId ?"+trackId);
				}
			}
			
		}
	}
	return hasChg;
}

 
 
}
