//
// Mining module for TETDM 
// Panoramic.java Version 0.30
// Copyright(C) 2011 WATARU SUNAYAMA All RIGHTS RESERVED.
// This program is provided under the license.
// You Should read the README file.
//

package module.MiningModules.Panoramic;

import source.*;
import source.TextData.*;
import source.Utility.*;

import java.io.*;
import java.util.*;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;


public class Panoramic extends MiningModule implements ActionListener
{
	PvsR pvs1;
	int line;

	JPanel subpanel1, subpanel2;	
	JLabel tf1;	
	JButton execute;	
	JToggleButton indica, inform;
	ButtonGroup group1;	
	JButton conclude;	
	JButton	reset, minus, plus, minus10, plus10;
	JToggleButton comp, back, view, feat;
		
	String summarized_text;
	
//	NewMapData map;
	
	public Panoramic()
	{
		setModuleID(11);
		pairingVisualizationID = new int[]{1,8};
		focusClickExecute = true;		
	}
	
	public void initializePanel(){}
	{
		line = 10;
		
//		operationPanel.setLayout(new BorderLayout());
		
//		subpanel1 = new JPanel(new GridLayout());
//		operationPanel.add(subpanel1);
		
		tf1 = new JLabel();
//		subpanel1.add(tf1);
	operationPanel.add(tf1);
		
		subpanel2 = new JPanel(new GridLayout());
		operationPanel.add(subpanel2, BorderLayout.SOUTH);		
        subpanel2.setBackground(Color.RED);
		
		execute = new JButton("Summarize");
        execute.setBackground(Color.RED);
        execute.addActionListener(this);
		subpanel2.add(execute);
		
		indica = new JToggleButton("Indicative");
		indica.setBackground(Color.CYAN);
		indica.addActionListener(this);
		subpanel2.add(indica);
		indica.setSelected(true);
		
		inform = new JToggleButton("Informative");		
		inform.setBackground(Color.CYAN);
		inform.addActionListener(this);
		subpanel2.add(inform);
		
		group1 = new ButtonGroup();
		group1.add(indica);
		group1.add(inform);
		
		conclude = new JButton("Conclude");		
        conclude.setBackground(Color.RED);
        conclude.addActionListener(this);
		subpanel2.add(conclude);		

		inform.setEnabled(false);		/////
		conclude.setEnabled(false);		/////
		
		reset = new JButton("Reset Number");
		reset.setBackground(Color.YELLOW);
        reset.addActionListener(this);
		subpanel2.add(reset);
		
		
		
		minus = new JButton("<");
		minus.setBackground(Color.YELLOW);
        minus.addActionListener(this);
		subpanel2.add(minus);
		
		plus = new JButton(">");		
        plus.setBackground(Color.YELLOW);
        plus.addActionListener(this);
		subpanel2.add(plus);
		
		minus10 = new JButton("<<");		
		minus10.setBackground(Color.YELLOW);
        minus10.addActionListener(this);
		subpanel2.add(minus10);		
		
		plus10 = new JButton(">>");		
        plus10.setBackground(Color.YELLOW);
        plus10.addActionListener(this);
		subpanel2.add(plus10);
		
		comp = new JToggleButton("Add Viewpoint");		
		comp.setBackground(Color.CYAN);
		comp.addActionListener(this);
		subpanel2.add(comp);
		comp.setSelected(true);
		
		back = new JToggleButton("Background");		
		back.setBackground(Color.CYAN);
		back.addActionListener(this);
		subpanel2.add(back);
		back.setSelected(true);
		
		view = new JToggleButton("Viewpoint");		
		view.setBackground(Color.CYAN);
		view.addActionListener(this);
		subpanel2.add(view);
		view.setSelected(true);
		
		feat = new JToggleButton("Feature");		
		feat.setBackground(Color.CYAN);
		feat.addActionListener(this);
		subpanel2.add(feat);
		feat.setSelected(true);
	}	
	
	public void initializeData()
	{		
		tf1.setText("OUTPUT Sentences = "+Integer.toString(line));
	}
	
