/* $Id: WebDavSyncData.java 351 2011-09-15 17:17:46Z shayashi $ */
package webdav;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;

import org.apache.commons.lang.StringUtils;

import smart_gs.logical.Preference;
//import sun.java2d.SunGraphicsEnvironment.TTFilter;

import webdav.table.PropFindSort;

public class WebDavSyncData {
	protected ArrayList syncList = new ArrayList();
	protected HashMap localMap = new HashMap();
	protected String webdavrootpath;
	protected String localrootpath;
	protected ArrayList downloadInfoList = new ArrayList();
	protected int max = 0;
	
	public static void main(String args[]){
		WebDavSyncData webDavSyncData = new WebDavSyncData();
		// Ignore status this case, as it might not cause problem.
		// 20110914 shayashi.
		Preference.getInstance().load();
		Preference preference = Preference.getInstance();
		// dscの処理
		ArrayList downloadList = new ArrayList();
		{
			webDavSyncData.init();
			String path = preference.getDscFolderPathString();
			File file = new File(path);
			System.out.println(file.getAbsolutePath());
			String root = file.getAbsolutePath();
			root = root.substring(0,root.lastIndexOf(file.getName()));
			webDavSyncData.local(path,root);
			webDavSyncData.webdav("smart_gs2",file.getName());
			webDavSyncData.sync(new File(root));
		}
		// imageの処理
		{
			webDavSyncData.init();
			String path = preference.getImageFolderPathString();
			File file = new File(path);
			System.out.println(file.getAbsolutePath());
			String root = file.getAbsolutePath();
			root = root.substring(0,root.lastIndexOf(file.getName()));
			webDavSyncData.local(path,root);
			webDavSyncData.webdav("smart_gs2",file.getName());
			webDavSyncData.sync(new File(root));
		}

	}
	public boolean initall(){
		downloadInfoList = new ArrayList();
		max = 0;
		return init();
	}

	public boolean init(){
		localMap = new HashMap();
		syncList = new ArrayList();
		this.webDavProcessor = WebDavProcessor.getInstance();
		if(webDavProcessor == null){
			return false;
		}else{
			return true;
		}
	}
	public void sync(File rootfile){
		ArrayList downloadList = new ArrayList();
		String path = rootfile.getPath();
		path = StringUtils.replace(path, "\\", "/");
		for(int i=0;i<syncList.size();i++){
			SyncInfo syncInfo = (SyncInfo)syncList.get(i);
			String key = syncInfo.getKey();
			if(localMap.containsKey(key)){
				PropFindInfo propFindInfo = syncInfo.getPropFindInfo();
				Date date = propFindInfo.getLastmodified();
				long webtime = date.getTime();
				File file = (File)localMap.get(key);
				long localtime = file.lastModified();
				if(file.exists()){
					if(file.isDirectory()){
						continue;
					}
				}
				if(webtime > localtime){
					DownLoadSyncInfo downLoadSyncInfo = new DownLoadSyncInfo();
					downLoadSyncInfo.setKey(key);
					downLoadSyncInfo.setSyncInfo(syncInfo);
					downloadList.add(downLoadSyncInfo);
					// download(key,path,syncInfo);
				}
			}else{
				DownLoadSyncInfo downLoadSyncInfo = new DownLoadSyncInfo();
				downLoadSyncInfo.setKey(key);
				downLoadSyncInfo.setSyncInfo(syncInfo);
				downloadList.add(downLoadSyncInfo);
				// download(key,path,syncInfo);
			}
		}
		max+=downloadList.size();
		WebDavSyncDownloadInfo webDavSyncDownloadInfo = new WebDavSyncDownloadInfo();
		webDavSyncDownloadInfo.setPath(path);
		webDavSyncDownloadInfo.setDownloadList(downloadList);
		downloadInfoList.add(webDavSyncDownloadInfo);
	}
	public void syncstart(){
		if(max != 0){
			int input = JOptionPane.showConfirmDialog(new JFrame(), max + " file found, Do you update it?" );
			if (input == JOptionPane.OK_OPTION) {
				WebDavSyncProgressBar jpt = new WebDavSyncProgressBar(new JFrame(),this,"Download",0,max);
		    	jpt.setLocationRelativeTo(null);
		    	jpt.setDownloadInfoList(downloadInfoList);
		    	jpt.sync();
		    	jpt.setVisible( true );
		    	jpt.join();
			}
		}else{
			JOptionPane.showMessageDialog(new JFrame(), "It is the latest. ");
		}
	}
	public void download(String key,String path,SyncInfo syncInfo){
		String localfileStr = path + key;
		// ディレクトリの確認
		{
			File localfile = new File(localfileStr);
			File localdir = new File(path + syncInfo.getPath());
			if(!localdir.exists()){
				if(!localdir.mkdirs()){
					return;
				}
			}
			if(!syncInfo.getPropFindInfo().isDirectory()){
				String downloadpath = syncInfo.getPropFindInfo().getPath();
				String downloadfile = syncInfo.getPropFindInfo().getDisplayname();
				try {
					webDavProcessor.download(downloadpath, downloadfile, localfile);
				} catch (IOException e) {
					// TODO 自動生成された catch ブロック
					e.printStackTrace();
				}
			}
		}
	}
	
