package schedule

import (
	"LAPP_LF_MOM_BACKEND/utils"
	"container/list"
	"time"
)

type TimeCurveSrv struct {
	StartTime     time.Time // 时间曲线的起始时间点
	EndTime       time.Time // 时间曲线的结束时间点
	EffFactor     float64   // 效率因子
	TimeLineArray []TimeLineSrv
	TimeLineList  *list.List
}

// 将时间数组转化成列表
func (tcs *TimeCurveSrv) GetLineList() {

	// 初始化
	tcs.TimeLineList = list.New()
	for _, tlsrv := range tcs.TimeLineArray {
		tcs.TimeLineList.PushBack(tlsrv)
	}
}

// 将时间列表转化成数组
func (tcs *TimeCurveSrv) GetLineArray() {
	// 初始化数组
	tcs.TimeLineArray = []TimeLineSrv{}
	for e := tcs.TimeLineList.Front(); e != nil; e = e.Next() {
		tlsrv := e.Value.(TimeLineSrv)
		tcs.TimeLineArray = append(tcs.TimeLineArray, tlsrv)
	}
}

// 获取某时间点在时间曲线上的位置（哪条时间线上）
func (tcs *TimeCurveSrv) GetTimeLine(tp time.Time) (node *list.Element, err error) {
	var (
		e          *list.Element
		tl, prevtl TimeLineSrv
	)
	/** 如果结束时间点小于计划曲线的起始时间点
	           |-------------------|
	      *
									*
	*/
	if tp.Unix() < tcs.StartTime.Unix() || tp.Unix() > tcs.EndTime.Unix() {
		node = nil
		return
	}

	for e = tcs.TimeLineList.Front(); e != nil; e = e.Next() {
		tl = e.Value.(TimeLineSrv)
		if tp.Unix() >= tl.StartTime.Unix() && tp.Unix() <= tl.EndTime.Unix() {
			node = e
			return
		}

		// 如果正好落在两段时间之内不可用时段，则返回后面时段的位置
		if e.Prev() != nil {
			prevtl = e.Prev().Value.(TimeLineSrv)
			if tp.Unix() >= prevtl.EndTime.Unix() && tp.Unix() <= tl.StartTime.Unix() {
				node = e
				return
			}
		}
	}

	node = nil
	return
}

// 删除指定时间线节点之后的所有节点
func (tcs *TimeCurveSrv) RemoveListAllAfterItem(delNode *list.Element, delItem bool) (err error) {
	var (
		e, el, next, n *list.Element
	)
	// 删除litem之后所有的节点
	for e = tcs.TimeLineList.Front(); e != nil; e = e.Next() {
		if delNode == e {
			next = e.Next()
			if delItem {
				tcs.TimeLineList.Remove(e)
			}
			for el = next; el != nil; el = n {
				n = el.Next()
				tcs.TimeLineList.Remove(el)
			}
			break
		}
	}
	return
}

// 删除指定时间线节点之前的所有节点
func (tcs *TimeCurveSrv) RemoveListAllBeforeItem(delNode *list.Element, delItem bool) (err error) {
	var (
		e, el, prev, p *list.Element
	)
	// 删除litem之前所有的节点
	for e = tcs.TimeLineList.Front(); e != nil; e = e.Next() {
		if delNode == e {
			prev = e.Prev()
			if delItem {
				tcs.TimeLineList.Remove(e)
			}
			for el = prev; el != nil; el = p {
				p = el.Prev()
				tcs.TimeLineList.Remove(el)
			}
			break
		}
	}
	return
}