	public void miningOperations(int optionNumber)
	{
		switch(optionNumber)
		{
			case 4502:	
			case 0:
				summarized_text = exepvs();				
				//for text display
				setData(0,summarized_text);
				
				//for fujisan
				make_map_data();

				//for table display
				//set_data();
				
				comp.setSelected(false);	// 
				back.setSelected(false);	//
				break;
				
			case 1:
				line = 1;
				summarized_text = exepvs();
				setData(1,summarized_text);
				break;
		}
	}	
	

	void make_map_data()
	{
		//for fujisan
		int sbase,back,feat,topic2;
		back = feat = topic2 = 0;
		sbase = pvs1.sbasenum;
		
		int sbase_idlist[] = new int[sbase];
		for(int i=0;i<sbase;i++)
			sbase_idlist[i] = pvs1.sbase_idlist[i];		
		
//		System.out.println("sbase= "+sbase);
		
		for(int i=0;i<pvs1.keyword_num;i++)// Must consider the order of value
		{
			if(pvs1.key2[i].score[1] > 0 && topic2 < 10)	//TOPIC with low value
			{
				int j;
				for(j=0;j<sbase;j++)
					if(i == sbase_idlist[j])
						break;
				
				if(j == sbase)
					topic2++;				
			}			
			else if(pvs1.key2[i].score[0] > 0 && back < 15)
				back++;
			else if(pvs1.key2[i].score[2] > 0 && feat < 15)
				feat++;
		}
		
		int topic_idlist[] = new int[topic2];
		int back_idlist[] = new int[back];
		int feat_idlist[] = new int[feat];		
		
		back = feat = topic2 = 0;		
		for(int i=0;i<pvs1.keyword_num;i++)
		{
			if(pvs1.key2[i].score[1] > 0 && topic2 < 10)	//TOPIC with low value
			{
				int j;
				for(j=0;j<sbase;j++)
					if(i == sbase_idlist[j])
						break;
				
				if(j == sbase)
					topic_idlist[topic2++] = i;				
			}			
			else if(pvs1.key2[i].score[0] > 0 && back < 15)
				back_idlist[back++] = i;
			else if(pvs1.key2[i].score[2] > 0 && feat < 15)
				feat_idlist[feat++] = i;				
			
		}

		setData(77,sbase_idlist);			// option is not intend to some specified modules		
		setData(50,topic_idlist);
		setData(51,back_idlist);
		setData(52,feat_idlist);
	}	
   

	
	//Action listener
	public void actionPerformed(ActionEvent e)
	{
		insideOfActionPerformed(e);
		
		
		//Execute summarization
		if(e.getSource() == execute)
		{
			if(indica.isSelected())
			{
				summarized_text = exepvs();
				setData(0,summarized_text);
				make_map_data();/**/
				displayOperations(0);
				
				
			}
/*			else
			{
				int sbasenum = text.sbasenum;
				int sbase_idlist[]= new int[sbasenum];
				if(text.sbasenum != 0)
					for(int i=0;i<sbasenum;i++)
						sbase_idlist[i] = text.sbase_idlist[i];
				
				Inform inf1 = new Inform(text, line, 0,1,1, english);
				original_text = inf1.output_summary();
				System.out.println("---Panoramic View System InFormative("+inf1.total_select+"/"+text.sentenceNumber+")---");
				
				if(sbasenum == 0)
					text.sbasenum = 0;
				else
				{
					for(int i=0;i<sbasenum;i++)
						text.sbase_idlist[i] = sbase_idlist[i];
					text.sbasenum = sbasenum;
				}
			}
			init_editor();*/
		}
		if(e.getSource() == conclude)
		{
/*			LabelData label = new LabelData(text, english);
			original_text = label.output_conclusion(line);
			init_editor();			*/
		}
		
		//Input a number of output sentences
		if(e.getSource() == minus)
			if(line > 0)
			{
 				line--;
				tf1.setText("OUTPUT Sentences = "+Integer.toString(line));
			}
		
		if(e.getSource() == plus)
		{
			line++;
			tf1.setText("OUTPUT Sentences = "+Integer.toString(line));			
		}
		
		if(e.getSource() == minus10)
			if(line > 9)
			{
				line -= 10;
				tf1.setText("OUTPUT Sentences = "+Integer.toString(line));				
			}
		
		if(e.getSource() == plus10)
		{
			line += 10;
			tf1.setText("OUTPUT Sentences = "+Integer.toString(line));			
		}
		
		if(e.getSource() == reset)
		{
			line = 10;
			tf1.setText("OUTPUT Sentences = "+Integer.toString(line));			
		}		
	}
	