	public void local(String dirPath,String match){
		localrootpath = match;
		searchDirectory(dirPath);
		
	}
	boolean searchDirectory(String dirPath) {
		File dir = new File(dirPath); 
		File[] files = dir.listFiles();
		int i;
		for (i = 0; i < files.length; i++) {
			String key = files[i].getPath();
			key = key.substring(localrootpath.length() - 1,key.length());
			key = StringUtils.replace(key, "\\", "/");
			if (files[i].isFile()) {
//				System.out.println(key);
				localMap.put(key, files[i]);
//				System.out.println("F:" + dirPath + ":" + files[i].getName());
			}else if (files[i].isDirectory()) {
				if(!key.endsWith("/")){
					key+="/";
				}
//				System.out.println(key);
				localMap.put(key, files[i]);

//				System.out.println("D:" + dirPath + ":" + files[i].getName());
				if (searchDirectory(files[i].getPath()) == false)
					return false;
			}
		}
		return true;			
	}
	
	protected WebDavProcessor webDavProcessor;
	
	public void webdav(String startpath,String match){
		
		PropFindInfo[] propFindInfoChild = null;
		this.webdavrootpath = startpath;
		try{
			PropFindInfo[] propFindInfo;
			if(startpath != null){
				propFindInfo = webDavProcessor.getPropFindInfo(startpath, 0);
			}else{
				propFindInfo = webDavProcessor.getPropFindInfo("", 0);
			}
			if(propFindInfo != null){
				try{
					propFindInfoChild = webDavProcessor.getPropFindInfo(propFindInfo[0].getPath(), 1);
					if(propFindInfoChild != null){
						for(int i=0;i<propFindInfoChild.length;i++){
							if(propFindInfoChild[i].isDirectory()){
								if(propFindInfoChild[i].getDisplayname().toLowerCase().equals(match)){
									searchDirectoryWebDav(propFindInfoChild[i].getPath());
								}
							}
						}
					}
				}catch(Exception ex){
					ex.printStackTrace();
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	public void searchDirectoryWebDav(String startpath){
		PropFindInfo[] propFindInfoChild = null;
		try{
			PropFindInfo[] propFindInfo;
			if(startpath != null){
				propFindInfo = webDavProcessor.getPropFindInfo(startpath, 0);
			}else{
				propFindInfo = webDavProcessor.getPropFindInfo("", 0);
			}
			if(propFindInfo != null){
				try{
					propFindInfoChild = webDavProcessor.getPropFindInfo(propFindInfo[0].getPath(), 1);
					if(propFindInfoChild != null){
						for(int i=0;i<propFindInfoChild.length;i++){
							String path = propFindInfoChild[i].getPath();
							String key = "";
							if(path.indexOf(webdavrootpath) != -1){
								key = path.substring(path.indexOf(webdavrootpath) + webdavrootpath.length(), path.length());
							}
							if(!propFindInfoChild[i].isDirectory()){
								SyncInfo syncInfo = new SyncInfo();
								syncInfo.setPath(key);
								key += propFindInfoChild[i].getDisplayname();
								syncInfo.setKey(key);
								syncInfo.setPropFindInfo(propFindInfoChild[i]);
								syncList.add(syncInfo);
//								System.out.println(key);
//								System.out.println("F:" + propFindInfoChild[i].getPath() + propFindInfoChild[i].getDisplayname());
							}else{
								SyncInfo syncInfo = new SyncInfo();
								syncInfo.setKey(key);
								syncInfo.setPath(key);
								syncInfo.setPropFindInfo(propFindInfoChild[i]);
								syncList.add(syncInfo);
//								System.out.println("D:" + propFindInfoChild[i].getPath() + propFindInfoChild[i].getDisplayname());
								searchDirectoryWebDav(propFindInfoChild[i].getPath());
							}
						}
					}
				}catch(Exception ex){
					ex.printStackTrace();
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	class SyncInfo{
		protected String key;
		protected String path;
		protected PropFindInfo propFindInfo;

		public String getKey() {
			return key;
		}
		public void setKey(String key) {
			this.key = key;
		}
		public String getPath() {
			return path;
		}
		public void setPath(String path) {
			this.path = path;
		}
		public PropFindInfo getPropFindInfo() {
			return propFindInfo;
		}
		public void setPropFindInfo(PropFindInfo propFindInfo) {
			this.propFindInfo = propFindInfo;
		}
		
	}
	class DownLoadSyncInfo{
		protected String key;
		protected String path;
		protected SyncInfo syncInfo;
		
		public String getKey() {
			return key;
		}
		public void setKey(String key) {
			this.key = key;
		}
		public SyncInfo getSyncInfo() {
			return syncInfo;
		}
		public void setSyncInfo(SyncInfo syncInfo) {
			this.syncInfo = syncInfo;
		}
	}

}