// 增加工作时段
func (tcs *TimeCurveSrv) AddTimeLine(addtlsrv TimeLineSrv) (err error) {
	var (
		tlsrv                     TimeLineSrv
		tl, tlb, tle              *TimeLineSrv
		e, next, nodeBeg, nodeEnd *list.Element
	)

	if addtlsrv.EndTime.Unix() <= addtlsrv.StartTime.Unix() {
		return
	}

	/** 如果结束时间点小于计划曲线的起始时间点
	        |-------------------|
	  <---->
	*/
	if addtlsrv.EndTime.Unix() <= tcs.StartTime.Unix() {
		return
	}

	/** 如果计算起始时间点大于等于计划曲线的起始时间点
	  |--------------------|
	                        <----------->
	*/
	if addtlsrv.StartTime.Unix() >= tcs.EndTime.Unix() {
		return
	}

	/**      |-------------------|
	  <--------------------------->
	*/
	if addtlsrv.StartTime.Unix() < tcs.StartTime.Unix() && addtlsrv.EndTime.Unix() > tcs.EndTime.Unix() {
		tlsrv = TimeLineSrv{}
		tlsrv.StartTime = addtlsrv.StartTime
		tlsrv.EndTime = addtlsrv.EndTime
		tlsrv.EffFactor = addtlsrv.EffFactor
		tcs.TimeLineList.Init()
		tcs.StartTime = addtlsrv.StartTime
		tcs.EndTime = addtlsrv.EndTime
		tcs.EffFactor = addtlsrv.EffFactor
		tcs.TimeLineList.PushBack(tlsrv)
		return
	}

	/**        |-------------------|
	<------>
	*/
	if addtlsrv.StartTime.Unix() < tcs.StartTime.Unix() && addtlsrv.EndTime.Unix() > tcs.StartTime.Unix() && addtlsrv.EndTime.Unix() <= tcs.EndTime.Unix() {
		if nodeEnd, err = tcs.GetTimeLine(addtlsrv.EndTime); err != nil {
			return
		}
		if nodeEnd != nil {
			tl = nodeEnd.Value.(*TimeLineSrv)
			tl.StartTime = addtlsrv.StartTime
			tcs.RemoveListAllBeforeItem(nodeEnd, false)
			tcs.StartTime = addtlsrv.StartTime
		} else {
			// 删除时段内的节点
			for e = tcs.TimeLineList.Front(); e != nil; e = next {
				next = e.Next()
				tl = e.Value.(*TimeLineSrv)
				if tl.StartTime.Unix() > addtlsrv.StartTime.Unix() && tl.EndTime.Unix() < addtlsrv.EndTime.Unix() {
					tcs.TimeLineList.Remove(e)
				}
			}
			tlsrv = TimeLineSrv{}
			tlsrv.StartTime = addtlsrv.StartTime
			tlsrv.EndTime = addtlsrv.EndTime
			tlsrv.EffFactor = tcs.EffFactor
			tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime)
			tcs.TimeLineList.PushFront(tlsrv)
			tcs.StartTime = addtlsrv.StartTime
		}
	}

	/**        |-------------------|
	  <------>
	*/
	if addtlsrv.StartTime.Unix() >= tcs.StartTime.Unix() && addtlsrv.EndTime.Unix() <= tcs.EndTime.Unix() {
		if nodeBeg, err = tcs.GetTimeLine(addtlsrv.StartTime); err != nil {
			return
		}
		if nodeEnd, err = tcs.GetTimeLine(addtlsrv.EndTime); err != nil {
			return
		}
		/** 落在可用时段内
		情况一： |-------|
		           |****|
		**/
		if nodeBeg != nil && nodeEnd == nil {
			tlb = nodeBeg.Value.(*TimeLineSrv)
			// 删除开始节点之后到结束时间点之间的Node
			for e = nodeBeg.Next(); e != nil; e = next {
				next = e.Next()
				tl = e.Value.(*TimeLineSrv)
				if tl.EndTime.Unix() <= addtlsrv.EndTime.Unix() {
					tcs.TimeLineList.Remove(e)
				} else {
					break
				}
			}
			// 更新开始节点的结束时间
			//tlb.EndTime = addtlsrv.EndTime


			tlsrv			= TimeLineSrv{}
			tlsrv.StartTime = tlb.StartTime
			tlsrv.EndTime 	= addtlsrv.EndTime
			tlsrv.EffFactor = addtlsrv.EffFactor
			tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime)
			tcs.TimeLineList.InsertBefore(tlsrv, nodeBeg)
			// 删除当前节点
			tcs.TimeLineList.Remove(nodeBeg)
		}
		/**
		情况二： |-------|   |-------|
		               |***|
		**/
		if nodeBeg == nil && nodeEnd == nil {
			tlsrv = TimeLineSrv{}
			tlsrv.StartTime = addtlsrv.StartTime
			tlsrv.EndTime = addtlsrv.EndTime
			tlsrv.EffFactor = addtlsrv.EffFactor
			// 删除开始节点之后到结束时间点之间的Node
			for e = tcs.TimeLineList.Front(); e != nil; e = next {
				next = e.Next()
				tl = e.Value.(*TimeLineSrv)
				if tl.StartTime.Unix() > addtlsrv.StartTime.Unix() && tl.EndTime.Unix() < addtlsrv.EndTime.Unix() {
					tcs.TimeLineList.Remove(e)
				}
			}
			// 添加节点到时间曲线中
			for e = tcs.TimeLineList.Front(); e != nil; e = next {
				tl = e.Value.(*TimeLineSrv)
				if tl.EndTime.Unix() >= tlsrv.StartTime.Unix() {
					tcs.TimeLineList.InsertAfter(tlsrv, e)
					break
				}
			}
		}
		/**
		情况三： |-------|   |-------|
		                  |**|
		**/
		if nodeBeg == nil && nodeEnd != nil {
			tle = nodeEnd.Value.(*TimeLineSrv)
			// 删除开始节点到结束时间点之间的Node
			for e = tcs.TimeLineList.Front(); e != nil; e = next {
				next = e.Next()
				tl = e.Value.(*TimeLineSrv)
				if tl.StartTime.Unix() > addtlsrv.StartTime.Unix() && tl.EndTime.Unix() < addtlsrv.EndTime.Unix() {
					tcs.TimeLineList.Remove(e)
				}
			}
			// 更新结束节点的开始时间
			//tle.StartTime = addtlsrv.StartTime

			tlsrv			= TimeLineSrv{}
			tlsrv.StartTime = addtlsrv.StartTime
			tlsrv.EndTime 	= tle.EndTime
			tlsrv.EffFactor = addtlsrv.EffFactor
			tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime)
			tcs.TimeLineList.InsertBefore(tlsrv, nodeEnd)
			// 删除当前节点
			tcs.TimeLineList.Remove(nodeEnd)

		}
		/**
		情况四： |-------|   |-------|
		                   |****|
		*/
		if nodeBeg != nil && nodeEnd != nil {
			if nodeBeg != nodeEnd {
				tlb = nodeBeg.Value.(*TimeLineSrv)
				tle = nodeEnd.Value.(*TimeLineSrv)
				if tlb != tle {
					// 删除两节点之间的所有节点
					for e = nodeBeg.Next(); e != nil && e != nodeEnd; e = next {
						next = e.Next()
						tcs.TimeLineList.Remove(e)
					}
					// 更新起始时间点
					//tlb.EndTime = tle.EndTime

					tlsrv			= TimeLineSrv{}
					tlsrv.StartTime = tlb.StartTime
					tlsrv.EndTime 	= tle.EndTime
					tlsrv.EffFactor = addtlsrv.EffFactor
					tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime)
					tcs.TimeLineList.InsertBefore(tlsrv, nodeEnd)

					tcs.TimeLineList.Remove(nodeBeg)
					tcs.TimeLineList.Remove(nodeEnd)
				}
			}
		}
	}

	/**        |-------------------|
	<------>
	*/
	if addtlsrv.StartTime.Unix() >= tcs.StartTime.Unix() && addtlsrv.StartTime.Unix() < tcs.EndTime.Unix() && addtlsrv.EndTime.Unix() > tcs.EndTime.Unix() {
		if nodeBeg, err = tcs.GetTimeLine(addtlsrv.StartTime); err != nil {
			return
		}
		if nodeBeg != nil {
			tl = nodeBeg.Value.(*TimeLineSrv)
			tl.EndTime = addtlsrv.EndTime
			tcs.RemoveListAllAfterItem(nodeBeg, false)
			tcs.EndTime = addtlsrv.EndTime
		} else {
			// 删除时段内的节点
			for e = tcs.TimeLineList.Front(); e != nil; e = next {
				next = e.Next()
				tl = e.Value.(*TimeLineSrv)
				if tl.StartTime.Unix() > addtlsrv.StartTime.Unix() && tl.EndTime.Unix() < addtlsrv.EndTime.Unix() {
					tcs.TimeLineList.Remove(e)
				}
			}
			tlsrv = TimeLineSrv{}
			tlsrv.StartTime = addtlsrv.StartTime
			tlsrv.EndTime = addtlsrv.EndTime
			tlsrv.EffFactor = addtlsrv.EffFactor
			tcs.TimeLineList.PushBack(tlsrv)
			tcs.EndTime = addtlsrv.EndTime
		}
	}

	return
}