	public String exepvs()
	{
		boolean c=false;
		double b=0,v=0,f=0;
		if(comp.isSelected())
			c = true;
		if(back.isSelected())
			b = 1;
		if(view.isSelected())
			v = 1;
		if(feat.isSelected())
			f = 1;
		
		pvs1 = new PvsR();
		pvs1.set_text(text);
		pvs1.set_parameters(line, c,b,v,f);
		pvs1.exec();
//		System.out.println("---Panoramic View System InDicative("+pvs1.select_number+"/"+text.sentenceNumber+")---");
		return pvs1.output_summary();
	}
	
	public int[] get_int_array_data(int n)
	{
		boolean c=true;
		double b=1.0, v=1.0, f=1.0;
		
		pvs1 = new PvsR();
		pvs1.set_text(text);
		pvs1.set_parameters(line, c,b,v,f);
		pvs1.exec();		
		
		int sbasenum;
		int sbase_idlist[];
		
		sbasenum = pvs1.sbasenum;
		sbase_idlist = new int[sbasenum];
		for(int i=0;i<sbasenum;i++)
			sbase_idlist[i] = pvs1.sbase_idlist[i];
		
		return sbase_idlist;
	}


class SentenceData2
{
	double score[] = new double[3];	//Score of a sentence(background, viewpoint, feature)
	int rank[] = new int[3];		//Rank of a sentence(background, viewpoint, feature)
	int ranktotal;					//Sum of ranks of sentence
	int finalrank;					//Final rank of a sentence	
	
	SentenceData2(){}
}

class KeywordData2// extends KeywordData
{
	double score[] = new double[3];	//Score of a sentence(background, viewpoint, feature)
	
	KeywordData2(){}
}

class PvsR
{
	TextData text;
	
	int sentence_num;	//Number of sentences
	SentenceData sen[];
	SentenceData2 sen2[];	
	
	int keyword_num;	//Number of keywords(candidates)
	KeywordData key[];
	KeywordData2 key2[];	
	
	int freqnum = 0;	//Number of background keywords
	int freq_idlist[];
	
	int sbasenum = 0;	//Number of viewpoint keywords
	int sbase_idlist[];
	int sbasemin = 2;	//Minimum number of viewpoint keywords
	int sbasemax = 7;	//Maximum number of viewpoint keywords
	
	int select;				//Given number of output sentences
	int select_number = 10;	//Practical number of output sentences
	double select_rate=0.3;	//Default summarization rate, activate when select_number = 0
	double weight[] = {1.0, 1.0, 1.0};	// weight[back,topic,feature]; parameters for output summarization
	
	boolean update_sbase = true;
	
	//rate of keywords against the number of all keywords(candidate)
	double CUTODDSB = 0.15;		// Rate of background keywords
	double CUTODDST	= 0.05;		// Rate of viewpoint keywords
	double CUTODDSF	= 0.10;		// Rate of feature keywords
	
	PvsR(){}
	
	public void set_text(TextData tex)
	{
		text = tex;
		
		//Copy addresses for SentenceData
		sentence_num = text.sentenceNumber;
		sen = new SentenceData[sentence_num];
		sen2 = new SentenceData2[sentence_num];
		
		for(int i=0;i<sentence_num;i++)
		{
			sen[i] = text.sentence[i];
			sen2[i] = new SentenceData2();
		}	
		
		//Copy addresses for KeywordData
		keyword_num = text.keywordNumber;
		key = new KeywordData[keyword_num];
		key2 = new KeywordData2[keyword_num];
		
		for(int i=0;i<keyword_num;i++)
		{
			key[i] = text.keyword[i];
			key2[i] = new KeywordData2();
		}
		
		sbasenum = 0;
		sbase_idlist = new int[sbasemax*2];		
	}
	
