void THISSequence::setDrawRange(ofRange newRange)
{
    if(newRange != drawRange) {
        drawRange = newRange;
        recomputePreview();
    }
}
void ofxTLAudioTrack::draw(){
	
	if(!soundLoaded || player.getBuffer().size() == 0){
		ofPushStyle();
		ofSetColor(timeline->getColors().disabledColor);
		ofRectangle(bounds);
		ofPopStyle();
		return;
	}
		
	if(shouldRecomputePreview || viewIsDirty){
		recomputePreview();
	}

    ofPushStyle();
    ofSetColor(timeline->getColors().keyColor);
    ofNoFill();
    
    for(int i = 0; i < previews.size(); i++){
        ofPushMatrix();
        ofTranslate( normalizedXtoScreenX(computedZoomBounds.min, zoomBounds)  - normalizedXtoScreenX(zoomBounds.min, zoomBounds), 0, 0);
        ofScale(computedZoomBounds.span()/zoomBounds.span(), 1, 1);
        previews[i].draw();
        ofPopMatrix();
    }
    ofPopStyle();
}
void THISSequence::loadSequence(string directoryName)
{
    if(loaded) {
        clear();
    }
    cout << "LOADING SEQUENCE " << directoryName << endl;

    loaded = false;

    ofDirectory list;
    list.allowExt("png");
    list.allowExt("jpg");

    directory = directoryName;
    int numFiles = list.listDir(directory);
    if(numFiles == 0) {
        ofLog(OF_LOG_ERROR, "THIS_Sequence -- ERROR -- Loaded sequence with no valid frames " + directory);
        return;
    }

    cout << "FOUND " << numFiles << endl;

    //create thumb directory
    if(!ofDirectory::doesDirectoryExist(directory+"/thumbs/")) {
        ofDirectory::createDirectory(directory+"/thumbs/");
    }

    if(imageType == OF_IMAGE_UNDEFINED) {
        //sniff the first file
        ofImage testImage;
        testImage.loadImage(list.getPath(0));
        imageType = testImage.getPixelsRef().getImageType();
    }

    for(int i = 0; i < numFiles; i++) {
        string frameFileName =  list.getPath(i);
        THISFrame* frame = new THISFrame();
        frame->setType(imageType);
        frame->setFrame(frameFileName);
        frames.push_back(frame);
    }

    cout << "CREATING FRAMES " << numFiles << endl;

    frames[0]->loadFrame();

    imageWidth = frames[0]->getFullFrameWidth();
    imageHeight = frames[0]->getFullFrameHeight();

    thumbWidth = frames[0]->getThumbWidth();
    thumbHeight = frames[0]->getThumbHeight();

    loaded = true;

    recomputePreview();

    cout << "DONE CREATING FRAMES " << numFiles << " img " << imageWidth << "x" << imageHeight << " thumb " << thumbWidth << "x" << thumbHeight << endl;

}
void THISSequence::setDrawWidth(float _width)
{
    if(_width != drawWidth) {
        drawWidth = _width;
        widthSet = true;
        recomputePreview();
    }
}
void ofxTLAudioTrack::update()
{
	//cout << "ofxTLAudioTrack:: update" <<  player.getPosition() << endl;
	float pos = player.getPosition();
	if (!zoomBounds.contains(pos) || oldpos != pos) {
		recomputePreview();
		oldpos = pos;
	}
}
void ofxTLAudioTrack::draw(){
	
	if(!soundLoaded || player.getBuffer().size() == 0){
		ofPushStyle();
		ofSetColor(timeline->getColors().disabledColor);
		ofRectangle(bounds);
		ofPopStyle();
		return;
	}
		
	if(shouldRecomputePreview || viewIsDirty){
//		cout << "recomputing waveform for audio file " << getSoundfilePath() << endl;
		recomputePreview();
	}


    ofPushStyle();
    ofSetColor(timeline->getColors().keyColor);
    ofNoFill();
    
    for(int i = 0; i < previews.size(); i++){
        ofPushMatrix();
        ofTranslate( normalizedXtoScreenX(computedZoomBounds.min, zoomBounds)  - normalizedXtoScreenX(zoomBounds.min, zoomBounds), 0, 0);
        ofScale(computedZoomBounds.span()/zoomBounds.span(), 1, 1);
        previews[i].draw();
        ofPopMatrix();
    }
    ofPopStyle();
	
	if(getIsPlaying() || timeline->getIsPlaying()){
		ofPushStyle();
		
		//will refresh fft bins for other calls too
		vector<float>& bins = getFFTSpectrum(defaultFFTBins);
		float binWidth = bounds.width / bins.size();
		//find max
		float averagebin = 0 ;
		for(int i = 0; i < bins.size(); i++){
			maxBinReceived = MAX(maxBinReceived, bins[i]);
			averagebin += bins[i];
		}
		averagebin /= bins.size();
		
		ofFill();
		ofSetColor(timeline->getColors().disabledColor, 120);
		for(int i = 0; i < bins.size(); i++){
			float height = bounds.height * bins[i]/maxBinReceived;
			float y = bounds.y + bounds.height - height;
			ofRect(i*binWidth, y, binWidth, height);
		}
		
		ofPopStyle();
	}
}
void ofxTLAudioTrack::draw(){
	
	if(!soundLoaded || player.getBuffer().size() == 0){
		ofPushStyle();
		ofSetColor(timeline->getColors().disabledColor);
		ofRectangle(bounds);
		ofPopStyle();
		return;
	}
		
	if(shouldRecomputePreview || viewIsDirty){
//		cout << "recomputing waveform for audio file " << getSoundfilePath() << endl;
		recomputePreview();
	}

    ofPushStyle();
    ofSetColor(timeline->getColors().keyColor);
    ofNoFill();
    
    for(int i = 0; i < previews.size(); i++){
        ofPushMatrix();
        ofTranslate( normalizedXtoScreenX(computedZoomBounds.min, zoomBounds) - normalizedXtoScreenX(zoomBounds.min, zoomBounds), 0, 0);
        ofScale(computedZoomBounds.span()/zoomBounds.span(), 1, 1);
        previews[i].draw();
        ofPopMatrix();
    }
    ofPopStyle();
	

    //fft draw in audioTrack
    if(bDrawFFT){
        ofPushStyle();
        
        //will refresh fft bins for other calls too
        vector<float>& bins = getFFT();
        float binWidth = bounds.width / bins.size();
        
        ofFill();
        ofSetColor(timeline->getColors().disabledColor, 120);
        for(int i = 0; i < bins.size(); i++){
            float height = MIN(bounds.height * bins[i], bounds.height);
            float y = bounds.y + bounds.height - height;
            ofRect(i*binWidth, y, binWidth, height);
        }
        
        ofPopStyle();
    }
}
void ofxTLImageSequence::setZoomBounds(ofRange zoomBoundsPercent){
	ofxTLElement::setZoomBounds(zoomBoundsPercent);
	recomputePreview();
}
void ofxTLImageSequence::drawRectChanged(){
	recomputePreview();
}
void ofxTLAudioTrack::draw(){
	
	if(!soundLoaded || player.getBuffer().size() == 0){
		ofPushStyle();
		ofSetColor(timeline->getColors().disabledColor);
		ofRectangle(bounds);
		ofPopStyle();
		return;
	}
		
	if(shouldRecomputePreview || viewIsDirty){
		recomputePreview();
	}

	//cout << "ofxTLAudioTrack::draw" << endl;

    ofSetColor(255, 255, 255, 205);
    ofFill();
    ofRect(bounds);
    ofPushStyle();
    //ofSetColor(timeline->getColors().keyColor);
    ofSetColor(0, 0 , 0, 255);
    ofNoFill();
    
    for(int i = 0; i < previews.size(); i++){
        ofPushMatrix();
        ofTranslate( normalizedXtoScreenX(computedZoomBounds.min, zoomBounds)  - normalizedXtoScreenX(zoomBounds.min, zoomBounds), 0, 0);
        ofScale(computedZoomBounds.span()/zoomBounds.span(), 1, 1);
        previews[i].draw();
        ofPopMatrix();
    }
    ofPopStyle();
	
	if(getIsPlaying() || timeline->getIsPlaying()){
		ofPushStyle();
		
		//will refresh fft bins for other calls too
		vector<float>& bins = getFFTSpectrum(defaultFFTBins);
		float binWidth = bounds.width / bins.size();
		//find max
		float averagebin = 0 ;
		for(int i = 0; i < bins.size(); i++){
			maxBinReceived = MAX(maxBinReceived, bins[i]);
			averagebin += bins[i];
		}
		averagebin /= bins.size();
		
		ofFill();
		ofSetColor(timeline->getColors().disabledColor, 120);
		for(int i = 0; i < bins.size(); i++){
			float height = bounds.height * bins[i]/maxBinReceived;
			float y = bounds.y + bounds.height - height;
			ofRect(bounds.x + i*binWidth, y, binWidth, height);
		}
		
		ofPopStyle();
	}

	// playhead 
	ofPushStyle();
	ofSetColor(0, 0, 0, 255);
	float x = normalizedXtoScreenX( oldpos, zoomBounds);
	ofLine(x, bounds.y, x, bounds.y + bounds.height);
	ofSetLineWidth(3);
	ofPopStyle();

	/*
	float pos = player.getPosition();
	if (pos) {
		ofxTLZoomer2D *zoom = (ofxTLZoomer2D*)timeline->getZoomer();
		ofRange z = zoom->getViewRange();
		ofRange oldz = z;
		float c = z.center(); 
		float d = pos - c;

		z.min = ofClamp(z.min + d, 0, 1); z.max = ofClamp(z.max + d, 0, 1);
		if (z.min == .0 && z.span() < oldz.span())
			z.max = oldz.max - oldz.min;
		if (z.max == 1. && z.span() < oldz.span())
			z.min = z.max - oldz.max + oldz.min;
	}*/




	// draw markers:
	for (vector<AlignMarker>::iterator m = markers.begin(); m != markers.end(); m++) {
		float xn = screenXtoNormalizedX(millisToScreenX(m->ms));
		if (zoomBounds.contains(xn)) {
			float x = timeline->normalizedXtoScreenX(xn, zoomBounds);
			if (m->selected)
				ofSetColor(255, 0, 0, 255);
			else 
				ofSetColor(0, 0, 0, 255);
			ofLine(x, bounds.y, x, bounds.y+bounds.height);
			m->rect = ofRectangle(x - 5, bounds.y + bounds.height - 12, 10, 10);
			ofSetColor(10, 0, 200, 100);
			ofFill();
			ofRect(m->rect);

			//cout << "m:" << m->ms << endl;
			ofSetColor(0, 0, 0, 255);
			timeline->getFont().drawString(ofToString(m->ms), x+1, bounds.y + 30);
		}
	}
	
}