// 减少工作时段
func (tcs *TimeCurveSrv) SubTimeLine(subtlsrv TimeLineSrv) (err error) {
	var (
		tlsrv                     TimeLineSrv
		tl, tlb, tle              TimeLineSrv
		e, next, nodeBeg, nodeEnd *list.Element
	)

	if subtlsrv.EndTime.Unix() <= subtlsrv.StartTime.Unix() {
		return
	}

	/** 如果结束时间点小于计划曲线的起始时间点
	        	|-------------------|
	  <---->
	*/
	if subtlsrv.EndTime.Unix() <= tcs.StartTime.Unix() {
		return
	}

	/** 如果计算起始时间点大于等于计划曲线的起始时间点
	  |--------------------|
	                        	<----------->
	*/
	if subtlsrv.StartTime.Unix() >= tcs.EndTime.Unix() {
		return
	}

	/**   |-------------------|
	  <--------------------------->
	*/
	if subtlsrv.StartTime.Unix() < tcs.StartTime.Unix() && subtlsrv.EndTime.Unix() > tcs.EndTime.Unix() {
		tcs.TimeLineList.Init()
		return
	}
	/**        |-------------------|
	<------>
	*/
	if subtlsrv.StartTime.Unix() < tcs.StartTime.Unix() && subtlsrv.EndTime.Unix() > tcs.StartTime.Unix() && subtlsrv.EndTime.Unix() <= tcs.EndTime.Unix() {
		if nodeEnd, err = tcs.GetTimeLine(subtlsrv.EndTime); err != nil {
			return
		}
		if nodeEnd != nil {
			tl = nodeEnd.Value.(TimeLineSrv)
			tl.StartTime = subtlsrv.EndTime
			tcs.RemoveListAllBeforeItem(nodeEnd, false)
			tcs.StartTime = subtlsrv.EndTime
		} else {
			// 删除时段内的节点
			for e = tcs.TimeLineList.Front(); e != nil; e = next {
				next = e.Next()
				tl = e.Value.(TimeLineSrv)
				if tl.StartTime.Unix() > subtlsrv.StartTime.Unix() && tl.EndTime.Unix() < subtlsrv.EndTime.Unix() {
					tcs.TimeLineList.Remove(e)
				}
			}
			tl = tcs.TimeLineList.Front().Value.(TimeLineSrv)
			tcs.StartTime = tl.StartTime
		}
	}

	/**        |-------------------|
	<------>
	*/


	if subtlsrv.StartTime.Unix() >= tcs.StartTime.Unix() && subtlsrv.EndTime.Unix() <= tcs.EndTime.Unix() {
		if nodeBeg, err = tcs.GetTimeLine(subtlsrv.StartTime); err != nil || nodeBeg == nil {
			return
		}
		if nodeEnd, err = tcs.GetTimeLine(subtlsrv.EndTime); err != nil || nodeEnd == nil {
			return
		}
		/** 落在可用时段内
		情况一： |-------|
		           |****|
		**/
		if nodeBeg != nil && nodeEnd == nil {
			tlb = nodeBeg.Value.(TimeLineSrv)
			// 删除开始节点之后到结束时间点之间的Node
			for e = nodeBeg.Next(); e != nil; e = next {
				next = e.Next()
				tl = e.Value.(TimeLineSrv)
				if tl.EndTime.Unix() <= subtlsrv.EndTime.Unix() {
					tcs.TimeLineList.Remove(e)
				} else {
					break
				}
			}
			// 更新开始节点的结束时间
			//tlb.EndTime = subtlsrv.StartTime
			tlsrv			= TimeLineSrv{}
			tlsrv.StartTime = tlb.StartTime
			tlsrv.EndTime 	= subtlsrv.StartTime
			tlsrv.EffFactor = subtlsrv.EffFactor
			tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime)
			tcs.TimeLineList.InsertAfter(tlsrv, nodeBeg)
			//删除
			tcs.TimeLineList.Remove(nodeBeg)
		}
		/**
		情况二： |-------|   |-------|
		               |***|
		**/
		if nodeBeg == nil && nodeEnd == nil {
			tlsrv = TimeLineSrv{}
			tlsrv.StartTime = subtlsrv.StartTime
			tlsrv.EndTime = subtlsrv.EndTime
			tlsrv.EffFactor = subtlsrv.EffFactor
			// 删除开始节点之后到结束时间点之间的Node
			for e = tcs.TimeLineList.Front(); e != nil; e = next {
				next = e.Next()
				tl = e.Value.(TimeLineSrv)
				if tl.StartTime.Unix() > subtlsrv.StartTime.Unix() && tl.EndTime.Unix() < subtlsrv.EndTime.Unix() {
					tcs.TimeLineList.Remove(e)
				}
			}
		}
		/**
		情况三： |-------|   |-------|
		                  |**|
		**/
		if nodeBeg == nil && nodeEnd != nil {
			tle = nodeEnd.Value.(TimeLineSrv)
			// 删除开始节点到结束时间点之间的Node
			for e = tcs.TimeLineList.Front(); e != nil; e = next {
				next = e.Next()
				tl = e.Value.(TimeLineSrv)
				if tl.StartTime.Unix() > subtlsrv.StartTime.Unix() && tl.EndTime.Unix() < subtlsrv.EndTime.Unix() {
					tcs.TimeLineList.Remove(e)
				}
			}
			// 更新结束节点的开始时间
			//tle.StartTime = subtlsrv.EndTime
			tlsrv			= TimeLineSrv{}
			tlsrv.StartTime = subtlsrv.EndTime
			tlsrv.EndTime 	= tle.EndTime
			tlsrv.EffFactor = subtlsrv.EffFactor
			tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime)
			tcs.TimeLineList.InsertBefore(tlsrv, nodeEnd)
			//删除
			tcs.TimeLineList.Remove(nodeEnd)
		}
		/**
		情况四： |-------|   |-------|
		                   |****|
		*/
		if nodeBeg != nil && nodeEnd != nil {
			if nodeBeg != nodeEnd {
				tlb = nodeBeg.Value.(TimeLineSrv)
				tle = nodeEnd.Value.(TimeLineSrv)
				if tlb != tle {
					/**********
					1   /------/ /----/  /-------/    可用时间
							/--------------/         任务占用时间
						/---/              /-----/    得到的结果
					********************/

					// 删除两节点之间的所有节点
					for e = nodeBeg.Next(); e != nil && e != nodeEnd; e = next {
						next = e.Next()
						tcs.TimeLineList.Remove(e)
					}
					//拆成两部分
					tlsrv			= TimeLineSrv{}
					tlsrv.StartTime = tlb.StartTime
					tlsrv.EndTime 	= subtlsrv.StartTime
					tlsrv.EffFactor = subtlsrv.EffFactor
					tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime)
					tcs.TimeLineList.InsertBefore(tlsrv, nodeBeg)

					tlsrv			= TimeLineSrv{}
					tlsrv.StartTime = subtlsrv.EndTime
					tlsrv.EndTime 	= tle.EndTime
					tlsrv.EffFactor = subtlsrv.EffFactor
					tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime)
					tcs.TimeLineList.InsertAfter(tlsrv, nodeBeg)
					//删除当前的
					tcs.TimeLineList.Remove(nodeBeg)
					tcs.TimeLineList.Remove(nodeEnd)
				}
			} else {

				/**********

				2  /------------------/    可用时间
						/-------/          任务占用时间
				********************/
				tlb = nodeBeg.Value.(TimeLineSrv)
				//先插入,再删除
				tlsrv			= TimeLineSrv{}
				tlsrv.StartTime = tlb.StartTime
				tlsrv.EndTime 	= subtlsrv.StartTime
				tlsrv.EffFactor = subtlsrv.EffFactor
				tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime)
				tcs.TimeLineList.InsertBefore(tlsrv, nodeBeg)

				tlsrv			= TimeLineSrv{}
				tlsrv.StartTime = subtlsrv.EndTime
				tlsrv.EndTime 	= tlb.EndTime
				tlsrv.EffFactor = subtlsrv.EffFactor
				tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime)
				tcs.TimeLineList.InsertAfter(tlsrv, nodeBeg)

				// 删除当前节点
				tcs.TimeLineList.Remove(nodeBeg)
			}
		}
	}

	/**        |-------------------|
	<------>
	*/
	if subtlsrv.StartTime.Unix() >= tcs.StartTime.Unix() && subtlsrv.StartTime.Unix() < tcs.EndTime.Unix() && subtlsrv.EndTime.Unix() > tcs.EndTime.Unix() {
		if nodeBeg, err = tcs.GetTimeLine(subtlsrv.StartTime); err != nil {
			return
		}
		if nodeBeg != nil {
			tl = nodeBeg.Value.(TimeLineSrv)
			tl.EndTime = subtlsrv.StartTime
			tcs.RemoveListAllAfterItem(nodeBeg, false)
			tcs.EndTime = subtlsrv.StartTime

		} else {
			// 删除时段内的节点
			for e = tcs.TimeLineList.Front(); e != nil; e = next {
				next = e.Next()
				tl = e.Value.(TimeLineSrv)
				if tl.StartTime.Unix() > subtlsrv.StartTime.Unix() && tl.EndTime.Unix() < subtlsrv.EndTime.Unix() {
					tcs.TimeLineList.Remove(e)
				}
			}
			// 获取最后一个节点
			tl = tcs.TimeLineList.Back().Value.(TimeLineSrv)
			tcs.EndTime = tl.EndTime
		}
	}

	return
}