	public void set_parameters(int sel, boolean update_s, double w1, double w2, double w3)
	{
		select = sel;
		update_sbase = update_s;
		
		weight[0] = w1;
		weight[1] = w2;
		weight[2] = w3;		
	}
	
	public void set_sbase(int idlist[], int num)
	{
		sbasenum = num;
		
		for(int i=0;i<sbasenum;i++)
			sbase_idlist[i] = idlist[i];
	}	
	
	public void exec()
	{
		if(make_parameters())
			make_summary();
	}
	
	
	
	
	
	//Display viewpoint keywords list
	public void show_sbase()
	{
		System.out.println("Number of TOPIC keywords = "+sbasenum);
		
		for(int i=0;i<sbasenum;i++)
			System.out.println(key[sbase_idlist[i]].word);
	}
	
	public boolean make_parameters()
	{
		if(sentence_num == 0 || keyword_num == 0)
			return false;
		
		//Give number of output sentences
		select_number = select;
		if(select_number > sentence_num)
			select_number = sentence_num;
		
		if(select_number == 0)
		{
			select_number = (int)((double)sentence_num * select_rate);
			if(select_number == 0)
				select_number = 1;
		}
		
		//Create background keywords
		double border = calc_keyparam();	    	//Decide the number of background keywords
		make_freqlist();
		
		//		System.out.println("Number of BASIC - TOPIC keywords : "+freqnum+" - "+sbasenum);
		//			for(int i=0;i<freqnum;i++)
		//				System.out.println(key[freq_idlist[i]].frequency+":"+key[freq_idlist[i]].word);
		
		//Create viewpoint keywords when viewpoint keywords do not exist
		
		if(sbasenum == 0)
		{
			for(int i=0;i<keyword_num;i++)
				if(text.focus.focusKeywords[i] && sbasenum < sbasemax)		//////////////////FOR LINKAGE
					sbase_idlist[sbasenum++] = i;
		}
		
		
		if(sbasenum == 0)
		{
			//Decide the number of viewpoint keywords
			sbasenum = (int)(1 + (double)border/5.0);
			if(sbasenum > sbasemax)
				sbasenum = sbasemax;
			make_sbaselist();
		}
		
		//		show_sbase();
		
		if(sbasenum == 0)	//When viewpoint keywords were not prepared
			return false;
		
		return true;
	}
	
	public double calc_keyparam()
	{
		int maxfreq=0;
		double border;
		
		for(int i=0;i<keyword_num;i++)
			if(key[i].frequency > maxfreq)
				maxfreq = key[i].frequency;
		
		int freq[] = new int[maxfreq+1];
		for(int i=0;i<=maxfreq;i++)
			freq[i] = 0;
		
		//Create frequency distribution, Evaluate words by frequency
		for(int i=0;i<keyword_num;i++)
		{	
			freq[key[i].frequency]++;
			key2[i].score[0] = key[i].frequency;
		}
		
		//Temporary number of background keywords
		if(keyword_num >= 100)
			border = 20.0 + (double)keyword_num/100.0;
		else
			border = ((double)keyword_num * 0.2);
		
		//Adjustment of the number of background keywords(Include keywords which have the same frequency)
		for(int i=maxfreq,ruikei=0;i>0;i--)
			if(freq[i] != 0 || i<10)
			{
				ruikei += freq[i];
				if(ruikei > border && ruikei-freq[i] <= border)
				{
					if(ruikei-border >= border-(ruikei-freq[i]))
						freqnum = ruikei-freq[i];
					else
						freqnum = ruikei;
				}
			}
	    if(freqnum == 0)
			freqnum = 1;
		
		freq_idlist = new int[freqnum];
		
		return border;
	}
	
	public void make_freqlist()
	{
		int num[] = new int[keyword_num];
		double sort_value[] = new double[keyword_num];
		
		for(int i=0;i<keyword_num;i++)
			sort_value[i] = key[i].frequency;
		
		Qsort.init_num(num, keyword_num);
		Qsort.quicksort(sort_value, num, keyword_num);
		
		for(int i=0;i<freqnum;i++)
			freq_idlist[i] = num[i];
	}
	
	//Count number of sentences including both words id1 and id2: using original_id
	public int common_appear(int id1, int id2)
	{
		int count=0;
		
		for(int i=0,j=0;i< key[id1].sentenceFrequency && j< key[id2].sentenceFrequency;)
			if(key[id1].appearingSentence[i] == key[id2].appearingSentence[j])
			{
				count++;    i++;    j++;
			}
			else
			{
				if(key[id1].appearingSentence[i] < key[id2].appearingSentence[j])
					i++;
				else
					j++;
			}
		return count;
	}
	
	//Return top n suffixes of value
	public void make_toplist(double value[], int n, int toplist[], int topn)
	{
		int num[] = new int[keyword_num];
		double sort_value[] = new double[keyword_num];
		
		for(int i=0;i<keyword_num;i++)
			sort_value[i] = value[i];
		
		Qsort.init_num(num, keyword_num);
		Qsort.quicksort(sort_value, num, keyword_num);
		
		for(int i=0;i<topn;i++)
			toplist[i] = num[i];
	}
	
	//Create viewpoint keyword list(create from background keywords)
	public void make_sbaselist()
	{
		int id1, id2;
		double shucho_up,shucho_down;
		int link1,link2,link12;
		double score[] = new double[keyword_num];
		
		for(int i=0;i<keyword_num;i++)
			key2[i].score[1] = 0;
		
		for(int i=0;i<freqnum;i++)
		{
			id1 = freq_idlist[i];
			shucho_up = 0.0;
			
			for(int j=0;j<freqnum;j++)
			{
				link12 = link1 = link2 = 0;
				
				id2 = freq_idlist[j];
				link12 = common_appear(id1,id2);
				link1 = key[id1].sentenceFrequency;
				link2 = key[id2].sentenceFrequency;
				
				if(link2 != 0)
					shucho_up += ((double)link12/(double)link2);
			}
			key2[id1].score[1] = shucho_up/(double)freqnum;		//Top sbasenum words in this score become viewpoint
		}
		
		for(int i=0;i<keyword_num;i++)
			score[i] = key2[i].score[1];
		
		make_toplist(score, keyword_num, sbase_idlist, sbasenum);
	}
	
	//Return 1: when revised 0: NOT revised
	public int sbase_selection(int new_sbase_idlist[])
	{
		int i,j,k;
		int searchnum, old_sbasenum;
		int revised = 0;
		
		searchnum = sbasenum;
		if(searchnum < sbasemin)
			searchnum = sbasemin;
		
		old_sbasenum = sbasenum;
		
		for(i=0;i<searchnum;i++)	//Each word in New top [searchnum] word
		{
			for(j=0;j<old_sbasenum;j++) //Compare with each word in the old list
				if(new_sbase_idlist[i] == sbase_idlist[j])
					break;
			
			if(j == sbasenum)	//If the word is not included in the old list, add to the list //If all words are added, the number is sbasenum*2
			{
				sbase_idlist[sbasenum++] = new_sbase_idlist[i];
				revised = 1;
			}
		}
		
		i--;
		k = i;
		for(;i<keyword_num;i++)	//Add a word which has the same score
		{
			if(key2[new_sbase_idlist[i]].score[1] != key2[new_sbase_idlist[k]].score[1])
				break;
			
			for(j=0;j<old_sbasenum;j++) //Compare with each word in the old list
				if(new_sbase_idlist[i] == sbase_idlist[j])
					break;
			
			if(j == sbasenum && sbasenum < sbasemax)	//If the word is not included in the old list, add to the list
			{
				sbase_idlist[sbasenum++] = new_sbase_idlist[i];
				revised = 1;
			}
		}
		return revised;
	}
	