// 基于起始时间点和Duration计算在当前时间曲线上的结束时间点
func (tcs *TimeCurveSrv) CalEndTime(startTime time.Time, duration time.Duration) (sTime time.Time ,endTime time.Time) {
	var (
		i                                        int
		zeroDuration, calDuration, totalDuration time.Duration
	)
	// 处理临界条件
	if duration <= 0 {
		endTime = startTime
		return
	}
	// 如果计算起始时间点大于等于计划曲线的结束时间点
	if startTime.Unix() >= tcs.EndTime.Unix() {
		endTime = startTime.Add(duration)
		return
	}

	// 初始化
	calDuration = duration
	endTime = startTime

	// 如果计算起始时间点小于计划曲线的起始时间点
	if startTime.Unix() < tcs.StartTime.Unix() {
		if startTime.Add(duration).Unix() <= tcs.StartTime.Unix() {
			endTime = startTime.Add(duration)
			return
		} else {
			calDuration = duration - tcs.StartTime.Sub(startTime)
		}
	}
	if len(tcs.TimeLineArray) <= 0 {
		return
	}
	totalDuration = 0
	zeroDuration = 0
	/************
	*                / ------ /  ***  ------***-----      /
	*					  / -----*** ------***---     /
	*				 0	  1                           2  3
	* 横线代表可用时间，*代表不可用时间
	*问题：  求出时间2 的时间节点? 已知 时间1和时间3的节点，0-3的可用时间间隔，1-2的可用时间间隔
	*逻辑:   求出 0-1的时间间隔，  用0-3的时间间隔 减去（0-1）减去（1-2） 计算出（2-3）间隔 ，用3点时间点减去（2-3）时间间隔得出时间2的时间点
	**********************/
	startbool := true
	sTime = startTime
	for i = 0; i < len(tcs.TimeLineArray); i++ {
		if startTime.Unix() >= tcs.TimeLineArray[i].EndTime.Unix() {
			continue
		}

		if startbool {
			//记录时间0的节点
			zeroStartTime := tcs.TimeLineArray[i].StartTime
			//计算0-1时间间隔
			zeroDuration = utils.GetDuration(zeroStartTime, startTime, tcs.TimeLineArray[i].EffFactor)
			//如果开始时间落到中断时间区间内，则开始时间变成可用时间的开始时间
			if startTime.Unix() < tcs.TimeLineArray[i].StartTime.Unix(){
				sTime = tcs.TimeLineArray[i].StartTime
			}
			startbool = false
		}
		totalDuration = totalDuration + tcs.TimeLineArray[i].Duration
		if (totalDuration - zeroDuration) >= calDuration {
			endTime = tcs.TimeLineArray[i].GetEndTimeByDuration(totalDuration - calDuration - zeroDuration)
			return
		}

		//endTime = tcs.TimeLineArray[i].EndTime.Add(calDuration - totalDuration)
	}
	return
}