	//Main function for Panoramic View System
	public boolean make_sbase_feat()	//Sbase will not be revised if update_sbase == false
	{
		int id1, id2;
		double shucho_up,shucho_down;
		int link1,link2,link12;
		
		int new_sbase_idlist[] = new int[keyword_num];
		double score[] = new double[keyword_num];
		
		for(int i=0;i<keyword_num;i++)
		{
			id1 = i;
			shucho_up = 0.0;
			shucho_down = 0.0;
			
			for(int j=0;j<sbasenum;j++)
			{
				link12 = link1 = link2 = 0;
				
				id2 = sbase_idlist[j];
				link12 = common_appear(id1,id2);
				link1 = key[id1].sentenceFrequency;
				link2 = key[id2].sentenceFrequency;
				
				if(link2 != 0)
					shucho_up += ((double)link12/(double)link2);
				
				if(link1 != 0)
					shucho_down += ((double)link12/(double)link1);
			}
			key2[id1].score[1] = (shucho_up*shucho_down)/((double)sbasenum*(double)sbasenum);
			key2[id1].score[2] = shucho_down/(double)sbasenum;
		}
		
		for(int i=0;i<keyword_num;i++)
			score[i] = key2[i].score[1];
		
		make_toplist(score, keyword_num, new_sbase_idlist, sbasemax);
		
		if(update_sbase == false)
			return false;
		
		if(sbase_selection(new_sbase_idlist) == 0)
			return false;
		
		if(sbasenum >= sbasemax)
			return false;
		
		return true;
	}
	
	//Set evaluation value 0 except for the words in the decided rate
	public int wordscore_cut(int type, double odds)
	{
		int count,bn;
		double border=0.0;
		double score[] = new double[keyword_num];
		
		for(int i=0;i<keyword_num;i++)
			score[i] = key2[i].score[type];
		
		bn = (int)((double)keyword_num*odds);
		border = Qsort.quickselect(score, keyword_num, bn);
		
		//		System.out.println("= "+border+"(Ratio="+odds+")");
		
		count = 0;
		for(int i=0;i<keyword_num;i++)
		{
			if(key2[i].score[type] < border)
				key2[i].score[type] = 0;
			else if(key2[i].score[type] > 0)
				count++;
		}
		return count;
	}
	
	void wordscore_change(boolean hindocut, boolean featcut)// Background NOT viewpoint, Feature NOT viewpoint
	{
		int va,vb,vc;	//Cutting border for background, viewpoint, feature
		
		//Viewpoint keywords, value cut
		//		System.out.println("Borders, TOPIC:");
		vb = wordscore_cut(1,CUTODDST);
		
		//Cut dupulication of viewpoint keywords
		for(int i=0;i<keyword_num;i++)
			if(key2[i].score[1]> 0)
			{
				if(hindocut)
					key2[i].score[0] = 0;
				if(featcut)
					key2[i].score[2] = 0;
			}
		
		//Background, Feature keywords, value cut
		//	    System.out.println("BASIC:");
		va = wordscore_cut(0,CUTODDSB);
		
		//		System.out.println("FEATURE:");
		vc = wordscore_cut(2,CUTODDSF);
		
		//		System.out.println("BASIC:"+va+"/"+keyword_num+",TOPIC:"+vb+"/"+keyword_num+",FEATURE:"+vc+"/"+keyword_num);
		//		System.out.println("BASIC:"+(100*va/keyword_num)+"%,TOPIC:"+(100*vb/keyword_num)+"%,FEATURE:"+(100*vc/keyword_num)+"%");
	}
	
	// Create evaluation values for each sentence, Background, Viewpoint, Feature
	public void make_bunscore()
	{
		int t;
		int wordcount[] = new int[keyword_num];
		
		for(int i=0;i<keyword_num;i++)//Plus evaluation value, first appearance ONLY
			wordcount[i] = 0;
		
		for(int i=0;i<sentence_num;i++)
		{
			sen2[i].score[0] = sen2[i].score[1] = sen2[i].score[2] = 0;
			for(int j=0;j<sen[i].keywordNumber;j++)
			{
				t = sen[i].keywordIDList[j];
				if(wordcount[t] == 0)
				{
					sen2[i].score[0] += key2[t].score[0];
					sen2[i].score[1] += key2[t].score[1];
					sen2[i].score[2] += key2[t].score[2];
					wordcount[t] = 1;
				}
			}
			for(int j=0;j<sen[i].keywordNumber;j++)		//Plus evaluation value, first appearance ONLY
				wordcount[sen[i].keywordIDList[j]] = 0;
		}
	}
	
	//Calculate rank by evaluation value for each sentence
	public void make_bunrank()
	{
		int num[] = new int[sentence_num];
		double sort_value[] = new double[sentence_num];
		
		for(int j=0;j<3;j++)
		{
			for(int i=0;i<sentence_num;i++)
				sort_value[i] = sen2[i].score[j];
			
			Qsort.init_num(num, sentence_num);
			Qsort.quicksort(sort_value, num, sentence_num);
			
			sen2[num[0]].rank[j] = 0;
			for(int i=1, rank=0;i<sentence_num;i++)
			{
				if(sen2[num[i]].score[j] != sen2[num[rank]].score[j])
					rank = i;
				
				sen2[num[i]].rank[j] = rank;
			}
		}
	}
	
	//Calcuate the final rank of each sentence
	public void make_finalscore()
	{
		int num[] = new int[sentence_num];
		double sort_value[] = new double[sentence_num];
		
		for(int i=0;i<sentence_num;i++)
			sen2[i].ranktotal = 0;
		
		for(int i=0;i<sentence_num;i++)
			for(int j=0;j<3;j++)
				sen2[i].ranktotal += (sen2[i].rank[j] * weight[j]);
		
		//Sorting ranktotal
		for(int i=0;i<sentence_num;i++)
			sort_value[i] = sentence_num * 3 - sen2[i].ranktotal;
		
		Qsort.init_num(num,sentence_num);
		Qsort.quicksort(sort_value,num,sentence_num);
		
		sen2[num[0]].finalrank = 0;
		for(int i=1,rank=0;i<sentence_num;i++)
		{
			if(sen2[num[i]].finalrank != sen2[num[rank]].finalrank)
				rank = i;
			
			sen2[num[i]].finalrank = i;
		}
	}
	
	public void make_summary() //Viewpoints are not revised when flag == 0
	{
		//Execute Panoramic View System
		for(int i=1;make_sbase_feat();i++);	//Loop Condition: sbase is not reached to MAX && flag != 0 -> sbaselist is revised
		
		//		show_sbase();
		
		wordscore_change((weight[0]>0),(weight[1]>0));	//Create evaluation values for each word
		make_bunscore();		// Create evaluation values for each sentence
		make_bunrank();			// Create ranks for each sentence
		make_finalscore();		// Create final evaluation values for each sentence
	}
	
	public String output_summary()
	{
		StringWriter sw1 = new StringWriter();
		BufferedWriter bw1 = new BufferedWriter(sw1);
		int c = 0;
		try
		{
			for(int i=0;i<sentence_num;i++)
				if(sen2[i].finalrank < select_number)
				{
					//					bw1.write(i+"("+(sen2[i].finalrank+1)+":"+(sen2[i].ranktotal+3)+"["+
					//					(sen2[i].rank[0]+1)+","+(sen2[i].rank[1]+1)+","+(sen2[i].rank[2]+1)+"]["+
					//					sen2[i].score[0]+","+sen2[i].score[1]+","+sen2[i].score[2]+"])");
					bw1.write(sen[i].sentenceText);
					bw1.newLine();
					c++;
				}
			select_number = c;
			bw1.write("---Panoramic View System InDicative("+select_number+"/"+text.sentenceNumber+")---");
			bw1.newLine();
			bw1.flush();
		}
		catch(Exception e){
			System.out.println("Error in output_summary");
		}
		return sw1.toString();
	}
}
	
}