// 基于给定的两个时间点获取时间曲线上的Duration
func (tcs *TimeCurveSrv) CalDuration(startTime, endTime time.Time) (totalDuration time.Duration) {
	var (
		i                        int
		actStartTime, actEndTime time.Time
	)
	// 初始化
	totalDuration = 0
	// 临界条件处理
	if startTime.Unix() >= endTime.Unix() {
		totalDuration = endTime.Sub(startTime)
		return
	}
	if endTime.Unix() <= tcs.StartTime.Unix() || startTime.Unix() >= tcs.EndTime.Unix() {
		totalDuration = endTime.Sub(startTime)
		return
	}

	//        |-------------------|
	//     <------>
	if startTime.Unix() < tcs.StartTime.Unix() && endTime.Unix() > tcs.StartTime.Unix() && endTime.Unix() <= tcs.EndTime.Unix() {
		actStartTime = tcs.StartTime
		actEndTime = endTime
		totalDuration = tcs.StartTime.Sub(startTime)
	}

	//        |-------------------|
	//    <--------------------------->
	if startTime.Unix() < tcs.StartTime.Unix() && endTime.Unix() > tcs.EndTime.Unix() {
		actStartTime = tcs.StartTime
		actEndTime = tcs.EndTime
		totalDuration = tcs.StartTime.Sub(startTime) + endTime.Sub(tcs.EndTime)
	}

	//        |-------------------|
	//           <------>
	if startTime.Unix() >= tcs.StartTime.Unix() && endTime.Unix() <= tcs.EndTime.Unix() {
		actStartTime = startTime
		actEndTime = endTime
		totalDuration = 0
	}

	//        |-------------------|
	//                        <------>
	if startTime.Unix() >= tcs.StartTime.Unix() && endTime.Unix() > tcs.EndTime.Unix() {
		actStartTime = startTime
		actEndTime = tcs.EndTime
		totalDuration = endTime.Sub(tcs.EndTime)
	}

	/**# 计算落在计划时间区间内的有效时间
	#                    ===================
	#NO         |-------|
	#NO                                     |-----|
	#1.YES         |--------|
	#2.YES         |---------------------------|
	#3.YES                  |------------|
	#4.YES                  |---------------------| **/
	for i = 0; i < len(tcs.TimeLineArray); i++ {
		if actEndTime.Unix() <= tcs.TimeLineArray[i].StartTime.Unix() || actStartTime.Unix() >= tcs.TimeLineArray[i].EndTime.Unix() {
			continue
		}
		if tcs.TimeLineArray[i].EffFactor <= 0 {
			tcs.TimeLineArray[i].EffFactor = 1.0
		}
		if actStartTime.Unix() < tcs.TimeLineArray[i].StartTime.Unix() && actEndTime.Unix() > tcs.TimeLineArray[i].StartTime.Unix() {
			if actEndTime.Unix() <= tcs.TimeLineArray[i].EndTime.Unix() {
				// 条件1
				totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByEndTime(actEndTime)
				break
			} else {
				// 条件2
				totalDuration = totalDuration + tcs.TimeLineArray[i].Duration
				actStartTime = tcs.TimeLineArray[i].EndTime
			}
		}

		if actStartTime.Unix() >= tcs.TimeLineArray[i].StartTime.Unix() && actStartTime.Unix() < tcs.TimeLineArray[i].EndTime.Unix() {
			if actEndTime.Unix() <= tcs.TimeLineArray[i].EndTime.Unix() {
				// 条件3
				totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByStartEndTime(actStartTime, actEndTime)
				break
			} else {
				// 条件4
				totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByStartTime(actStartTime)
				actStartTime = tcs.TimeLineArray[i].EndTime
			}
		}
	}
	return
}


// 计算负载,每天的可用时间求和
func (tcs *TimeCurveSrv) SumDuration(startTime, endTime time.Time) (totalDuration time.Duration) {
	var (
		i                        int
		actStartTime, actEndTime time.Time
	)
	// 初始化
	totalDuration = 0
	// 临界条件处理
	if startTime.Unix() >= endTime.Unix() {
		totalDuration = endTime.Sub(startTime)
		return
	}
	if endTime.Unix() <= tcs.StartTime.Unix() || startTime.Unix() >= tcs.EndTime.Unix() {
		totalDuration = endTime.Sub(startTime)
		return
	}

	//        |-------------------|
	//     <------>
	if startTime.Unix() < tcs.StartTime.Unix() && endTime.Unix() > tcs.StartTime.Unix() && endTime.Unix() <= tcs.EndTime.Unix() {
		actStartTime = tcs.StartTime
		actEndTime = endTime
		//不用做计算
		//totalDuration = tcs.StartTime.Sub(startTime)
	}

	//        |-------------------|
	//    <--------------------------->
	if startTime.Unix() < tcs.StartTime.Unix() && endTime.Unix() > tcs.EndTime.Unix() {
		actStartTime = tcs.StartTime
		actEndTime = tcs.EndTime
		totalDuration = tcs.StartTime.Sub(startTime) + endTime.Sub(tcs.EndTime)
	}

	//        |-------------------|
	//           <------>
	if startTime.Unix() >= tcs.StartTime.Unix() && endTime.Unix() <= tcs.EndTime.Unix() {
		actStartTime = startTime
		actEndTime = endTime
		totalDuration = 0
	}

	//        |-------------------|
	//                        <------>
	if startTime.Unix() >= tcs.StartTime.Unix() && endTime.Unix() > tcs.EndTime.Unix() {
		actStartTime = startTime
		actEndTime = tcs.EndTime
		totalDuration = endTime.Sub(tcs.EndTime)
	}
	/**# 计算落在计划时间区间内的有效时间
	#                    ===================
	#NO         |-------|
	#NO                                     |-----|
	#1.YES         |--------|
	#2.YES         |---------------------------|
	#3.YES                  |------------|
	#4.YES                  |---------------------| **/
	for i = 0; i < len(tcs.TimeLineArray); i++ {
		if actEndTime.Unix() <= tcs.TimeLineArray[i].StartTime.Unix() || actStartTime.Unix() >= tcs.TimeLineArray[i].EndTime.Unix() {
			continue
		}
		if tcs.TimeLineArray[i].EffFactor <= 0 {
			tcs.TimeLineArray[i].EffFactor = 1.0
		}
		if actStartTime.Unix() < tcs.TimeLineArray[i].StartTime.Unix() && actEndTime.Unix() > tcs.TimeLineArray[i].StartTime.Unix() {
			if actEndTime.Unix() <= tcs.TimeLineArray[i].EndTime.Unix() {
				// 条件1
				totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByEndTime(actEndTime)
				break
			} else {
				// 条件2
				totalDuration = totalDuration + tcs.TimeLineArray[i].Duration
				actStartTime = tcs.TimeLineArray[i].EndTime
			}
		}

		if actStartTime.Unix() >= tcs.TimeLineArray[i].StartTime.Unix() && actStartTime.Unix() < tcs.TimeLineArray[i].EndTime.Unix() {
			if actEndTime.Unix() <= tcs.TimeLineArray[i].EndTime.Unix() {
				// 条件3
				totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByStartEndTime(actStartTime, actEndTime)
				break
			} else {
				// 条件4
				totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByStartTime(actStartTime)
				actStartTime = tcs.TimeLineArray[i].EndTime
			}
		}
	}
	return
}